java stream中Collectors的用法

简介

在java stream中,我们通常需要将处理后的stream转换成集合类,这个时候就需要用到stream.collect方法。collect方法需要传入一个Collector类型,要实现Collector还是很麻烦的,需要实现好几个接口。

于是java提供了更简单的Collectors工具类来方便我们构建Collector。

下面我们将会具体讲解Collectors的用法。

假如我们有这样两个list:

List<String> list = Arrays.asList("jack", "bob", "alice", "mark");
List<String> duplicateList = Arrays.asList("jack", "jack", "alice", "mark");

上面一个是无重复的list,一个是带重复数据的list。接下来的例子我们会用上面的两个list来讲解Collectors的用法。

Collectors.toList()

List<String> listResult = list.stream().collect(Collectors.toList());
log.info("{}",listResult);

将stream转换为list。这里转换的list是ArrayList,如果想要转换成特定的list,需要使用toCollection方法。

Collectors.toSet()

Set<String> setResult = list.stream().collect(Collectors.toSet());
log.info("{}",setResult);

toSet将Stream转换成为set。这里转换的是HashSet。如果需要特别指定set,那么需要使用toCollection方法。

因为set中是没有重复的元素,如果我们使用duplicateList来转换的话,会发现最终结果中只有一个jack。

Set<String> duplicateSetResult = duplicateList.stream().collect(Collectors.toSet());
log.info("{}",duplicateSetResult);

Collectors.toCollection()

上面的toMap,toSet转换出来的都是特定的类型,如果我们需要自定义,则可以使用toCollection()

List<String> custListResult = list.stream().collect(Collectors.toCollection(LinkedList::new));
log.info("{}",custListResult);

上面的例子,我们转换成了LinkedList。

Collectors.toMap()

toMap接收两个参数,第一个参数是keyMapper,第二个参数是valueMapper:

Map<String, Integer> mapResult = list.stream()
.collect(Collectors.toMap(Function.identity(), String::length));
log.info("{}",mapResult);

如果stream中有重复的值,则转换会报IllegalStateException异常:

Map<String, Integer> duplicateMapResult = duplicateList.stream()
.collect(Collectors.toMap(Function.identity(), String::length));

怎么解决这个问题呢?我们可以这样:

Map<String, Integer> duplicateMapResult2 = duplicateList.stream()
.collect(Collectors.toMap(Function.identity(), String::length, (item, identicalItem) -> item));
log.info("{}",duplicateMapResult2);

在toMap中添加第三个参数mergeFunction,来解决冲突的问题。

Collectors.collectingAndThen()

collectingAndThen允许我们对生成的集合再做一次操作。

List<String> collectAndThenResult = list.stream()
.collect(Collectors.collectingAndThen(Collectors.toList(), l -> {return new ArrayList<>(l);}));
log.info("{}",collectAndThenResult);

Collectors.joining()

Joining用来连接stream中的元素:

String joinResult = list.stream().collect(Collectors.joining());
log.info("{}",joinResult);
String joinResult1 = list.stream().collect(Collectors.joining(" "));
log.info("{}",joinResult1);
String joinResult2 = list.stream().collect(Collectors.joining(" ", "prefix","suffix"));
log.info("{}",joinResult2);

可以不带参数,也可以带一个参数,也可以带三个参数,根据我们的需要进行选择。

Collectors.counting()

counting主要用来统计stream中元素的个数:

Long countResult = list.stream().collect(Collectors.counting());
log.info("{}",countResult);

Collectors.summarizingDouble/Long/Int()

SummarizingDouble/Long/Int为stream中的元素生成了统计信息,返回的结果是一个统计类:

IntSummaryStatistics intResult = list.stream()
.collect(Collectors.summarizingInt(String::length));
log.info("{}",intResult);

输出结果:

22:22:35.238 [main] INFO com.flydean.CollectorUsage - IntSummaryStatistics{count=4, sum=16, min=3, average=4.000000, max=5}

Collectors.averagingDouble/Long/Int()

averagingDouble/Long/Int()对stream中的元素做平均:

Double averageResult = list.stream().collect(Collectors.averagingInt(String::length));
log.info("{}",averageResult);

Collectors.summingDouble/Long/Int()

summingDouble/Long/Int()对stream中的元素做sum操作:

Double summingResult = list.stream().collect(Collectors.summingDouble(String::length));
log.info("{}",summingResult);

Collectors.maxBy()/minBy()

maxBy()/minBy()根据提供的Comparator,返回stream中的最大或者最小值:

Optional<String> maxByResult = list.stream().collect(Collectors.maxBy(Comparator.naturalOrder()));
log.info("{}",maxByResult);

Collectors.groupingBy()

GroupingBy根据某些属性进行分组,并返回一个Map:

Map<Integer, Set<String>> groupByResult = list.stream()
.collect(Collectors.groupingBy(String::length, Collectors.toSet()));
log.info("{}",groupByResult);

Collectors.partitioningBy()

PartitioningBy是一个特别的groupingBy,PartitioningBy返回一个Map,这个Map是以boolean值为key,从而将stream分成两部分,一部分是匹配PartitioningBy条件的,一部分是不满足条件的:

 Map<Boolean, List<String>> partitionResult = list.stream()
.collect(Collectors.partitioningBy(s -> s.length() > 3));
log.info("{}",partitionResult);

看下运行结果:

22:39:37.082 [main] INFO com.flydean.CollectorUsage - {false=[bob], true=[jack, alice, mark]}

