Collectors

Collectors类API

1. public static <T, C extends Collection<T>> Collector<T, ?, C> toCollection(Supplier<C> collectionFactory);    2. public static <T> Collector<T, ?, List<T>> toList();3. public static <T> Collector<T, ?, Set<T>> toSet();    4. public static <T, K, U> Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,                                    Function<? super T, ? extends U> valueMapper) ;5. public static <T, K, U> Collector<T, ?, Map<K,U>> toMap(                                    Function<? super T, ? extends K> keyMapper,                                    Function<? super T, ? extends U> valueMapper,                                    BinaryOperator<U> mergeFunction);6. public static <T, K, U, M extends Map<K, U>> Collector<T, ?, M> toMap(                                Function<? super T, ? extends K> keyMapper,                                Function<? super T, ? extends U> valueMapper,                                BinaryOperator<U> mergeFunction,                                Supplier<M> mapSupplier);    7. public static <T, K> Collector<T, ?, Map<K, List<T>>>    groupingBy(Function<? super T, ? extends K> classifier) ;8. public static <T, K, A, D>    Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,                                          Collector<? super T, A, D> downstream) ;9. public static <T, K, D, A, M extends Map<K, D>>    Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier,                                  Supplier<M> mapFactory,                                  Collector<? super T, A, D> downstream);    10. public static Collector<CharSequence, ?, String> joining();11. public static Collector<CharSequence, ?, String> joining(CharSequence delimiter);12. public static Collector<CharSequence, ?, String> joining(CharSequence delimiter,                                                             CharSequence prefix,                                                             CharSequence suffix) ;13. public static <T, U, A, R>    Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper,                               Collector<? super U, A, R> downstream)
@Getter@Setter@ToString@Builderpublic class Student {    private Long id;    private String name;    private Integer age;    private String address;}

toCollection办法

Collectors类给了toList()toSet()办法,默认的是ArrayListHashSet,所以要想应用其余的类型的汇合就能够应用这个办法,例如应用LinkedList

public class CollectorsTest {    public static void main(String[] args) {    }        private List<Student> list = new ArrayList<>();    @Before    public void init(){        Student student1 = Student.builder().id(1L).name("张三").age(20).address("北京").build();        Student student2 = Student.builder().id(2L).name("李四").age(21).address("上海").build();        Student student3 = Student.builder().id(3L).name("王五").age(22).address("广州").build();        Student student4 = Student.builder().id(4L).name("赵六").age(23).address("重庆").build();        Student student5 = Student.builder().id(5L).name("钱七").age(24).address("武汉").build();        list = Stream.of( student4,student5,student1, student2, student3).collect(Collectors.toList());    }    @Test    public void testCollection(){        System.out.println("list : ");        System.out.println(JSON.toJSONString(list));        LinkedList<Student> linkedList = list.stream().collect(Collectors.toCollection(LinkedList::new));        System.out.println("linkedList : ");        System.out.println(JSON.toJSONString(linkedList));    }}
list : [{"address":"北京","age":20,"id":1,"name":"张三"},{"address":"上海","age":21,"id":2,"name":"李四"},{"address":"广州","age":22,"id":3,"name":"王五"},{"address":"重庆","age":23,"id":4,"name":"赵六"},{"address":"武汉","age":24,"id":5,"name":"钱七"}]linkedList : [{"address":"北京","age":20,"id":1,"name":"张三"},{"address":"上海","age":21,"id":2,"name":"李四"},{"address":"广州","age":22,"id":3,"name":"王五"},{"address":"重庆","age":23,"id":4,"name":"赵六"},{"address":"武汉","age":24,"id":5,"name":"钱七"}]

toList()办法

这个最常见和罕用的办法

List<Student> list = Stream.of( student4,student5,student1, student2, student3).collect(Collectors.toList());

toSet()办法

这个也是最常见和罕用的办法

Set<Student> set = Stream.of(student4, student5, student1, student2, student3).collect(Collectors.toSet());

toMap()办法

toMap()起码接管两个参数

    @Test    public void testToMap(){        Map<Long, Student> towParamMap = list.stream().collect(Collectors.toMap(Student::getId, Function.identity()));        System.out.println(JSON.toJSONString(towParamMap));    }

