java stream中Collectors的用法

简介: java stream中Collectors的用法

目录



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

相关文章
|
Java API 数据处理
Java新特性:使用Stream API重构你的数据处理
Java新特性:使用Stream API重构你的数据处理
|
Java 大数据 API
Java Stream API:现代集合处理与函数式编程
Java Stream API:现代集合处理与函数式编程
505 100
|
Java API 数据处理
Java Stream API:现代集合处理新方式
Java Stream API:现代集合处理新方式
470 101
|
并行计算 Java 大数据
Java Stream API:现代数据处理之道
Java Stream API:现代数据处理之道
584 101
|
存储 Java API
Java Stream API:现代数据处理之道
Java Stream API:现代数据处理之道
526 188
|
存储 Java API
Java Stream API:现代数据处理之道
Java Stream API:现代数据处理之道
454 92
|
Oracle Java 关系型数据库
掌握Java Stream API:高效集合处理的利器
掌握Java Stream API:高效集合处理的利器
589 80
|
安全 Java API
Java 8 Stream API:高效集合处理的利器
Java 8 Stream API:高效集合处理的利器
501 83
|
Java Unix Go
【Java】(8)Stream流、文件File相关操作,IO的含义与运用
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。!但本节讲述最基本的和流与 I/O 相关的功能。我们将通过一个个例子来学习这些功能。
455 1
|
存储 数据可视化 Java
Java Stream API 的强大功能
Java Stream API 是 Java 8 引入的重要特性,它改变了集合数据的处理方式。通过声明式语法,开发者可以更简洁地进行过滤、映射、聚合等操作。Stream API 支持惰性求值和并行处理,提升了代码效率和可读性,是现代 Java 开发不可或缺的工具。
293 0
Java Stream API 的强大功能