首页 > 编程语言 >collect 详细解析 Java 8 Stream API 中的 collect 方法

collect 详细解析 Java 8 Stream API 中的 collect 方法

时间:2024-07-16 14:55:54浏览次数:16  
标签:java Java Stream Collectors 收集器 util collect import

collect 详解

 Java 8 引入的 Stream API 提供了一种强大的方式来处理集合数据
 其中的 collect 方法是一个关键操作,用于将流中的元素收集到不同类型的结果容器中。
 本文将详细介绍 Java 中 Stream 的 collect 方法
 包括其基本用法、常见的收集器以及一些实际应用场景。

1,collect 方法的基本用法

collect 方法是 Stream API 中的一个终端操作,它接受一个 Collector 参数,用于将流中的元素累积成一个结果。Collector 接口定义了如何收集元素的方法,通常使用 Collectors 工具类来提供各种预定义的收集器。

基本语法:

<R, A> R collect(Collector<? super T, A, R> collector)
其中:
T 是流中元素的类型。
A 是累加器的类型,用于在收集过程中累积部分结果。
R 是收集操作最终要返回的类型。

示例1:将元素收集为列表

假设我们有一个字符串列表,我们希望将其中长度大于等于5的字符串收集到一个新的列表中。

List<String> words = Arrays.asList("apple", "banana", "grape", "orange", "kiwi");

List<String> longWords = words.stream()
                             .filter(word -> word.length() >= 5)
                             .collect(Collectors.toList());

System.out.println(longWords); // 输出:[banana, orange]

在这个示例中,collect(Collectors.toList()) 使用了 Collectors 工具类提供的静态方法 toList(),将流中符合条件的元素收集到一个新的 List 中。

当使用Java中的Stream API时,collect 方法是一个非常有用的工具,用于将流中的元素收集到不同类型的结果容器中。以下是一些直观易懂的例子,展示了 collect 方法的不同用法和常见场景。

假设我们有一个整数列表,我们想要将其中的偶数收集到一个新的列表中:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class CollectExamples {

    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        List<Integer> evenNumbers = numbers.stream()
                                           .filter(n -> n % 2 == 0)
                                           .collect(Collectors.toList());

        System.out.println("Even numbers: " + evenNumbers); // 输出:Even numbers: [2, 4, 6, 8, 10]
    }
}

在这个例子中,.collect(Collectors.toList()) 将流中的偶数收集到一个新的列表中。

示例2:将元素收集为 Set

假设我们有一个字符串列表,我们想要将其中的元素收集到一个 HashSet 中:

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class CollectExamples {

    public static void main(String[] args) {
        List<String> words = Arrays.asList("apple", "banana", "orange", "apple", "grape");

        Set<String> uniqueWords = words.stream()
                                      .collect(Collectors.toSet());

        System.out.println("Unique words: " + uniqueWords); // 输出:Unique words: [orange, grape, banana, apple]
    }
}

在这个例子中,.collect(Collectors.toSet()) 将列表中的字符串元素收集到一个 HashSet 中,去除了重复的元素。

示例3:将元素收集为 Map

假设我们有一个对象列表,每个对象有一个唯一的 ID 和一个名称,我们希望将这些对象收集到一个 Map 中,以对象的 ID 作为键,对象本身作为值:

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

class Item {
    private int id;
    private String name;

    public Item(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}

public class CollectExamples {

    public static void main(String[] args) {
        List<Item> items = Arrays.asList(
            new Item(1, "Apple"),
            new Item(2, "Banana"),
            new Item(3, "Orange")
        );

        Map<Integer, Item> itemMap = items.stream()
                                         .collect(Collectors.toMap(Item::getId, item -> item));

        System.out.println("Item map: " + itemMap); 
        // 输出:Item map: {1=Item{id=1, name='Apple'}, 2=Item{id=2, name='Banana'}, 3=Item{id=3, name='Orange'}}
    }
}

在这个例子中,.collect(Collectors.toMap(Item::getId, item -> item)) 将对象列表转换为一个 Map,其中键为对象的 ID,值为对象本身。

示例4:自定义收集器

有时候,我们需要根据特定的需求创建自定义的收集器。例如,假设我们希望将列表中的字符串连接成一个以逗号分隔的字符串:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class CollectExamples {

    public static void main(String[] args) {
        List<String> letters = Arrays.asList("a", "b", "c", "d");

        String result = letters.stream()
                               .collect(Collectors.joining(", "));

        System.out.println("Concatenated string: " + result);
         // 输出:Concatenated string: a, b, c, d
    }
}

在这个例子中,.collect(Collectors.joining(", ")) 使用了 joining 方法来将流中的字符串连接成一个以逗号分隔的单个字符串。

这些例子展示了 collect 方法在日常编程中的实际应用,通过合适的收集器,可以轻松地将流中的元素转换为我们想要的数据结构或格式。

2,常见的收集器

Java 提供了丰富的预定义收集器,通过 Collectors 工具类可以方便地使用这些收集器。以下是一些常见的收集器示例:

将元素收集为 Set

Set<String> wordSet = words.stream()
                           .collect(Collectors.toSet());

System.out.println(wordSet);
 // 输出:[apple, banana, grape, orange, kiwi]

将元素收集为 Map
假设我们有一个对象列表,我们想要将列表中的对象按照某个属性收集到一个 Map 中,以属性值作为键,对象列表作为值。

class Person {
    private String name;
    private int age;

