Stream 的终止操作
一、规约
* reduce(T iden, BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。 返回 T
* reduce(BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。 返回 Optional<T>
public static void test02() {
//01.数值求和
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
/**
*0 是起始x,0 + y[0] 结果赋值给x, 再➕y[1] 结果再赋值给x 再➕y[2] 。。。。。。
* 因为有起始数值,所以不可能为空,所以返回值为 泛型的类型
*/
Integer reduce = list.stream().reduce(0, (x, y) -> x + y);
System.out.println(reduce);
System.out.println("--------------------");
//02.求JavaBean的工资属性求和
//没有起始值,可能为空,所以返回值类型设为了Optional,为了避免空指针异常,有可能为空的情况就用这个
Optional<Double> reduce2 = emps.stream()
.map(Employee::getSalary)
.reduce(Double::sum);
System.out.println(reduce2.get());
}
二、收集
方法 |
描述 |
collect(Collector c) |
将流转换为其他形式。接收一个 Collector接口的 实现,用于给Stream中元素做汇总的方法 |
Collector 接口中方法的实现决定了如何对流执行收集操作(如收 集到 List、Set、Map)。但是 Collectors 实用类提供了很多静态 方法,可以方便地创建常见收集器实例,具体方法与实例如下表:
/** * 收集 */ public static void collect() { List<String> list = emps.stream() .map(Employee::getName) .collect(Collectors.toList());//Collectors.toSet(); list.forEach(System.out::println); System.out.println("----------------------"); TreeSet<String> treeSet = emps.stream() .map(Employee::getName) .collect(Collectors.toCollection(TreeSet::new)); //定制化容器类 treeSet.forEach(System.out::println); }
三、判断性终止函数
public static void test01() { boolean allMatch = emps.stream().allMatch(x -> x.getStatus().equals(Status.BUSY)); boolean anyMatch = emps.stream().anyMatch(x -> x.getStatus().equals(Status.BUSY)); boolean noneMatch = emps.stream().noneMatch(x -> x.getStatus().equals(Status.BUSY)); //Optional是一个新的集合类,为了防止空指针异常 Optional<Employee> first = emps.stream().sorted((x1,x2) -> Double.compare(x1.getSalary(),x2.getSalary())).findFirst(); Employee employee = first.get(); //并行执行 sorted和findAny Optional<Employee> anyEmployeeOptional = emps.parallelStream().sorted((x1,x2) -> Double.compare(x1.getSalary(),x2.getSalary())).findAny(); Employee anyEmployee = first.get(); long count = emps.stream().count(); Optional<Employee> max = emps.stream().max((x, y) -> Double.compare(x.getSalary(), y.getSalary())); Employee maxSalaryEmployee = max.get(); Optional<Double> minSalary = emps.stream().map(Employee::getSalary) .min(Double::compare); Double maxSalary = minSalary.get(); System.out.println(allMatch); System.out.println(anyMatch); System.out.println(noneMatch); System.out.println(anyEmployee); System.out.println(first); System.out.println(count); System.out.println(maxSalaryEmployee); System.out.println(minSalary); }
四、组函数
/** * 组函数 */ public static void groupFunction() { //总数 long count0 = emps.stream().count(); Long count1 = emps.stream().collect(Collectors.counting()); System.out.println("总数1:" + count0); System.out.println("总数2:" + count1); //平均值 Double avg = emps.stream().collect(Collectors.averagingDouble(Employee::getSalary)); System.out.println("平均值:" + avg); //总和 Double collectSum = emps.stream().collect(Collectors.summingDouble(Employee::getSalary)); double reduceSum = emps.stream().mapToDouble(Employee::getSalary).reduce(0, (x, y) -> x + y); System.out.println("总和1:" + collectSum); System.out.println("总和2:" + reduceSum); //最大值 Optional<Double> collectMax = emps.stream().map(Employee::getSalary).collect(Collectors.maxBy((x1, x2) -> x1.compareTo(x2))); Optional<Double> max = emps.stream().map(Employee::getSalary).max((x1, x2) -> x1.compareTo(x2)); System.out.println("最大值1:" + collectMax.get()); System.out.println("最大值2:" + max.get()); //最小值 Optional<Double> collectMin = emps.stream().map(Employee::getSalary).collect(Collectors.minBy((x1, x2) -> x1.compareTo(x2))); Optional<Double> min = emps.stream().map(Employee::getSalary).min((x1, x2) -> x1.compareTo(x2)); System.out.println("最小值1:" + collectMin.get()); System.out.println("最小值2:" + min.get()); }
五、分组
/** * 分组 */ public static void group() { System.out.println("按照单个字段分组-----------------"); Map<Status, List<Employee>> collectGroupMap = emps.stream().collect(Collectors.groupingBy(Employee::getStatus)); collectGroupMap.forEach((key,value) -> System.out.println(key + " | " + value)); System.out.println(" 先按单个字段分组,每个分组里面再按自定义规则分组-----------------"); Map<Status, Map<String, List<Employee>>> innerGroupMapByIdentify = emps.stream().collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy(x -> { if (((Employee) x).getAge() < 35) { return "青年"; } else if (((Employee) x).getAge() < 55) { return "中年"; } else { return "老年"; } }))); innerGroupMapByIdentify.forEach((key,value) -> System.out.println(key + " | " + value)); System.out.println(" 先按单个字段分组,每个分组里面再按另外一字段分组-----------------"); Map<Status, Map<String, List<Employee>>> innerGroupMapByColum = emps.stream() .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy(Employee::getName) ) ); innerGroupMapByColum.forEach((key,value) -> System.out.println(key + " | " + value)); System.out.println(" 先按2个字段一起分组-----------------"); Map<String, List<Employee>> columsMap = emps.stream() .collect(Collectors.groupingBy(x -> ((Employee) x).getName() + " : " + ((Employee) x).getStatus().toString())); columsMap.forEach((key,value) -> System.out.println(key + " | " + value)); }
六、分区
/** * 分区 */ public static void partition() { //一层分区 Map<Boolean, List<Employee>> partitionMap = emps.stream().collect(Collectors.partitioningBy(x -> x.getAge() > 35)); //多层级分区,二层按照一层相同的规则分区 Map<Boolean, Map<Boolean, List<Employee>>> collect = emps.stream().collect(Collectors.partitioningBy(x -> x.getAge() > 35, Collectors.partitioningBy(x -> x.getSalary() < 6000.0))); //多层级分区,二层按照一层不同的规则分区 Map<Boolean, Map<String, List<Employee>>> collect1 = emps.stream().collect(Collectors.partitioningBy(x -> x.getAge() > 35, Collectors.groupingBy(Employee::getName))); partitionMap.forEach((key,value) -> System.out.println(key + " | " + value)); collect.forEach((key,value) -> System.out.println(key + " | " + value)); collect1.forEach((key,value) -> System.out.println(key + " | " + value)); }
七、字符串拼接:join
/** * 字符串拼接:join */ public static void join(){ String joinResult = emps.stream().map(Employee::getName).collect(Collectors.joining(",", " ===start=== ", " ===end=== ")); System.out.println(joinResult); }