一:简介

Stream中有两个个方法collect和collectingAndThen用于对流中的数据进行处理,可以对流中的数据进行聚合操作,如:

  • 将流中的数据转成集合类型: toList、toSet、toMap、toCollection
  • 将流中的数据(字符串)使用分隔符拼接在一起:joining
  • 对流中的数据求最大值maxBy、最小值minBy、求和summingInt、求平均值averagingDouble
  • 对流中的数据进行映射处理 mapping
  • 对流中的数据分组:groupingBy、partitioningBy
  • 对流中的数据累计计算:reducing
c6e8c7c8eeacda26bed48f50ba11e5b4.png
public final class Collectors {    // 转换成集合    public static  Collector> toList();    public static  Collector> toSet();    public static  Collector> toMap(Function super T, ? extends K> keyMapper,                                    Function super T, ? extends U> valueMapper);    public static > Collector toCollection(Supplier collectionFactory);   // 拼接字符串,有多个重载方法                                     public static Collector joining(CharSequence delimiter);      public static Collector joining(CharSequence delimiter,                                                             CharSequence prefix,                                                             CharSequence suffix);          // 最大值、最小值、求和、平均值                                                             public static  Collector> maxBy(Comparator super T> comparator);    public static  Collector> minBy(Comparator super T> comparator);    public static  Collector summingInt(ToIntFunction super T> mapper);          public static  Collector averagingDouble(ToDoubleFunction super T> mapper);                       // 分组:可以分成true和false两组,也可以根据字段分成多组                                     public static  Collector>> groupingBy(Function super T, ? extends K> classifier);    // 只能分成true和false两组    public static  Collector>> partitioningBy(Predicate super T> predicate);     // 映射     public static  Collector mapping(Function super T, ? extends U> mapper,                               Collector super U, A, R> downstream);     public static  Collector reducing(U identity,                                Function super T, ? extends U> mapper,                                BinaryOperator op);}

二:示例

流转换成集合

@Testpublic void testToCollection(){    List list = Arrays.asList(1, 2, 3);    // [10, 20, 30]    List collect = list.stream().map(i -> i * 10).collect(Collectors.toList());    // [20, 10, 30]    Set collect1 = list.stream().map(i -> i * 10).collect(Collectors.toSet());    // {key1=value:10, key2=value:20, key3=value:30}    Map collect2 = list.stream().map(i -> i * 10).collect(Collectors.toMap(key -> "key" + key/10, value -> "value:" + value));    // [1, 3, 4]    TreeSet collect3= Stream.of(1, 3, 4).collect(Collectors.toCollection(TreeSet::new));}
@Data@ToString@AllArgsConstructor@RequiredArgsConstructorpublic class User {    private Long id;    private String username;}@Testpublic void testToMap() {    List userList = Arrays.asList(         new User(1L, "mengday"),         new User(2L, "mengdee"),         new User(3L, "mengdy")    );    // toMap 可用于将List转为Map,便于通过key快速查找到某个value    Map userIdAndModelMap = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));    User user = userIdAndModelMap.get(1L);    // User(id=1, username=mengday)    System.out.println(user);    Map userIdAndUsernameMap = userList.stream().collect(Collectors.toMap(User::getId, User::getUsername));    String username = userIdAndUsernameMap.get(1L);    // mengday    System.out.println(username);}

集合元素拼接

@Testpublic void testJoining(){    // a,b,c    List list2 = Arrays.asList("a", "b", "c");    String result = list2.stream().collect(Collectors.joining(","));    // Collectors.joining(",")的结果是:a,b,c  然后再将结果 x + "d"操作, 最终返回a,b,cd    String str= Stream.of("a", "b", "c").collect(Collectors.collectingAndThen(Collectors.joining(","), x -> x + "d"));}

元素聚合

@Testpublic void test(){    // 求最值 3    List list = Arrays.asList(1, 2, 3);    Integer maxValue = list.stream().collect(Collectors.collectingAndThen(Collectors.maxBy((a, b) -> a - b), Optional::get));    // 最小值 1    Integer minValue = list.stream().collect(Collectors.collectingAndThen(Collectors.minBy((a, b) -> a - b), Optional::get));    // 求和 6    Integer sumValue = list.stream().collect(Collectors.summingInt(item -> item));    // 平均值 2.0    Double avg = list.stream().collect(Collectors.averagingDouble(x -> x));}
@Testpublic void test(){    // 映射:先对集合中的元素进行映射,然后再对映射的结果使用Collectors操作    // A,B,C    Stream.of("a", "b", "c").collect(Collectors.mapping(x -> x.toUpperCase(), Collectors.joining(",")));}

分组

public class User {    private Long id;    private String username;    private Integer type;    // Getter & Setter & toString}@Testpublic void testGroupBy(){    List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);    // 奇偶数分组:奇数分一组,偶数分一组    // groupingBy(Function super T, ? extends K> classifier) 参数是Function类型,Function返回值可以是要分组的条件,也可以是要分组的字段    // 返回的结果是Map,其中key的数据类型为Function体中计算类型,value是List类型,为分组的结果    Map> result = list.stream().collect(Collectors.groupingBy(item -> item % 2 == 0));    // {false=[1, 3, 5, 7, 9], true=[2, 4, 6, 8, 10]}    System.out.println(result);     // partitioningBy 用于分成两组的情况    Map> twoPartiton = list.stream().collect(Collectors.partitioningBy(item -> item % 2 == 0));    System.out.println(twoPartiton);    User user = new User(1L, "zhangsan", 1);    User user2 = new User(2L, "lisi", 2);    User user3 = new User(3L, "wangwu", 3);    User user4 = new User(4L, "fengliu", 1);    List users = Arrays.asList(user, user2, user3, user4);    // 根据某个字段进行分组    Map> userGroup = users.stream().collect(Collectors.groupingBy(item -> item.type));    /**     * key 为要分组的字段     * value 分组的结果     * {     *  1=[User{id=1, username='zhangsan', type=1}, User{id=4, username='fengliu', type=1}],     *  2=[User{id=2, username='lisi', type=2}],     *  3=[User{id=3, username='wangwu', type=3}]     * }     */    System.out.println(userGroup);}    // 分组并对分组中的数据统计@Testpublic void testGroupBy2() {       Foo foo1 = new Foo(1, 2);        Foo foo2 = new Foo(2, 23);        Foo foo3 = new Foo(2, 6);        List list = new ArrayList<>(4);        list.add(foo1);        list.add(foo2);        list.add(foo3);        Map collect = list.stream().collect(Collectors.groupingBy(Foo::getCode, Collectors.summarizingInt(Foo::getCount)));        IntSummaryStatistics statistics1 = collect.get(1);        IntSummaryStatistics statistics2 = collect.get(2);        System.out.println(statistics1.getSum());        System.out.println(statistics1.getAverage());        System.out.println(statistics1.getMax());        System.out.println(statistics1.getMin());        System.out.println(statistics1.getCount());        System.out.println(statistics2.getSum());        System.out.println(statistics2.getAverage());        System.out.println(statistics2.getMax());        System.out.println(statistics2.getMin());        System.out.println(statistics2.getCount());}

累计操作

@Testpublic void testReducing(){    // sum: 是每次累计计算的结果,b是Function的结果    System.out.println(Stream.of(1, 3, 4).collect(Collectors.reducing(0, x -> x + 1, (sum, b) -> {        System.out.println(sum + "-" + b);        return sum + b;    })));     // 下面代码是对reducing函数功能实现的描述,用于理解reducing的功能    int sum = 0;    List list3 = Arrays.asList(1, 3, 4);    for (Integer item : list3) {        int b = item + 1;        System.out.println(sum + "-" + b);        sum = sum + b;    }    System.out.println(sum);    // 注意reducing可以用于更复杂的累计计算,加减乘除或者更复杂的操作    // result = 2 * 4 * 5 = 40    System.out.println(Stream.of(1, 3, 4).collect(Collectors.reducing(1, x -> x + 1, (result, b) -> {        System.out.println(result + "-" + b);        return result * b;    })));}