collect
分组和分区
public class StreamTest04 {
    public static void main(String[] args) {
        List<String> list1 = Arrays.asList("hi", "hello", "你好");
        List<String> list2 = Arrays.asList("张三", "李四", "王五");
        List<String> collect = list1.stream().flatMap(l1 -> list2.stream().map(l2 -> l1 + ":" + l2)).collect(Collectors.toList());
        collect.stream().forEach(System.out::println);
       //  hi:张三
       //  hi:李四
       //  hi:王五
       //  hello:张三
       //  hello:李四
       //  hello:王五
       //  你好:张三
       //  你好:李四
       //  你好:王五
        //  ------------1.按年龄分组,并返回每组总数----------------
        List<User> users=Arrays.asList(
                new User("tom",11,87),
                new User("jim",11,88),
                new User("join",12,90),
                new User("tax",13,78)
        );
        Map<Integer, Long> fzOne = users.stream().collect(Collectors.groupingBy(e -> e.getAge(), Collectors.counting()));
        System.out.println(fzOne);
        //{11=2, 12=1, 13=1}
        //  ------------2.按年龄分组,并返回每组的分数平均值----------------
        Map<Integer, Double> fzTwo= users.stream().collect(Collectors.groupingBy(e -> e.getAge(), Collectors.averagingDouble(User::getScore)));
        System.out.println(fzTwo);
        //{11=87.5, 12=90.0, 13=78.0}
    }
    
}
分区: 分区(partitioningBy)可以看成是一种特殊的分组 ,分区只能分为两组 ,即成立某种条件的和不成立某种条件的
//  ------------按照成绩是否大于90分组----------------
     List<User> userList =Arrays.asList(
             new User("tom",11,87),
             new User("jim",11,98),
             new User("join",12,90),
             new User("tax",13,78)
     );
     Map<Boolean, List<User>> c1 = userList.stream().collect(Collectors.partitioningBy(e -> e.getScore() >= 90));
     System.out.println(c1);
     //{
     // false=[User(name=tom, age=11, score=87), User(name=tax, age=13, score=78)],
     // true =[User(name=jim, age=11, score=98), User(name=join, age=12, score=90)]
     // }
     Map<Boolean, Long> c2 = userList.stream().collect(Collectors.partitioningBy(e -> e.getScore() >= 90, Collectors.counting()));
     System.out.println(c2);
     //{false=2, true=2}
收集器:collect
Collector是专门用来作为Stream的collect方法的参数的。 而Collectors是作为生产具体Collector的工具类。
Collector主要包含五个参数,它的行为也是由这五个参数来定义的,如下所示:
public interface Collector<T, A, R> {
    // supplier参数用于生成结果容器,容器类型为A
    Supplier<A> supplier();
    // accumulator用于消费元素,也就是归纳元素,这里的T就是元素,它会将流中的元素一个一个与结果容器A发生操作
    BiConsumer<A, T> accumulator();
    // combiner用于两个两个合并并行执行的线程的执行结果,将其合并为一个最终结果A
    BinaryOperator<A> combiner();
    // finisher用于将之前整合完的结果R转换成为A
    Function<A, R> finisher();
    // characteristics表示当前Collector的特征值,这是个不可变Set
    Set<Characteristics> characteristics();
}
Collectors是一个工具类,是JDK预实现Collector的工具类,它内部提供了多种Collector,如:
toCollection
将流中的元素全部放置到一个集合中返回,这里使用Collection,泛指多种集合。
toSet
将流中的元素放置到一个列表集合中去。这个列表默认为ArrayList。
joining
joining的目的是将流中的元素全部以字符序列的方式连接到一起,可以指定连接符,甚至是结果的前后缀。
public class CollectorsTest {
    public static void joiningTest(List<String> list){
        // 无参方法
        String s = list.stream().collect(Collectors.joining());
        System.out.println(s);
        // 指定连接符
        String ss = list.stream().collect(Collectors.joining("-"));
        System.out.println(ss);
        // 指定连接符和前后缀
        String sss = list.stream().collect(Collectors.joining("-","S","E"));
        System.out.println(sss);
    }
    public static void main(String[] args) {
        List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
        joiningTest(list);
    }
}
console:
1234567891101212121121asdaa3e3e3e2321eew
123-456-789-1101-212121121-asdaa-3e3e3e-2321eew
S123-456-789-1101-212121121-asdaa-3e3e3e-2321eewE
mapping
这个映射是首先对流中的每个元素进行映射,即类型转换,然后再将新元素以给定的Collector进行归纳。
public class CollectorsTest {
    public static void mapingTest(List<String> list){
        List<Integer> ll = list.stream().limit(5).collect(Collectors.mapping(Integer::valueOf,Collectors.toList()));
    }
    public static void main(String[] args) {
        List<String> list = Arrays.asList("123","456","789","1101","111","asdaa","3e3e3e","2321eew");
        mapingTest(list);
    }
}
collectingAndThen
该方法是在归纳动作结束之后,对归纳的结果进行再处理。
public class CollectorsTest {
    public static void collectingAndThenTest(List<String> list){
        int length = list.stream().collect(Collectors.collectingAndThen(Collectors.toList(),e -> e.size()));
        System.out.println(length);
    }
    public static void main(String[] args) {
        List<String> list = Arrays.asList("123","456","789");
        collectingAndThenTest(list);
    }
}
等等………
多级分组
//  ------------按照成绩是否大于90分组----------------
        List<User> userList =Arrays.asList(
                new User("tom",11,87),
                new User("jim",11,98),
                new User("join",12,90),
                new User("tax",13,90)
        );
        // 先按照成绩分组,在按照年龄分组:
        Map<Integer, Map<Integer, List<User>>> cc = userList.stream().collect(Collectors.groupingBy(User::getScore, Collectors.groupingBy(User::getAge)));
        System.out.println(cc);
console:
{
    98={11=[User(name=jim, age=11, score=98)]},
    87={11=[User(name=tom, age=11, score=87)]},
    90={
        12=[User(name=join, age=12, score=90)], 
        13=[User(name=tax, age=13, score=90)]
       }
}
//先按照年龄分组,再求分数最高的
        Map<Integer, User> ccc = userList.stream().collect(Collectors.groupingBy(User::getAge, Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparingInt(User::getScore)), Optional::get)));
        System.out.println(ccc);
console:
{
    11=User(name=jim, age=11, score=98),
    12=User(name=join, age=12, score=90),
    13=User(name=tax, age=13, score=90)
}
给个饭钱?
- Post link: http://sovzn.github.io/2022/12/03/collect/
 - Copyright Notice: All articles in this blog are licensed under unless otherwise stated.
 



若没有本文 Issue,您可以使用 Comment 模版新建。
GitHub Issues