Collectors.toMap(Student::getId, Function.identity())这个办法碰到反复的key会抛出异样,把张三和李四的id改成一样,再次运行机会抛出异样

    @Before    public void init(){        Student student1 = Student.builder().id(1L).name("张三").age(20).address("北京").build();        Student student2 = Student.builder().id(1L).name("李四").age(21).address("上海").build();        Student student3 = Student.builder().id(3L).name("王五").age(22).address("广州").build();        Student student4 = Student.builder().id(4L).name("赵六").age(23).address("重庆").build();        Student student5 = Student.builder().id(5L).name("钱七").age(24).address("武汉").build();        list = Stream.of(student1, student2, student3,student4,student5).collect(Collectors.toList());    }    @Test    public void testToMap(){        Map<Long, Student> towParamMap = list.stream().collect(Collectors.toMap(Student::getId, Function.identity()));        System.out.println(JSON.toJSONString(towParamMap));    }
java.lang.IllegalStateException: Duplicate key Student(id=1, name=张三, age=20, address=北京)

所以应用这个办法时须要留神,这时能够通过第三个参数来解决反复key的问题

    @Before    public void init(){        Student student1 = Student.builder().id(1L).name("张三").age(20).address("北京").build();        Student student2 = Student.builder().id(1L).name("李四").age(21).address("上海").build();        Student student3 = Student.builder().id(3L).name("王五").age(22).address("广州").build();        Student student4 = Student.builder().id(4L).name("赵六").age(23).address("重庆").build();        Student student5 = Student.builder().id(5L).name("钱七").age(24).address("武汉").build();        list = Stream.of(student1, student2, student3,student4,student5).collect(Collectors.toList());    }    @Test    public void testToMap(){        Map<Long, Student> threeParamMap = list.stream().collect(Collectors.toMap(Student::getId, Function.identity(), (a,b) -> b));        System.out.println(JSON.toJSONString(threeParamMap));    }

后果为

{1:{"address":"上海","age":21,"id":1,"name":"李四"},3:{"address":"广州","age":22,"id":3,"name":"王五"},4:{"address":"重庆","age":23,"id":4,"name":"赵六"},5:{"address":"武汉","age":24,"id":5,"name":"钱七"}}

能够看到李四笼罩了张三,所以理论中应用时也要留神数据抉择.留神一下这个函数(a,b) -> b也能够从新本人定义一个合并的函数BinaryOperator<U> mergeFunction来解决反复数据

还有四个参数的办法能够不应用默认的HashMap而应用其余的容器,例如TreeMap

Map<Long, String> fourParamMap = list.stream().collect(Collectors.toMap(Student::getId, student -> student.getName(), (a,b) -> b, TreeMap::new));System.out.println(JSON.toJSONString(fourParamMap));

后果

{1:"李四",3:"王五",4:"赵六",5:"钱七"}

groupingBy()办法

Collectors类 groupingBy 办法

  1. 一个参数的办法

    一个参数的办法,还是调用的两个参数的重载办法,第二个参数默认调用 toList() 办法

    public static <T, K> Collector<T, ?, Map<K, List<T>>>    groupingBy(Function<? super T, ? extends K> classifier) {        return groupingBy(classifier, toList());    }

    示例:

    public class GroupingByTest {    public static void main(String[] args) {        List<Student> students = new ArrayList<>();        Student student = new Student();        student.setId(1L);        student.setName("小明");        students.add(student);        Student student2 = new Student();        student2.setId(2L);        student2.setName("小红");        students.add(student2);        Map<Long, List<Student>> collect = students.stream().collect(Collectors.groupingBy(s -> {            return s.getId();        }));        System.out.println(JSON.toJSONString(collect));    }}

    后果

    {1:[{"id":1,"name":"小明"}],2:[{"id":2,"name":"小红"}]}

    groupingBy 办法参数Function<? super T, ? extends K> classifier

    @FunctionalInterfacepublic interface Function<T, R> {    R apply(T t);}

