1. Stream
Stream 是元素的集合,类似 Iterator,但行为和集合类又有所不同,是对集合对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作,或者大批量数据操作。Stream 借助于同样新出现的 Lambda 表达式,极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用 fork/join 并行方式来拆分任务和加速处理过程。通常编写并行代码很难而且容易出错, 但使用 Stream 无需编写一行多线程的代码,就可以很方便地写出高性能的并发程序。
2. 用法
2.1 创建 Stream
Stream<Integer> s1 = Stream.of(1); Stream<Integer> s2 = Stream.of(2, 3, 4); Stream<Double> s3 = Stream.generate(Math::random); Stream.iterate(1, x -> x + 1).limit(10).forEach(System.out::print); List<Integer> x = Lists.newArrayList(); Stream<Integer> s4 = x.stream();
四个方法,两种方式
第一种方式,of、generate、iterate,静态工厂方法,区别在于参数的不同
第二种方式,Collection 接口有一个 stream 方法
2.2 distinct、count、limit、sorted、max、min
Stream<Integer> s = Stream.of(1, 2, 3, 4, 5, 1); // 去重、排序、截断、计算个数 System.out.println(s.distinct().sorted((o1,o2) -> o1.compareTo(o2)).limit(3).count()); System.out.println(s.max((o1, o2) -> o1.compareTo(o2)).get()); System.out.println(s.min((o1, o2) -> o1.compareTo(o2)).get());
这几个方法从方法名上就能理解它的意思
2.3 map、mapToInt、mapToLong、mapToDouble
Stream<Integer> s = Stream.of(1, 2, 3, 4); s.map(x -> x * 2).forEach(System.out::print); s.mapToInt(x -> x).forEach(System.out::print); s.mapToLong(x -> x).forEach(System.out::print); s.mapToDouble(x -> x).forEach(System.out::print);
map 对于 Stream 中包含的元素使用给定的转换函数进行转换操作,新生成的 Stream 只包含转换生成的元素。mapToInt、mapToLong、mapToDouble 将新生成的元素转换成特定的类型
2.4 flatMap、flatMapToInt、flatMapToLong、flatMapToDouble
List<Integer> testList0 = Lists.newArrayList(1, 2, 3, 4); List<Integer> testList1 = Lists.newArrayList(6, 7, 8, 9); testList0.stream().flatMap(x -> { if(x == 1 || x ==3) return testList1.stream().skip(x); else return null; }).forEach(System.out::print); // 7899
flatMap 的参数为 Function<? super T, ? extends Stream<? extends R>> mapper 也就是定义一个 Function,这个 Function 的入参是 Stream 中的元素类型,返回的是另一个Stream,其作用和 map 的类似,都是循环元素,不同在返回,map 返回一个对象,flatMap 返回一个 Stream
2.5 allMatch、noneMatch、anyMatch
findFirst、findAny、filter
Stream<Integer> s = Stream.of(1, 2, 3, 4); Predicate<Integer> p = x -> x > 2; s.allMatch(p); // false s.noneMatch(p); // false s.anyMatch(p); // true s.findFirst().orElse(0); // 1 s.findAny().orElse(0); //1 s.filter(p).findFirst().orElse(0); //3
根据判断条件 Predicate 查询,获取对应的元素,match 用于匹配,filter 用作过滤
2.6 skip、peek、collect
Stream<Integer> s = Stream.of(1, 2, 3, 4); s.skip(2).forEach(System.out::print); s.peek(System.out::print).skip(2).limit(2).count(); List<Integer> list = s.collect(Collectors.toList());
skip 返回一个丢弃原 Stream 的前 N 个元素后剩下元素组成的新 Stream
peek 生成一个包含原 Stream 的所有元素的新 Stream,同时会提供一个 Consumer 实例,新 Stream 每个元素被消费的时候都会执行 Consumer
collect 把 Stream 中的要有元素收集到一个结果容器中
2.7 reduce
List<Integer> testList = Lists.newArrayList(1, 2, 3, 4); testList.stream().reduce(0, (sum, item) -> sum + item); // 10 testList.stream().reduce((sum, item) -> sum + item).orElse(0); // 10
reduce 的这两个接口,作用都在于通过后面定义的 BinaryOperator 对 Steam 中的元素进行操作,每次操作的接口,作为 BinaryOperator 中的第一个参数,继续下去,直到所有元素遍历完