结果被分成了两部分。

总结

Collectors是一个非常强大的工具类,希望大家能够灵活使用。

本文的例子https://github.com/ddean2009/learn-java-streams/tree/master/Collectors

欢迎关注我的公众号:程序那些事,更多精彩等着您!

更多内容请访问 www.flydean.com

java stream中Collectors的用法的更多相关文章

  1. JAVA语言中冒号的用法

    近来由于本人要介入android平台的开发,所以就买了本JAVA语言的书学习.学习一段时间来,我的感觉是谭浩强就是厉害,编写的<C编程语言>系列丛书不愧是经典.书中对C语言的介绍既系统又全 ...

  2. Java集合中List的用法

    List接口是Collection接口的子接口,List有一个重要的实现类--ArrayList类,List中的元素是有序排列的而且可重复,所以被称为是序列. List可以精确的控制每个元素的插入位置 ...

  3. java web中cookies的用法 转

    一.什么是cookies? 大家都知道,浏览器与WEB服务器之间是使用HTTP协议进行通信的,当某个用户发出页面请求时,WEB服务器只是简单的进行响应,然后就关闭与该用户的 连接.因此当一个请求发送到 ...

  4. java string中indexOf()常用用法

    Java中字符串中子串的查找共有四种方法,如下: 1.int indexOf(String str) :返回第一次出现的指定子字符串在此字符串中的索引. 2.int indexOf(String st ...

  5. Java类中static的用法

    关于Java中static的使用有以下四种情况: 1.静态成员变量         被static修饰的成员变量,叫静态成员变量或类变量:没有被static修饰的变量,叫实例变量. 两者的区别是:  ...

  6. java——ArrayList中常见方法用法

    package com.xt.list; import java.util.ArrayList; import java.util.Iterator; import java.util.List; p ...

  7. Java线程中yield()的用法

    Thread.yield()方法的作用:暂停当前正在执行的线程,并执行其他线程.(可能没有效果) yield()让当前正在运行的线程回到可运行状态,以允许具有相同优先级的其他线程获得运行的机会.因此, ...

  8. java 10 中 var关键字用法

    引用:https://mp.weixin.qq.com/s/n1tcJ0CywSi0j-YycGPwxg what java10引入了局部变量折断 var用于声明局部变量. 如var user=new ...

  9. Java Stream函数式编程第三篇:管道流结果处理

    一.Java Stream管道数据处理操作 在本号之前写过的文章中,曾经给大家介绍过 Java Stream管道流是用于简化集合类元素处理的java API.在使用的过程中分为三个阶段.在开始本文之前 ...

随机推荐

  1. 9.Metasploit制作木马后门

    01木马与后门   木马?后门? 木马和后门都有害,尤其是木马,它由攻击者主动发起,稍不留心就会被利用:后门原来是留给自己方便用的,但也有可能被非法利用,这两种程序都会给用户带来损失. 木马是指潜伏在 ...

  2. C++ 同类不同对象的互相访问

    C++ 同类不同对象的互相访问 C++ 允许同一个类的不同对象(实例)访问彼此的私有成员. 示例 #include <iostream> using namespace std; clas ...

  3. Kylin 新定位:分析型数据仓库

    亲爱的各位社区朋友: Apache Kylin 在 2014 年 10 月开源并加入 Apache 软件基金会的孵化器,一年后从孵化器毕业成为 Apache 顶级项目.从第一天起,Kylin 的标语是 ...

  4. Linux基础篇,文本数据的比较与排序:sort、uniq、comm、diff

    一.sort sort命令用于将文本文件内容以行排序 sort [选项参数] [-o<输出文件>] [-t<分隔字符>] [+<起始栏位> -<结束栏位> ...

  5. c++用递归法将一个整数n转换成字符串

    任务描述 用递归法将一个整数n转换成字符串.例如,输入483,应输出字符串“483”.n的位数不确定,可以是任意位数的整数. 测试输入: 预期输出: 程序源码: #include <stdio. ...

  6. GO中的逃逸分析

    1.什么是逃逸分析 以前写c/c++代码时,为了提高效率,常常将pass-by-value(传值)“升级”成pass-by-reference,企图避免构造函数的运行,并且直接返回一个指针. 那么这里 ...

  7. EL表达式 -- 比较不错

    EL表达式 EL 全名为Expression Language EL 语法很简单,它最大的特点就是使用上很方便.接下来介绍EL主要的语法结构: ${sessionScope.user.sex} 所有E ...

  8. SpringMVC中利用HandlerExceptionResolver完成异常处理

    在解决Controller层中的异常问题时,如果针对每个异常处理相对较为繁琐.在SpringMVC中提供了HandlerExceptionResolver用于处理捕获到的异常,从而重新定义返回给前端的 ...

  9. Shell 变量引用实例

    初学 Shell 编程时,对变量各种引用使用不太熟悉,走了很多弯路,本文记录变量引用的一些用法,希望对大家有所帮助. 引用 引用指将字符串用引用符号引起来,以防止特殊字符被 shell 脚本解释为其他 ...

  10. 学习Salesforce | Platform Developer Ⅰ 平台初级开发认证考试指南及备考资源

    一.平台开发人员考试计划 Salesforce平台开发人员初级认证面向具有在Lightning平台上构建自定义应用程序的知识.技能和经验的个人. 该认证考核Lightning平台的基本编程能力,并会使 ...