对具有相同特性的值进行分组时一个很常见的任务,我们可以直接使用groupingBy来进行分组。
当分类函数是一个predicate函数时,流会被分成2组列表,一组返回true,一组返回false。
public class Test { public static void main(String[] args) { Stream<Person> stream = Stream.of(new Person("1", "林肯"), new Person("2", "冰儿")); Map<String, List<Person>> collect = stream.collect(Collectors.groupingBy(Person::getId)); for (String string : collect.keySet()) { System.out.println(string + "-->" + collect.get(string)); } System.out.println("=====华丽丽的分割线=========="); Stream<Person> stream1 = Stream.of(new Person("1", "林肯"), new Person("2", "冰儿"), new Person("3", "忽忽")); Map<Boolean, List<Person>> collect2 = stream1.collect(Collectors.partitioningBy(Person::isMyLove)); for (boolean string : collect2.keySet()) { System.out.println(string + "-->" + collect2.get(string)); } } } class Person { private String id; private String name; public Person(String id, String name) { this.id = id; this.name = name; } public boolean isMyLove() { if ("冰儿".equals(name)) { return true; } return false; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person [id=" + id + ", name=" + name + "]"; } }
java8还提供了一些其他的收集器,用来对分组后的元素进行downstream处理,这几个收集器都是Collectors的静态方法,具体介绍如下:
1,counting方法会返回收集元素的总个数。代码如下:
Map<Boolean, Long> collect = stream.collect(Collectors.partitioningBy(Person::isMyLove, Collectors.counting()));2,summing(Int|long|Double)方法接受一个函数作为参数,它会将该函数应用到downstream元素中,并生成他们的求和。代码如下:
Map<Boolean, Integer> collect = stream.collect(Collectors.partitioningBy(Person::isMyLove, Collectors.summingInt(a -> new Integer(((Person) a).getId()))));3,maxBy方法和minBy方法会接受一个比较器,并生成downstream元素的最大值和最小值。代码如下:
Map<Boolean, Optional<Person>> collect = stream.collect(Collectors.partitioningBy(Person::isMyLove, Collectors.maxBy(Comparator.comparing(Person::getId)))); Map<Boolean, Optional<Person>> collect = stream.collect(Collectors.partitioningBy(Person::isMyLove, Collectors.minBy(Comparator.comparing(Person::getId))));4,mapping方法会将一个函数应用到downstream结果上,并且需要另一个收集器来处理结果,代码如下:
Map<Boolean, Optional<String>> collect = stream.collect(Collectors.partitioningBy(Person::isMyLove, Collectors.mapping(Person::getId, Collectors.minBy(Comparator.comparing(String::length)))));5,reducing方法会对downstream元素进行一次普通的聚合操作,代码如下:
Map<Boolean, Optional<Person>> collect = stream.collect(Collectors.partitioningBy(Person::isMyLove, Collectors.reducing((a, b) -> b)));
总结:
downstream收集器可以产生非常复杂的表达式。我们只有在为了通过groupingBy或者partitoningBy来产生“dowmstream”map时,才使用它们。其他情况下,只需要对流直接应用map,reduce,count,max或者min方法即可。