1 不可变集合
不可被修改的集合,只能查看
// 不可变list集合
List<Integer> lists = List.of(1,2,3);
// 不可变Set集合
Set<Integer> sets = Set.of(1,2,3);
// 不可变Map集合
Map<String, Integer> maps = Map.of("aa",1,"bb",2,"cc",3);
2 stream流
作用:结合Lambda表达式,简化集合数组操作的API
示例:获取姓张的三个字的名字(用以前方法和stream流分别示例)
List<String> names = new ArrayList<>();
Collections.addAll(names, "张三丰","张无忌","周芷若","赵敏","张强");
// 1、从集合中找出姓张的放到新集合
List<String> zhangNames = new ArrayList<>();
for (String name : names) {
if(name.startsWith("张")) {
zhangNames.add(name);
}
}
// 2、找名称长度是3的姓名
List<String> zhangThreeNames = new ArrayList<>();
for (String name : zhangNames) {
if(name.length() == 3){
zhangThreeNames.add(name);
}
}
System.out.println(zhangThreeNames);
// 用stream流
names.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));
2.1 stream流获取
集合获取stream流
default Stream<E> stream() | 获取当前集合对象的Stream流 |
// 获取Collection系列集合的stream流
Collection<String> list = new ArrayList<>();
Stream<String> s1 = list.stream();
// 获取map系列集合的stream数据流
Map<String, Integer> maps = new HashMap<>();
// 键流
Stream<String> s2 = maps.keySet().stream();
// 值流
Stream<Integer> s3 = maps.values().stream();
// 键值流
Stream<Map.Entry<String, Integer>> str = maps.entrySet().stream();
数组获取stream流
public static <T> Stream<T> stream(T[] array) | 获取当前数组的Stream流 |
public static<T> Stream<T> of(T... values) | 获取当前数组/可变数据的Stream流 |
Integer[] a = {1, 2, 3};
Stream<Integer> s4 = Arrays.stream(a);
// 法二
Stream<Integer> s5 = Stream.of(a);
2.2 常用API
Stream流中间操作方法
调用完成后返回新的Stream流可以继续使用,在Stream流中无法直接修改集合、数组中的数据
Stream<T> filter(Predicate<? super T> predicate) | 用于对流中的数据进行过滤。 |
Stream<T> limit(long maxSize) | 获取前几个元素 |
Stream<T> skip(long n) | 跳过前几个元素 |
Stream<T> distinct() | 去除流中重复的元素。依赖(hashCode和equals方法) |
static <T> Stream<T> concat(Stream a, Stream b) | 合并a和b两个流为一个流 |
List<String> names = new ArrayList<>();
Collections.addAll(names, "张三丰","张无忌","周芷若","赵敏","张强");
Stream<Stream> stream = names.stream();
// 找出姓张的人的个数
long size = stream.filter(s -> s.startsWith("张")).count()
// 取出前三个数,并打印
names.stream().limit(3).forEach(s->System.out.println(s));
// 在每个数据前加上'a'
names.stream().map(s->'a'+s).forEach(s->System.out.println(s));
Stream常见终结操作
终结操作方法调用完后stream流就无法继续使用(因为其不返回stream)
void forEach(Consumer action) | 对此流的每个元素执行遍历操作 |
long count() | 返回此流中的元素数 |
2.3 收集stream流
把stream流操作后的结果数据转回到集合或数组中
stream流收集方法
R collect(Collector collector) | 开始收集Stream流,指定收集器 |
Collectors工具类提供的具体收集方法
public static <T> Collector toList() | 把元素收集到List集合中 |
public static <T> Collector toSet() | 把元素收集到Set集合中 |
public static Collector toMap(Function keyMapper , Function valueMapper) | 把元素收集到Map集合中 |
// 转为list集合
List<String> name = stream1.collect(Collectors.toList());
// 转为数组
String[] ar = stream2.toArray(s->new String[s]);
3 异常处理
Throeable(Error,Exception)
Error:系统级别问题,JVM退出等,代码无法控制
Exception:java.lang包下,称为异常类,它表示程序本身可以处理的问题
- RuntimeException及其子类:运行异常,编译阶段不会报错(空指针异常,数组索引越界异常)
- 其余异常:编译时异常,编译时必须处理,否则程序不能通过编译
3.1 常见运行时异常
数组索引越界异常 | ArrayIndexOutOfBoundsException |
空指针异常 | NullPointerException |
数学操作异常 | ArithmeticException |
类型转换异常 | ClassCastException |
数字转换异常 | NumberFormatException |
3.2 编译时异常处理
方式1:throws
用在方法上,将方法内部出现的异常抛出给方法的调用者
方法 throws 异常1,异常2,...{
}
方法 throws Exception{
}
方式2:try...catch...
监视捕获异常,用在方法内部,将方法内部出现的异常直接捕获处理
try{
// 监视可能出现的异常的代码
}catch(异常类型1 变量){
// 处理异常
}catch(异常类型2 变量){
// 处理异常
}...
try{
// 可能出现异常的代码
}catch(Exception e){
e.printStackTrace();//直接打印异常栈信息
}
方式3:前两种结合
方法体直接将异常通过throws抛给调用者,调用者接到异常后直接捕获处理