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

相关文章
|
10天前
|
Java
Java中的抽象类:深入了解抽象类的概念和用法
Java中的抽象类是一种不能实例化的特殊类,常作为其他类的父类模板,定义子类行为和属性。抽象类包含抽象方法(无实现)和非抽象方法。定义抽象类用`abstract`关键字,子类继承并实现抽象方法。抽象类适用于定义通用模板、复用代码和强制子类实现特定方法。优点是提供抽象模板和代码复用,缺点是限制继承灵活性和增加类复杂性。与接口相比,抽象类可包含成员变量和单继承。使用时注意设计合理的抽象类结构,谨慎使用抽象方法,并遵循命名规范。抽象类是提高代码质量的重要工具。
25 1
|
29天前
|
前端开发 Java
java中的Queue队列的用法
java中的Queue队列的用法
19 1
|
30天前
|
XML Java 编译器
java aspectjrt AOP 用法
java aspectjrt AOP 用法
21 0
|
1月前
|
Java API 数据处理
探索 Java 8 中的 Stream 流:构建流的多种方式
探索 Java 8 中的 Stream 流:构建流的多种方式
|
1月前
|
Java API 数据处理
Java 8新特性之Stream API详解
【2月更文挑战第22天】本文将深入探讨Java 8中引入的Stream API,这是一种基于函数式编程的新特性,用于处理集合数据。我们将详细介绍Stream的基本概念、操作方法以及在实际开发中的应用,帮助读者更好地理解和使用这一强大的工具。
|
1月前
|
Java API
Java 8新特性之Lambda表达式与Stream API
【2月更文挑战第21天】本文将介绍Java 8中的两个重要特性:Lambda表达式和Stream API。Lambda表达式是Java 8中引入的一种新的编程语法,它允许我们将函数作为参数传递给方法,从而使代码更加简洁、易读。Stream API是一种用于处理集合的新API,它提供了一种高效且易于使用的处理数据的方式。本文将通过实例讲解这两个特性的基本用法以及它们如何帮助我们编写更简洁、高效的Java代码。
|
3天前
|
存储 安全 Java
说说Java 8 引入的Stream API
说说Java 8 引入的Stream API
8 0
|
3天前
|
分布式计算 Java API
Java 8新特性之Lambda表达式与Stream API
【4月更文挑战第16天】本文将介绍Java 8中的两个重要新特性:Lambda表达式和Stream API。Lambda表达式是Java 8中引入的一种新的编程语法,它允许我们将函数作为参数传递给其他方法,从而使代码更加简洁、易读。Stream API是Java 8中引入的一种新的数据处理方式,它允许我们以声明式的方式处理数据,从而使代码更加简洁、高效。本文将通过实例代码详细讲解这两个新特性的使用方法和优势。
|
7天前
|
前端开发 Oracle Java
Java 22 新增利器: 使用 Java Stream Gather 优雅地处理流中的状态
Java 22 新增利器: 使用 Java Stream Gather 优雅地处理流中的状态
17 0