    // 省略构造方法和其他方法
}

List<Person> people = Arrays.asList(
    new Person("Alice", 30),
    new Person("Bob", 25),
    new Person("Charlie", 35)
);

Map<String, Person> nameToPersonMap = people.stream()
                                            .collect(Collectors.toMap(Person::getName, person -> person));

System.out.println(nameToPersonMap);

这段代码将根据 Person 对象的 name 属性将对象收集到一个 Map 中,键为 name,值为 Person 对象本身。

3,自定义收集器

除了使用预定义的收集器外,还可以通过实现 Collector 接口来创建自定义的收集器,以满足特定的需求。自定义收集器需要实现 Supplier, BiConsumer, BinaryOperator, Characteristics 接口方法。

例如,假设我们要将流中的字符串连接成一个单独的字符串:

List<String> letters = Arrays.asList("a", "b", "c", "d");

String result = letters.stream()
                       .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
                       .toString();

System.out.println(result); 
// 输出:abcd

在这个例子中,我们通过 StringBuilder::new 提供了一个初始的累加器,然后使用 StringBuilder::append 将每个元素连接到累加器上,最后通过 StringBuilder::toString 获得最终的字符串结果。

4,注意事项和使用场景

在使用 collect 方法时,需要考虑以下几点:

  1. 并行流: 当使用并行流时,应确保收集器具备无状态(stateless)或线程安全(thread-safe)的特性,以避免并发问题。
  2. 性能考量: 使用合适的收集器能够有效地提升性能,特别是在处理大数据量时。
  3. 可变性: 尽量避免在并行流中使用可变的累加器,以免产生不可预料的结果。

5,总结

Stream 的 collect 方法是一个强大且灵活的工具,用于将流中的元素收集到不同类型的结果容器中。通过预定义的收集器或自定义的方式,可以满足各种不同的需求,使得集合操作变得简洁和高效。在实际开发中,充分利用 collect 方法能够大大简化代码,提高代码的可读性和维护性,是 Java 8 引入的函数式编程风格的重要体现之一。

标签:java,Java,Stream,Collectors,收集器,util,collect,import
From: https://blog.csdn.net/anyifeiyi/article/details/139987795

相关文章

  • 由于安装多个jdk导致出现java以及javac版本不匹配问题
    之前由于下载了多个版本的jdk版本,导致了在运行java程序时出现了报错thisversionoftheJavaRuntimeonlyrecognizesclassfileversionsupto52.0报错信息大概为版本不匹配,查看了java以及javac的版本,发现一个是18,一个是20,所以查看解决方法,实现版本匹配一开始全在修改环......
  • Java中的泛型(很细)
    非常好,让我们深入探讨Java中的泛型这个重要主题。我将按照之前提供的框架,为您创作一篇全面而专业的技术博客文章。引言在Java编程世界中,泛型(Generics)是一个革命性的特性,它彻底改变了我们编写和组织代码的方式。自Java5引入以来,泛型已成为Java语言不可或缺的一部分,为开发者提供......
  • Java性能优化-书写高质量SQL的建议(如何做Mysql优化)
    场景Mysql中varchar类型数字排序不对踩坑记录:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/139955012为避免开发过程中针对mysql语句的写法再次踩坑,总结开发过程中常用书写高质量sql的一些建议。注:博客:https://blog.csdn.net/badao_liumang_qizhi实现查询......
  • 为什么JAVA库不用随机pivot方式的快速排序?
    在Java库中,不使用随机pivot方式的快速排序的原因主要有以下几点:性能问题:虽然随机pivot方式可以平均情况下提高快速排序的效率,但其在最坏情况下的表现并不理想。如果每次分区都产生极端不平衡的子数组(例如一个空数组和一个包含所有元素的数组),则会导致递归调用次数暴增,从而导致......
  • Java入门
    Java是什么?java是一门非常火热的计算机语言Java程序初体验下载和安装下载JDK通过官方网站获取:http://www.oracle.com注意:针对不同操作系统,下载对应的安装包1、在浏览器输入网址,点击【Products】-->【Java】2、点击【DownloadJava】进行下载3、本人使用的是17版本,......
  • 【热门】用 Java 构建高并发电子商务网站(深入研究+详解代码)
    书接上回,想必大家都对该类型的话题很感兴趣。是的,这个话题确实很热门,它也有很多优点。好的,接下来我们进行深入研究。本作品由老程个人著作,仅供参考以下是一个简单的JavaWeb应用示例,结合优化建议进行了逐步的优化和讲解:importjava.sql.Connection;importjava.sql.D......
  • 基于Java+SpringBoot+Vue的创新创业教育中心项目申报管理系统的设计与开发(源码+lw+部
    文章目录前言项目背景介绍技术栈后端框架SpringBoot前端框架Vue数据库MySQL(MyStructuredQueryLanguage)具体实现截图详细视频演示系统测试系统测试目的系统功能测试系统测试结论代码参考数据库参考源码获取前言......
  • JavaScript Promise.withResolvers API All In One
    JavaScriptPromise.withResolversAPIAllInOnePromise.withResolvers()https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolversdemoscancelablePromise/cancelFetchrequest(......
  • java学习笔记
    //单行注释/**/多行注释/** */文档注释byte:-128~127short:正负三万int:正负21亿long:如果表示的数超过int需要加L 123456789123456Lfloat:后面加fdouble:char:单引号引起来的单个字符增强for循环:for(intnum:arr)创建新的构造器,要保留空构造器,构造器也......
  • 基于 JAVA 的旅游网站设计与实现
    点击下载源码塞北村镇旅游网站设计摘要城市旅游产业的日新月异影响着村镇旅游产业的发展变化。网络、电子科技的迅猛前进同样牵动着旅游产业的快速成长。随着人们消费理念的不断发展变化,越来越多的人开始注意精神文明的追求,而不仅仅只是在意物质消费的提高。塞北村镇旅游......