Stream流
Function 接口 : 用于类型函数转换,就是apply
// 表示将x 乘2 得到另外一个整数
Function<Integer, Integer> multiple2 = x -> x * 2;
// +100
Function<Integer, Integer> add100 = x -> x + 100;
// compose 接口表示,先对x执行add100,再对结果执行multiple2
Integer apply = multiple2.compose(add100).apply(2);
System.out.println(apply);
// 先乘2 再执行add100
System.out.println(multiple2.andThen(add100).apply(2));
// identity : 恒等函数,就是输出原值,没啥意义
Integer x=900;
System.out.println(System.identityHashCode(x));
Object apply1 = Function.identity().apply(x);
System.out.println(System.identityHashCode(apply1));
Optional 是一个容器类,用于包装可能为空的对象,避免直接返回 null
// optional:通过显式的 API 操作,减少 NullPointerException 的发生
String s = null;
Optional<String> optional = Optional.ofNullable(s);
// map返回一个optional对象,当optional为空时,不会执行对应方法map方法
// orElse表示如果optional对象为空,则返回0
int i = optional.map(String::length).orElse(0);
System.out.println(i);
// 链式编程:避免判空操作
i = Optional.ofNullable(s).map(String::length).orElse(0);
System.out.println(i);
// orElseGet:如果optional对象为空,则调用函数获取值,Supplier接口就一个抽象方法get()
Optional.ofNullable(s).map(String::length).orElseGet(() -> 90);
Stream流操作:
- 中间操作(Intermediate Operations): 通常返回流
-
-
无状态(Stateless)操作:每个数据的处理是独立的,不会影响或依赖之前的数据。如
filter()、flatMap()、map()、peek()、unordered()等// filter ==> 传入一个Predicate对象,重写test方法,test方法内部用于筛选元素 , 返回一个新流 // flatMap: 将多个流(集合),展开成一个新的流 ==> 合并多个List List<List<String>> listOfLists = Arrays.asList( Arrays.asList("a", "b"), Arrays.asList("c", "d"), Arrays.asList("e", "f") ); Stream<Object> objectStream = listOfLists.stream().flatMap(new Function<List<String>, Stream<?>>() { @Override public Stream<?> apply(List<String> strings) { return strings.stream(); } }); objectStream.forEach(System.out::println); // map : 对流中数据类型进行转换,得到新的流 List<String> strings = Arrays.asList("1", "2", "3"); List<Integer> integers = strings.stream() .map(new Function<String, Integer>() { @Override public Integer apply(String s) { return Integer.parseInt(s); } }) .collect(Collectors.toList()); // peek():类似于foreach,不会改变流,同时只有终止操作触发才会执行,通常用于测试 ,unordered()用于声明流是无序的对list速度可能会加快
-
-
-
有状态(Stateful)操作:处理时会记录状态,依赖前一个处理。如
distinct()、sorted(comparator)、limit()、skip()等// distinct 去重 Stream.of(1, 2, 3,5,6,7,4,3,3) .distinct() // 基于equals进行判断是否去重 .forEach(x -> System.out.println("distinct: " + x)); // sorted 排序 Stream.of(1, 2, 3,5,6,7,4,3,3).sorted(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o2-o1; } }).forEach(x -> System.out.println("sorted: " + x)); // limit :取前n个 Stream.of(1, 2, 3,5,6,7,4,3,3).limit(3) .forEach(x -> System.out.println("limit: " + x)); // skip : 跳过前n个 Stream.of(1, 2, 3,5,6,7,4,3,3).skip(3) .forEach(x -> System.out.println("skip: " + x));
-
- 终止操作(Terminal Operations): 无返回值
-
-
非短路操作:处理完所有数据才能得到结果。如
collect()、forEach()、forEachOrdered()、max()、min()、reduce()等。// collect:收集,转为集合类型,分组等操作 List<Integer> collect1 = Stream.of(1, 2, 3, 5, 6, 7, 4, 3, 3).collect(Collectors.toList()); // 转链表 Map<Integer, Integer> collect2 = Stream.of(1, 2, 5, 6, 7, 4, 3).collect(Collectors.toMap(x -> x, x -> x * 2)); // 映射成map,x不能重复 Map<Integer, List<Integer>> collect3 = Stream.of(1, 2, 3, 5, 6, 7, 4, 3, 3).collect(Collectors.groupingBy(x -> x % 2)); // 按照 模2 分组 collect3.entrySet().forEach(x -> System.out.println(x.getKey() + ":" + x.getValue())); // forEach 传入一个Consumer实现即可, forEachOrdered() 用于并行流处理后结果,保证按照原始顺序输出 // max,min 求极值 Optional<Integer> max1 = Stream.of(1, 2, 3, 5, 6, 7, 4, 3, 3).max(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o2 - o1; } }); // reduce : apply的第一个参数是求和就是合并后的结果 System.out.println(max1.get()); Stream.of(1, 2, 3, 5, 6, 7, 4, 3, 3).reduce(new BinaryOperator<Integer>() { @Override public Integer apply(Integer integer, Integer integer2) { System.out.println("integer:" + integer + " integer2:" + integer2); return integer + integer2; } }); -
短路(short-circuiting)操作:拿到符合预期的结果就会停下来,不一定会处理完所有数据。如
anyMatch()、allMatch()、noneMatch()、findFirst()、findAny()等。// anyMatch 存在一个匹配的元素 boolean b = Stream.of(1, 2, 3, 5, 6, 7, 4, 3, 3).anyMatch(new Predicate<Integer>() { @Override public boolean test(Integer integer) { return integer == 3; } }); // allMatch() 所有的都要匹配, noneMatch 一个都不匹配, findFirst 获取首个元素(适用于有序的流), findAny 返回任意一个元素
-
并行流:底层用了ForkJoinPool,ForkJoinPool将任务拆分成多个小任务,然后分散到不同线程中执行,每个线程都有自己的任务队列,当某个线程空闲时会从其他线程的任务队列窃取任务执行,充分发挥了cpu的性能
如果是IO密集型任务,线程阻塞这段时间cpu的性能是没有利用到的,从而io密集型任务不适合ForkJoinPool
Stream.of(1, 2, 3, 5, 6, 7, 4, 3, 3).parallel().forEach(System.out::println); // 不是按照顺序输出
创建流
// 串行流
// 从集合中创建
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream(); // 创建串行流
// 数组中创建
String[] array = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);
// 并行流
// 从集合中创建
List<String> list = Arrays.asList("a", "b", "c", "d");
Stream<String> parallelStream = list.stream().parallel();
// 从普通流中创建
List<String> list = Arrays.asList("a", "b", "c", "d");
Stream<String> parallelStream = list.stream().parallel();