admin管理员组文章数量:1594570
异常
- 出现异常终止
- 出现异常继续运行
-
分类
异常是类,所有异常类的根类是Throwable- Err
- 异常不需处理(不需要写throws抛出或者try/catch),因为不需要写处理异常所以会自动打印栈的跟踪信息
- Exception
- 异常需要处理(需要抛出)
- Err
-
编译期异常,try,catch是必不可少的,finally可以不写;如未调用含有异常方法,则可以用try,final组成
-
运行期异常继承RuntimeException,不用try/catch或添加throws
-
throws将异常抛出,交给调用者
自定义异常
-
继承Exception或者RuntimeException
-
添加构造方法
-
在需要报异常的地方生成异常,若是运行期异常需要在调用该异常方法的地方用try/catch捕获
没有向外抛出异常,在调用自定义异常时,就解决了异常
try { throw new MyProductException("出错了"); } catch (MyProductException e) { System.err.println(e.getMessage()); }
-
集合
就是数据结构,包含List,Set,Map
-
List(存的都是地址**,list对象被引用后无法垃圾回收**)
List就是列表,用来存储一组数据的数据结构
可变长的数据结构,可以知道里面存了多少数据
List是一个有序的列表,数据可以重复
List可以保存不同类型的数据
ArrayList
ArrayList采用数组方式实现,因为是采用数组实现,所以对元素插入和删除会较慢
读写(不超过默认长度)和遍历都很快,插入和删除数据比较慢
LinkedList
采用双向链表实现,插入,修改,删除速度特别快,查询和遍历速度慢
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RymZzKzB-1660484425169)(C:\Users\24890\Desktop\上课\笔记\Java高级\第十一天\Java学习第十一天_高级第一天.assets\双向链表结构.jpg)]
- 插入和删除速度快
- 查询和遍历速度慢
- 链表的保存的数据是地址
- 每个子节点除了自身的数据地址外,还保存前一个和后一个的节点地址
- pop,对于栈,弹出
- push,对于栈,压栈
泛型
因为List可以存各种类型的数据,但是取出的是Object类型数据,需要强制转换
泛型可以解决这个问题,在创建List时,可以指定存储的类型
泛型不能是基本类型
Set
- 无序集合
- 元素不重复(覆盖)
- 没有索引(序号),不能通过下标访问
HashSet->LinkedHashSet
TreeSet
哈希表 hash table
-
哈希表,散列表,是一种高效数据结构
-
要保存的数据称为值,根据hash算法给每一个值算出一个hash code
-
保存数据就用hash code根值一一对应
hash table保存数据的原理
-
根据hash code从表里面查找是否存在:
- 不存在,直接添加
- 存在,再判断equals是否相等:
- false,直接添加
- true,说明两个值一样,不添加
Hash Code:
- 两个对象的HashCode值相同,它们的equals不一定相同
- 两个值得equals值相同,HashCode的值也不一定相同
- 两个值得HashCode相同,equals相同,这个两个值相同
HashSet
采用hash表实现
元素不重复
允许null但不能重复)
TreeSet
树
-
二叉树
每个节点只有两个分支
-
满二叉树
除了叶节点外,每个分支都有两个节点
-
完全二叉树
最底层可以不满,但必须保证左边填满
-
二叉查找树
排列顺序,每个节点分支,左节点比父节点小,右节点比父节点大
-
平衡二叉树
左右子树高度差小于1,并且子树也是平衡二叉树
-
红黑树
自平衡的二叉查找树
- 节点只有红,黑色
- 根节点是黑色
- 叶节点为黑色,叶节点不存数据,为NIL标志
- 一个节点为红,则它的两个子节点必须为黑色(从根节点到叶子节点使用路径,不可能存在两个连续的红色节点)
- 每个节点到叶子节点的所有路径,都包含相同数目的黑色节点
TreeSet采用红黑树数据结构来实现
-
不能添加null
-
不能添加重复的元素
-
添加的元素会被排序(大小排序),遍历出来是按顺序排列的
-
TreeSet的元素必须实现Comparable
自定义的对象需要实现Comparable接口,重写compareTo方法
-
当前对象大于参数对象返回1,TreeSet的内部为 升序
-
当前对象大于参数对象返回-1,TreeSet的内部为 降序
-
如果不实现Comparable接口,会报一个类型转换异常
-
当判断相等时,TreeSet不会存入,如果要存入需要把等于条件去掉
-
public class Sportsman implements Comparable<Sportsman> {
private String name;
private float score;
...
@Override
public int compareTo(Sportsman o) {
if (this.score>o.score){
return -1;
}else if(this.score<o.score){
return 1;
}else{
return 0;
}
}
}
Collection集合用迭代器遍历(Iterator)
调用list的iterator()方法返回一个泛型迭代器<T>对象,结合对象hasNext()方法判断迭代器是否为空,以及next()取出元素进行迭代
//iterator迭代器,迭代器里面存数据
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {//判断里面是否还有数据
Integer next = iterator.next();//从迭代器里面取出一个数据,取一个少一个
System.out.println(next);
}
只要实现了Iterable接口就可以使用Itertor迭代器
Collections集合工具类
- Collections与Collection区别
- Collection是接口,是List和Set的父接口
- Collections是处理集合的工具类
package Java高级.第十二天;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CollcetionsDemo {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(11);
list.add(22);
list.add(33);
list.add(99);
list.add(22);
list.add(66);
list.add(70);
Collections.shuffle(list);//随机打乱list的顺序
System.out.println(list);
Collections.reverse(list);//逆序
System.out.println(list);
Collections.sort(list);//调用sort方法必须泛型必须实现Comperable接口,并重写接口里的方法
System.out.println(list);
Collections.swap(list,0,3);
System.out.println(list);
System.out.println(Collections.max(list));//返回集合中最大元素
System.out.println(Collections.min(list));//返回集合中最小元素
}
}
- Collections.shuffle 随机打乱list的顺序
- Collections.reverse 逆序
- Collections.sort 调用sort方法因为是泛型,必须实现Comperable接口,并重写接口里的方法
Map
- 保存键值对数据(key-value)
- key不能重复,value可以重复
- key和value都可以为null
HashMap
采用数组+链表+红黑树的数据结构来实现
- 先根据hash code保存数组中,如果出现hash碰撞,用链表,链表长度超过8,改用红黑树
public class HashMapDemo {
public static void main(String[] args) {
//默认长度16 加载因子0.75
HashMap<String, String> map = new HashMap<>();
map.put("yyds", "永远单身");
map.put("emo", "抑郁了");
map.put("u1s1", "有一说一");
System.out.println(map.get("yyds"));//根据key查询对象value
System.out.println(map);
System.out.println(map.containsKey("emo"));//查询Key是否包含
System.out.println(map.containsValue("蔡徐坤"));//查询Value是否包含
System.out.println(map.size());//获取键值对个数
map.remove("yyds");//删除
map.clear();//格式化
System.out.println(map.isEmpty());
map.put("yyds", "永远单身");
map.put("emo", "抑郁了");
map.put("u1s1", "有一说一");
/**
*变量value
*/
for (String s :
map.values()) {
System.out.println(s);
}
/**
*变量key
*/
for (String s :
map.keySet()) {
System.out.println(s);
}
System.out.println("==========遍历entry============");
Set<Map.Entry<String, String>> entries = map.entrySet();
for (Map.Entry<String,String> entry:
entries) {
System.out.println(entry.getKey()+","+entry.getValue());
}
}
}
集合继承关系
注意
Set和Map默认长度16,都存在加载因子为0.75,当使用长度为75%时,自动准备加载集合长度,并非使用完全时再加载长度
IO文件读写
Input输入,Output输出
信息需要永久保存(持久化),一般用文件的形式把信息保存到磁盘上
程序运行需要一些基本配置信息,配置信息也是保存在磁盘文件中
程序从磁盘读取文件,就称为Input,把文件写到磁盘,称为Output.已内存为参考
java.io包下的分类
按照输入输出的方向分类:
- 输入 Input,Reader
- 输出 Output,Writer
按照数据格式:
-
字节流(二进制文件,如:exe,office,图片,视频,音频)
Stream
-
字符流(文本文件,txt,程序源代码,html)
Reader,Writer
文件
所有的IO操作都于文件类对象打交道
File类方法总结:
file.exists()//判断该对象 文件或目录是否存在
file.isFile()//判断该对象 是否是文件
file.isDirectory()//判断该对象 是否是目录
file.lastModified()//最后一次的文件修改时间
file.length()//返回文件长度,以字节byte为单位
file.listFiles()//将file内子文件和目录以File对象存入数组,如果file内为null,则产生的数组长度为0
序列化
Java在运行时,如果需要保存对象的状态(下次在运行时,也能还原当前对象状态),就需要使用序列化操作
注意:当某些变量不想被序列化,同是又不适合使用static关键字声明,那么此时就需要用transient关键字来声明该变量。
IO编程:存储对象
网络编程:如果想把一个对象从一台机器(虚拟机)发送到另一台机器(虚拟机),这种情况需要把对象序列化二进制内容,然后再网络发送,对方收到二进制内容,再反序列化为对象
ObjectOutPutStream序列化
把对象保存在文件中,要被序列化的对象需要实现Serializable接口
-
Student类,实现Serializable
import java.io.Serializable; public class Student implements Serializable { //eclipse中需要生成序列化版本 private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
运行
package Java高级.第十四天.序列化; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; public class SerializableDemo { public static void main(String[] args) { Student student = new Student("蔡徐坤",18); ObjectOutputStream oos=null; try { oos= new ObjectOutputStream(new FileOutputStream("src\\Java高级\\第十四天\\序列化")); oos.writeObject(student); oos.flush(); } catch (IOException e) { e.printStackTrace(); }finally{ try { if (oos!=null){ oos.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
反序列化
import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream; public class SerializableInputDemo { public static void main(String[] args) { ObjectInputStream ois = null; try { ois= new ObjectInputStream(new FileInputStream("src\\Java高级\\第十四天\\序列化/蔡徐坤.data")); try { Student s =(Student) ois.readObject(); System.out.println(s); } catch (ClassNotFoundException e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); }finally { if (ois!=null){ try { ois.close() ; } catch (IOException e) { e.printStackTrace(); } } } } }
序列化与反序列化不能更改序列化类,否则反序列化会失败
序列化应用于:上传图片,Excel(POI EasyExcel),生成文件
常量池中存的是一种对象吗
常量池中存的也是一种对象,主要针对String类型,如果用字面量赋值的string,就会在常量池中创建一个对象,下一次再用相同的
基本类型:指向的是数值并不是指向堆中的对象
如果进行引用,虚拟机不能自动垃圾回收吗
首先对Java虚拟机的内存进行配置:
List集合泛型为引用类型的对象如果被引用后没有清除掉,直接将List的对象赋null空值会发生三种情况:
- 不能自动垃圾回收
- JVM虚拟机内存泄漏
- 如果次数多,JVM虚拟机内存耗光,会产生内存溢出
抽象abstract
抽象可以修饰类,方法
抽象方法,就是没有方法体,目的是同一方法名,具体实现交给子类,一般来说每个子类实现都不一样
网络编程
-
TCP/IP
长连接,连接后一直保持连接,可靠通讯,一字节流传输,效率低
-
UDP
非长连接,通讯不可靠,数据报文发送,效率高
-
端口 prot
区分同一台服务器不同的网络通讯软件
操作系统也会用到端口号,操作系统保留1024以下的端口,要避开,一些软件的端口也要避免:tomcat 8080 数据库 3306 oracle 1512 如果自己的程序与其他软件用来同样端口,同时启动时其中一个会端口占用
InetAddress类(网络地址类)
用来表示网络上的一台服务器,网络通讯中数据的来源或目的地,相当于文件读写里的File类
-
InetAddress.getLocalHost();//获取本地网络地址对象,如果主机存在多个ip,返回最靠前的ip
-
InetAddress.getLocalHost().getAddress();//获取数组类型的ip地址,有符号
-
InterAddress.getByName(“www.baidu”);获取服务器地址对象
-
getHostAddres();返回ip地址
-
getHostName;返回域名或机器名
import com.sun.jmx.snmp.InetAddressAcl; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; public class InetAddressDeomo { public static void main(String[] args) { //本机地址:localhost或127.0.0.1 try { InetAddress localHost = InetAddress.getLocalHost();//获取本地的Localhost // System.out.println(new String(localHost.getAddress()));//未知 System.out.println(localHost.getHostAddress());//ip地址 System.out.println(localHost.getHostName());//计算机名称 InetAddress byName = InetAddress.getByName("192.168.3.120"); System.out.println("===================="); System.out.println(byName.getHostAddress()); System.out.println(byName.getHostName()); } catch (UnknownHostException e) { e.printStackTrace(); }finally{ } } }
ServerSocket类
TCP通讯(Socket 套接字)的服务器端,被动等待客服端建立连接,获取连接后的Socket
- 创建ServerSocket(服务器套接字)
- 调用accept方法等待客服端建立连接,获取连接后的Socket
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class SeverSocketDemo {
public static void main(String[] args) {
ServerSocket ss = null;
Socket accept = null;
InputStream inputStream = null;
try {
InetAddress byName = InetAddress.getByName("192.168.3.56");//创建网络对象
ss = new ServerSocket(10086,9, byName);//服务器Socket,端口,连接数,网络地址
accept = ss.accept();//接收,对待客户端的Socket,程序被阻塞
inputStream = accept.getInputStream();
byte[] bytes=new byte[1024];
int count=inputStream.read(bytes);
System.out.println(new String(bytes,0,count));
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
inputStream.close();
accept.close();
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Socket 类
套接字的客户端,去连接服务器端,连上之后发送信息
- 创建客户端套接字Socket,ip和端口跟服务器端设置一样
- 得到输出流
- 往输出流写信息
package com.hqyj;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class SocketDemo {
public static void main(String[] args) {
Socket socket = null;
OutputStream outputStream = null;
try {
socket = new Socket("192.168.3.178", 9090);
outputStream = socket.getOutputStream();
byte[] bytes = "您好!".getBytes();
outputStream.write(bytes);
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(outputStream != null){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
UDP
- DatagramSocket 创建UDB连接
- DatagramPacket 报文内容
服务端代码
import java.io.IOException;
import java.net.*;
public class UdpServer {
public static void main(String[] args) throws IOException {
//创建Socket
DatagramSocket socket = new DatagramSocket(8888, InetAddress.getByName("192.168.3.178"));
//创建packet对象
byte[] bytes = new byte[1024];
DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
while (true){
//读取数据
socket.receive(packet);
//返回读取到的字节数
int length = packet.getLength();
//new String(bytes, 0, length) 只打印有内容的字节,避免打出空白内容
System.out.println(new String(bytes, 0, length));
}
}
}
客户端代码
import java.io.IOException;
import java.net.*;
import java.util.Scanner;
public class UdpClient {
public static void main(String[] args) throws IOException {
//创建socket
DatagramSocket socket = new DatagramSocket();
//控制台输入内容,完成发送
Scanner scanner = new Scanner(System.in);
while (true){
System.out.println("请输入要发送的消息:");
String msg = scanner.next();
byte[] bytes = msg.getBytes();
//创建报文包,参数依次为:字节数组, 长度,服务器地址, 服务器端口
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("192.168.3.178"), 8888);
//发送报文包
socket.send(packet);
}
}
}
多线程
进程和线程
-
进程process
每个程序运行就会创建一进程,进程就是由操作系统管理,每个进程独享一段内存空间,进程之间互不干扰
-
线程Thread
线程是进程的组成单元,一个进程可以创建多个线程,多个线程之间共享同一资源
Java中,运行的进程有一种看不见的垃圾回收器线程在运行
并行和并发
-
并行
多个线程同时都在运行,并行
-
并发
并行的多个线程同一时间点访问同一资源(执行同一方法或访问同一属性),产生并发可能导致数据不一致(混乱)
多线程好处:加快程序运行速度,防止程序阻塞
多线程坏处:产生并发线程
同步和异步
-
同步(线程安全):StringBffer,ConcurrentHashMap
多个线程排队执行,称为同步,同一时间点只有一个线程在执行,不会导致并发,执行效率不高(兼顾效率,只会对造成数据不一致的代码同步)
-
异步(线程不安全),StringBuilder,HashMap
多个线程同时运行,可能会导致并发,执行效率比较高
创建和执行线程
方式一,继承Thread
-
继承Thread类
-
调用线程类的start()方法启动线程,并不一定会立即执行,什么时候执行这个线程是由进程调度的,start()方法相当于告诉进程,这个线程准备好了,不能直接调用run方法,是没有多线程的效果
Thread线程类
public class Thread1 extends Thread{ public Thread1(String name) {//构造方法不能重写,只能生成一个调用父类的构造方法 super(name); } @Override public void run() { for (int i = 0; i < 20; i++) { System.out.println(getName()+""+i);//this可以不要,因为是Thread的方法 try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } }
测试代码
public class Thread1Test { public static void main(String[] args) { Thread1 thread1 = new Thread1("线程一"); Thread1 thread2 = new Thread1("线程二"); thread1.start();//run方法是可以运行的,运行没有多线程效果,因为线程是由进程控制的,而线程是否执行却是由操作系统决定,是不可控制的 thread2.start(); } }
第二种方式,实现Runnable接口
- 实现Runnabel接口,并在run方法写入线程代码
- 创建一Thread对象,构造方法参数是实现了Runnabel接口类的对象
- 调用Thread对象的start方法启动线程
Runnabel代码
public class Thread2 implements Runnable{ @Override public void run() { for (int i = 0; i < 100; i++) { //Thread.currentThread()获取当前线程对象 System.out.println(Thread.currentThread().getName()+ i); } } }
测试代码
public class Thread2Test { public static void main(String[] args) { Thread2 t1 = new Thread2(); Thread2 t2=new Thread2(); new Thread(t1).start(); new Thread(t2).start(); } }
方式三,实现Callable接口
FutureTask实体类实现了RunnableFuture接口,RunnableFuture接口继承了Future,Runnable接口,因为继承了Runnable接口,所以可以作为Thread的参数对象,FutureTask的构造参数需要Callable的实体类对象,Callable是顶级接口
- 实现Callable接口,call方法内写入线程代码
- 创建FutureTask对象,构造方法是实现了Callabel接口对象
- 创建Thread对象,构造方法的参数是FutureTask对象
- 调用start方法启动线程
Callable代码
import java.util.concurrent.Callable; public class Thread3 implements Callable<String> { @Override public String call() throws Exception { for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName()+":"+i); } return Thread.currentThread().getName(); } }
测试代码
import java.util.concurrent.FutureTask; public class Thread3Test { public static void main(String[] args) { Thread3 callable1 = new Thread3(); Thread3 callable2 = new Thread3(); FutureTask<String> stringFutureTask1 = new FutureTask<>(callable1); FutureTask<String> stringFutureTask2 = new FutureTask<>(callable2); new Thread(stringFutureTask1).start(); new Thread(stringFutureTask2).start(); } }
线程生命周期
new 新生态
新生状态,当线程被实例化后new Thread,就进入新生状态
Runnable就绪态
就绪状态,当线程对象执行了start()后进入就绪状态
就绪状态的线程可以执行,但不会执行,等待线程调度触发他执行
Running 运行状态
当线程被激活执行,这个时候就是运行状态,执行run()方法,一个执行周期内不一定能执行完整个run方法,如果分配CPU时间片被消耗完毕或线程调用yield()方法,线程会退回就绪状态,等待下次分配CPU时间片进入运行态,如果run方法被执行完毕就会进入终止态,且不可逆
Blocked 阻塞态
暂停运行,正在运行的线程执行了sleep(),wait()方法,就进入阻塞状态,因sleep()方法阻塞的线程,sleep时间到了后,重新返回就绪状态,因wait()方法阻塞的线程,必须等待notify或notifyAl被执行,才能由阻塞态重新回到就绪态
Terminated 结束态
终止状态,run()正常执行完毕,就进入终止状态,线程生命周期到此结束
线程不安全(并发)
解决线程不安全问题
加锁
把并发代码(或方法)添加一个同步的synchronized关键字给这段代码加锁(让这段代码变为同步的代码),小括号里面的就是加锁对象,如果有对象就用这个对象,没有可以new 一个Object对象
死锁
两个线程相互等待对方释放它额锁定资源,两个线程都没有办法执行,程序将会一直处于等待状态,不会结束,也不会成功运行,这种现象就是死锁
形成条件
- 互斥使用,当一个资源被一个线程使用时,另一个线程不能使用
- 不可抢占,资源请求者不能强制从资源占用者手中夺取资源,只能由资源的占有者主动释放
- 请求和保持,当资源的请求者在请求已占用的资源,该资源一直不被释放
- 循环等待,A线程持有资源1等待资源2,B线程持有资源2等待资源1
避免死锁
- 以相同顺序去锁定资源
- 另外建立一个锁对象,只锁一个对象,不要锁多个对象
JDK1.8新特性
接口默认方法
-
default
- 接口可以有实现的方法,加上default(并非缺省)关键字
- 一个接口里可以有多个default修饰的方法
- 该方法必须实现,不能只声明
- 加了default关键字的方法必须实例接口并实现才可以调用
-
static
- 接口可以有实现的方法,加上static关键字
- 一个接口里可以有多个static修饰的方法
- 该方法必须实现,不能只声明
- 加了static关键字的方法通过接口调用该方法
函数式接口
-
只有一个抽象方法,可以有多个实现方法
-
函数式接口一般在接口名称上添加注解:@FunctionalInterface,注解和函数式接口没有必然关系,加了注解强转语法检查是否只有一个抽象方法,只要满足只有一个接口方法,不叫注解@FunctionalInterface它也是函数式接口,注解的目的只是更能保障它是一个函数式接口
-
作用:函数式接口在实现的时候可以用Lambda表达式(箭头函数),还可以用new的接口方式
注解
注解是一个接口,定义时和接口类似用@interface加一个@
Lambda表达式
//Lambda参数不需要写类型
//表达式只有一行代码,不用写大括号,分号
//() -> 5//无参方法,不用写分号,只有一行代码,自动作为返回值,没有参数,参数需要写小括号
//x-> 2*x//一个参数不用写小括号
//(x,y) ->x-y
//()->{多行代码}//方法体有多行代码需要加大括号,分号
JDK的类中,只要某个方法的类型是函数式接口,调用该方法的时候就可以用Lambda表达式
Stream
集合类型类都有stream方法,产生一个数据流,可以对数据流做处理:forEach,map,filter,limt,sorted,Collectors
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.stream.Collectors;
public class StreamDemo {
public static void main(String[] args) {
//filter 过滤
List<String> stringList = Arrays.asList("dasd", "dasdas", "dasdsa", "", "dasdqe");
List<String> collect = stringList.stream().filter(str -> !str.isEmpty()).collect(Collectors.toList());
System.out.println(collect);
//将集合转换成Stream流调用filter过滤,参数可以是Lambda代码,再调用collect进行收集,参数是Collectors是收集后的对象toList()转换成需要的类型
//map 映射
List<Integer> integerList = Arrays.asList(1, 2, 3, 6, 4, 5);
List<Integer> collect1 = integerList.stream().map(inem -> inem * inem).collect(Collectors.toList());
System.out.println(collect1);
//limit 限制数量
Random random = new Random();
random.ints().limit(2).forEach(itrm -> System.out.println(itrm));
//sorted 排序
List<Integer> integerList1 = Arrays.asList(9, 65, 66, 5645, 223, 12, 545, 65, 78, 22, 1, 54, 6, 6, 3, 5);
integerList1.stream().sorted().forEach(item -> System.out.println(item));
//collect 将数据流拼接成字符串
String collect2 = stringList.stream().collect(Collectors.joining("蔡徐坤"));
System.out.println(collect2);
}
}
方法引用
对象::方法
//用小括号里面指定的方法来处理foreach出来的的每个元素
integerList1.forEach(System.out::println);
Optional
为了解决放回值为unll的一个类
//Optional为了解决返回值为null
//sum1(null,3).intValue();抛出空指针异常
if (sum2(null,3).isPresent()){//是否有值
System.out.println(sum2(null,3).get().intValue());
}else{
System.out.println("无");
}
private static Integer sum1(Integer a,Integer b){
if (a==null||b==null){
return null;
}else
return a+b;
}
private static Optional<Integer> sum2(Integer a, Integer b){
if (a==null||b==null){
return Optional.empty();//empty方法没有给Optional赋值
}else
return Optional.of(a+b);//把值封装到Optional里,使用的时候用get()方法取值
}
日期时间类
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class LocalDateDemo {
public static void main(String[] args) {
LocalDateTime now=LocalDateTime.now();//创建当前时间的日期时间对象
System.out.println(now);
LocalDate localDate = now.toLocalDate();//只要日期的对象
System.out.println(localDate);
LocalTime localTime = now.toLocalTime();//只要时间的对象
System.out.println(localTime);
System.out.println(now.getMonthValue());//返回月份
System.out.println(now.getYear());//一年的第几天
System.out.println(now.getDayOfMonth());//每个月的第几天,就是号数
System.out.println(now.getDayOfWeek());//返回星期对象
System.out.println(now.getDayOfWeek().getValue());//返回数字星期
System.out.println(now.getHour());//返回当前小时(几点,24小时制)
System.out.println(now.getMonth());//返回分钟
System.out.println(now.getSecond());//返回秒
now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));//格式化日期
System.out.println(now.plusDays(40));//加天也可以加时分秒年
}
}
版权声明:本文标题:Java学习技术总结_Java基础学习下 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dongtai/1728195498a1149225.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论