流的概念:
步骤
创建stream
可以通过collection系列集合提供的stream()或parallelStream()方法获取,第一个是串行流,第二个是并行流。
Listlist = new ArrayList<>();
Stream stream = list.stream();
通过Arrays中的静态方法stream()获取数组流
Listlist = new ArrayList<>();
Stream stream = list.stream();
通过Stream类中的静态方法of()
Stream stringStream = Stream.of("aa", "bb", "cc");
创建无限流
// 迭代
Stream integerStream = Stream.iterate(0, (x) -> x + 2);// 生成
Stream doubleStream = Stream.generate(Math::random);
中间操作:
惰性求值:多个中间操作连接成一个流水线,除非流水线触发终止操作,否则中间操作不会执行任何处理。在终止操作时一次性全部处理。
筛选与切片操作:
Filter:接收lambda,从流中排除某些元素
内部迭代:
惰性求值:
filter(x -> x.getAge() > 10)
limit:截断流,使其元素不超过给定数量
内部会先找到满足条件的前n个值,内部迭代操作也仅仅在这几个值进行,我们称之为短路
employees.stream().filter(e->{System.out.println("limit");return e.getSalary() > 5000;}).limit(5).forEach(System.out::println);
skip:跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与limit互补
distinct:筛选,通过流所生成元素的hashcode( )和equals()去除重复元素
映射:
map(Function f):
mapToDouble(ToDoubleFunction f)
mapToInt(ToIntFunction f)
mapToLong(ToLongFunction f)
flatMap(Function f):接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。
flatMap和Map的区别:
public static Stream filterCharacter(String str){Listlist = new ArrayList<>();for(Character ch:str.toCharArray()){list.add(ch);}return list.stream();}@Testpublic void test6(){List list = Arrays.asList("aaa","bbb","ccc","ddd","eee");// 用map,返回Stream>Stream> streamStream = list.stream().map(TestStreamAPI2::filterCharacter);// 用flatMap,返回StreamStream characterStream = list.stream().flatMap(TestStreamAPI2::filterCharacter);}
排序:
sorted():自然排序,按照对象指定的Comparable排序
sorted(Comparator comp):定制排序Comparator
employees.stream().sorted((e1,e2)->{if(e1.getAge()!=e2.getAge()){return -e1.getAge()+e2.getAge();}else return e1.getName().compareTo(e2.getName());}).forEach(System.out::println);
终止操作
查找与匹配
allMatch():检查是否匹配所有元素,相当于全称量词
boolean b = employees.stream().allMatch(e -> e.getStatus().equals(Status.BUSY));
anyMatch():是否存在一个匹配值,相当于存在量词
noneMatch():检查是否没有匹配的元素,相当于存在量词的非
findFirst():找到第一个元素,返回optional对象
Optional对象:一个容器类,为了避免空指针异常,当返回的值有可能为空时,就会封装进optional
orElse方法:如果当前容器封装的对象指针为空,可以搞一个替代的对象
Optional first = employees.stream().sorted(Comparator.comparingDouble(Employee::getSalary)).findFirst();first.orElse(new Employee());
findAny():找到任意一个元素
count:返回流中元素总数
long count = employees.stream().count();
min:返回流中最小值
Optional min = employees.stream().map(Employee::getSalary).min(Double::compare);System.out.println(min.get());
max:返回流中的最大值
归约 reduce(T identity, Binaryoperator) / reduce(BinaryOperator) 可以将流中元素反复结合起来,得到一个值。
reduce(T identity, Binaryoperator) : 第一个参数为启始值,第二个参数为运算式
map-reduce 连用成为map-reduce模式:
Optional map-reduce = employees.stream().map(Employee::getSalary).reduce(Double::sum);System.out.println();
收集 collect-将流转换为其他形式。接收一个collector接口的实现,用于Stream中元素汇总方法
collect(Collector c )
// 使用listList collect = employees.stream().map(Employee::getName).collect(Collectors.toList());collect.forEach(System.out::println);// 使用setSet set = employees.stream().map(Employee::getName).collect(Collectors.toSet());set.forEach(System.out::println);// 使用构造HashSet stringHashSet = employees.stream().map(Employee::getName).collect(Collectors.toCollection(HashSet::new));
Collector.counting:收集总数
Long aLong = employees.stream().collect(Collectors.counting());
Collector.avg : 平均值
Double avg = employees.stream().collect(Collectors.averagingDouble(Employee::getSalary));
Collector.summing :总和
Double sum = employees.stream().collect(Collectors.summingDouble(Employee::getSalary));
最大值:
Optional max = employees.stream().collect(Collectors.maxBy(Comparator.comparingDouble(Employee::getSalary)));
最小值
Optional min = employees.stream().map(e -> e.getSalary()).collect(Collectors.minBy(Double::compareTo));// 或者
Optional min = employees.stream().map(Employee::getSalary).min(Double::compareTo);
分组:
Map> statusListMap = employees.stream().collect(Collectors.groupingBy(Employee::getStatus));
多级分组
Map>> statusMapMap = employees.stream().collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy(e -> {if (e.getAge() > 50) return "老年";else if (e.getAge() <= 50 && e.getAge() > 30) return "中年";else return "青年";})));
分区
Map> listMap = employees.stream().collect(Collectors.partitioningBy(e -> e.getSalary() > 8000));
统计
DoubleSummaryStatistics collect = employees.stream().collect(Collectors.summarizingDouble(Employee::getSalary));System.out.println(collect.getAverage());System.out.println(collect.getMax());System.out.println(collect.getSum());
字符串连接
String collectStr = employees.stream().map(Employee::getName).collect(Collectors.joining(","));