Function是函数式接口,接管一个参数T,返回一个后果R,示例中能够示意为上面这样的,先创立一个Function接口,再将接口当作参数传进去.

   Function<Student, Long> groupingByFun = s -> {return s.getId()};           Map<Long, List<Student>> collect = students.stream().collect(Collectors.groupingBy(groupingByFun           ));

优化s -> {return s.getId()} 能够简化写法

Function<Student, Long> groupingByFun = s -> {return s.getId()};// 能够简化成Function<Student, Long> groupingByFun = s ->  s.getId();// 再一次简化Function<Student, Long> groupingByFun = Student::getId;
  1. 两个参数的办法

    public static <T, K, A, D>    Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,                                          Collector<? super T, A, D> downstream) {        return groupingBy(classifier, HashMap::new, downstream);    }

    示例

    Map<Long, Long> countMap = students.stream().collect(Collectors.groupingBy(Student::getId, Collectors.counting()));        System.out.println(JSON.toJSONString(countMap));// {1:1,2:1}
  1. 三个参数的办法

    public static <T, K, D, A, M extends Map<K, D>>    Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier,                                  Supplier<M> mapFactory,                                  Collector<? super T, A, D> downstream) {    }

    示例

    TreeMap<Long, Set<Student>> treeMapSet = students.stream().collect(Collectors.groupingBy(Student::getId, TreeMap::new, Collectors.toSet()));System.out.println(JSON.toJSONString(treeMapSet));// {1:[{"id":1,"name":"小明"}],2:[{"id":2,"name":"小红"}]}

joining()办法

总共默认了三个拼接办法

    @Test    public void testJoin(){        String join = Stream.of("hello", "world", "hello", "java").collect(Collectors.joining());        System.out.println(join);        String join1 = Stream.of("hello", "world", "hello", "java").collect(Collectors.joining(","));        System.out.println(join1);        String join2 = Stream.of("hello", "world", "hello", "java").collect(Collectors.joining(",","",""));        System.out.println(join2);    }// helloworldhellojava//hello,world,hello,java//hello,world,hello,java

从外部实现来看,还是有不一样,不带参数的办法,外部应用StringBuilder实现

public static Collector<CharSequence, ?, String> joining() {        return new CollectorImpl<CharSequence, StringBuilder, String>(                StringBuilder::new, StringBuilder::append,                (r1, r2) -> { r1.append(r2); return r1; },                StringBuilder::toString, CH_NOID);    }

带参数的办法应用StringJoiner实现

public static Collector<CharSequence, ?, String> joining(CharSequence delimiter,                                                             CharSequence prefix,                                                             CharSequence suffix) {        return new CollectorImpl<>(                () -> new StringJoiner(delimiter, prefix, suffix),                StringJoiner::add, StringJoiner::merge,                StringJoiner::toString, CH_NOID);    }

mapping()办法

mapping简略用法,mapping最简略的用法能够和map办法一样收集某一个字段的值,大部分状况能够和groupingBy,配合应用,例如分组之后只想取某一个字段的值,就能够应用Collectors.mapping配合

    private List<Student> list = new ArrayList<>();    @Before    public void init(){        Student student1 = Student.builder().id(1L).name("张三").age(20).address("北京").build();        Student student2 = Student.builder().id(1L).name("李四").age(21).address("上海").build();        Student student3 = Student.builder().id(3L).name("王五").age(22).address("广州").build();        Student student4 = Student.builder().id(4L).name("赵六").age(23).address("重庆").build();        Student student5 = Student.builder().id(5L).name("钱七").age(24).address("武汉").build();        list = Stream.of(student1, student2, student3,student4,student5).collect(Collectors.toList());    }    @Test    public void testMapping(){        // 收集单个字段         List<Long> mappingList = list.stream().collect(Collectors.mapping(Student::getId, Collectors.toList()));        System.out.println(JSON.toJSONString(mappingList));        // 和groupingBy配合应用        Map<Long, List<String>> mapping = list.stream().collect(Collectors.groupingBy(Student::getId, Collectors.mapping(Student::getName, Collectors.toList())));        System.out.println(JSON.toJSONString(mapping));    }
本文由博客一文多发平台 OpenWrite 公布!