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
@Builder
public 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<>();@Beforepublic 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());}@Testpublic 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()最少接收两个参数

    @Testpublic 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改成一样,再次运行机会抛出异常

    @Beforepublic 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());}@Testpublic 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的问题

    @Beforepublic 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());}@Testpublic 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

    @FunctionalInterface
    public 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()方法

总共默认了三个拼接方法

    @Testpublic 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<>();@Beforepublic 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());}@Testpublic 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 发布!

Collectors简单使用相关推荐

  1. 还在用Spring Security?推荐你一款使用简单、功能强大的权限认证框架

    欢迎关注方志朋的博客,回复"666"获面试宝典 来源:blog.csdn.net/qq_40058629/article/ details/116692302 我们先看一下官网介绍 ...

  2. java8 group by_java8新特性Java 8 – Stream Collectors groupingBy 示例 - Java教程

    在这篇教程中,将向你展示如何使用Java 8 Stream的Collectors,来对一个List进行分组,计算个数,求和以及排序. 1. Group By, Count and Sort 1.1 对 ...

  3. js 中转换成list集合_java stream中Collectors的用法

    简介 在java stream中,我们通常需要将处理后的stream转换成集合类,这个时候就需要用到stream.collect方法.collect方法需要传入一个Collector类型,要实现Col ...

  4. java 返回double数组_java-如何使用Collectors.averagingDouble计算双精度数组的均值?

    我不明白为什么以下代码无法编译: import java.util.Arrays; import java.util.stream.Collectors; public class AppMain { ...

  5. 朱晔和你聊Spring系列S1E7:简单好用的Spring Boot Actuator

    本文会来看一下Spring Boot Actuator提供给我们的监控端点Endpoint.健康检查Health和打点指标Metrics等所谓的Production-ready(生产环境必要的一些)功 ...

  6. 打印Java数组的最简单方法是什么?

    在Java中,数组不会覆盖toString() ,因此,如果尝试直接打印一个,则将得到className +'@'+数组的hashCode的十六进制,如Object.toString()所定义: in ...

  7. 原来这就是Java代码生成器的原理啊,太简单了

    1. 前言 前几天写了篇关于代码生成器的文章(可查看历史文章),不少同学私下问我这个代码生成器是如何运作的,为什么要用到一些模板引擎,所以今天来说明下代码生成器的流程. 2. 代码生成器的使用场景 我 ...

  8. java foreach用法_Java十大简单性能优化

    以下是Java中最容易进行的10个性能优化: 1.使用StringBuilder 这几乎是所有Java代码中的默认设置.尽量避免+操作员.当然,您可能会争辩说它StringBuilder无论如何都是语 ...

  9. java8新特性-lambda表达式和stream API的简单使用

    一.为什么使用lambda Lambda 是一个 匿名函数,我们可以把 Lambda表达式理解为是 一段可以传递的代码(将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码风 ...

最新文章

  1. 阿里云OSS上传图片实现流程
  2. 与江岭师弟的讨论 - 关于形式化逻辑的局限以及其它
  3. 字符串字符和数字分割
  4. 界面设计方法 (1) — 2.活动功能的设计
  5. 保存时间 默认_操作技能|WORD文档没保存,有办法恢复吗?
  6. 使用WindowsXP中的网桥功能
  7. Windows 10 使用问题
  8. 机器学习基础算法33-HMM实践
  9. NVIDIA下载老版本驱动/CUDA/Video Codec SDK的链接
  10. 关于ATmega328P和ATmega328PB中16位定时器的使用
  11. 【优雅的使用Matlab进行机器学习】作业
  12. 洛谷题解(持续更新)
  13. 如何手动彻底消除U盘使用痕迹
  14. kali功能介绍及安装(超详细)
  15. 笔记本显示器仅计算机,笔记本可以当屏幕用 笔记本屏幕当显示器用
  16. Linux 查询系统日志
  17. OKHttp源码详解_tony_851122
  18. UVA11584PartitioningByPalindromes
  19. Mark loves cat
  20. C语言数据类型谜题总结

热门文章

  1. android+系统画面恢复,坚持Android系统恢复?轻松修复它
  2. 如何彻底关掉pycharm的警告
  3. css flex布局超长自动换行
  4. ROS-Industrial 之 MoveIt —— 碰撞物体约束添加
  5. 密码学系列之:生日攻击
  6. C语言课设 航空订票系统
  7. Java 三种循环的流程图画法总结(for,while,do-while循环)
  8. 罗马音平假名中文可复制_如何快速有效地学习日语五十音?
  9. PDN设计关键点之滤波电容位置
  10. Carsim2016和Matlab 2018 联合仿真