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

打印 上一主题 下一主题

主题 546|帖子 546|积分 1638

collect 详解

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

collect 方法是 Stream API 中的一个终端操纵,它担当一个 Collector 参数,用于将流中的元素累积成一个效果。Collector 接口界说了如何收集元素的方法,通常使用 Collectors 工具类来提供各种预界说的收集器。
基本语法:
  1. <R, A> R collect(Collector<? super T, A, R> collector)
复制代码
  1. 其中:
  2. T 是流中元素的类型。
  3. A 是累加器的类型,用于在收集过程中累积部分结果。
  4. R 是收集操作最终要返回的类型。
复制代码
示例1:将元素收集为列表

假设我们有一个字符串列表,我们希望将此中长度大于等于5的字符串收集到一个新的列表中。
  1. List<String> words = Arrays.asList("apple", "banana", "grape", "orange", "kiwi");
  2. List<String> longWords = words.stream()
  3.                              .filter(word -> word.length() >= 5)
  4.                              .collect(Collectors.toList());
  5. System.out.println(longWords); // 输出:[banana, orange]
复制代码
在这个示例中,collect(Collectors.toList()) 使用了 Collectors 工具类提供的静态方法 toList(),将流中符合条件的元素收集到一个新的 List 中。
当使用Java中的Stream API时,collect 方法是一个非常有效的工具,用于将流中的元素收集到差别范例的效果容器中。以下是一些直观易懂的例子,展示了 collect 方法的差别用法和常见场景。
假设我们有一个整数列表,我们想要将此中的偶数收集到一个新的列表中:
  1. import java.util.Arrays;
  2. import java.util.List;
  3. import java.util.stream.Collectors;
  4. public class CollectExamples {
  5.     public static void main(String[] args) {
  6.         List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
  7.         List<Integer> evenNumbers = numbers.stream()
  8.                                            .filter(n -> n % 2 == 0)
  9.                                            .collect(Collectors.toList());
  10.         System.out.println("Even numbers: " + evenNumbers); // 输出:Even numbers: [2, 4, 6, 8, 10]
  11.     }
  12. }
复制代码
在这个例子中,.collect(Collectors.toList()) 将流中的偶数收集到一个新的列表中。
示例2:将元素收集为 Set

假设我们有一个字符串列表,我们想要将此中的元素收集到一个 HashSet 中:
  1. import java.util.Arrays;
  2. import java.util.HashSet;
  3. import java.util.List;
  4. import java.util.Set;
  5. import java.util.stream.Collectors;
  6. public class CollectExamples {
  7.     public static void main(String[] args) {
  8.         List<String> words = Arrays.asList("apple", "banana", "orange", "apple", "grape");
  9.         Set<String> uniqueWords = words.stream()
  10.                                       .collect(Collectors.toSet());
  11.         System.out.println("Unique words: " + uniqueWords); // 输出:Unique words: [orange, grape, banana, apple]
  12.     }
  13. }
复制代码
在这个例子中,.collect(Collectors.toSet()) 将列表中的字符串元素收集到一个 HashSet 中,去除了重复的元素。
示例3:将元素收集为 Map

假设我们有一个对象列表,每个对象有一个唯一的 ID 和一个名称,我们希望将这些对象收集到一个 Map 中,以对象的 ID 作为键,对象本身作为值:
  1. import java.util.Arrays;
  2. import java.util.List;
  3. import java.util.Map;
  4. import java.util.stream.Collectors;
  5. class Item {
  6.     private int id;
  7.     private String name;
  8.     public Item(int id, String name) {
  9.         this.id = id;
  10.         this.name = name;
  11.     }
  12.     public int getId() {
  13.         return id;
  14.     }
  15.     public String getName() {
  16.         return name;
  17.     }
  18. }
  19. public class CollectExamples {
  20.     public static void main(String[] args) {
  21.         List<Item> items = Arrays.asList(
  22.             new Item(1, "Apple"),
  23.             new Item(2, "Banana"),
  24.             new Item(3, "Orange")
  25.         );
  26.         Map<Integer, Item> itemMap = items.stream()
  27.                                          .collect(Collectors.toMap(Item::getId, item -> item));
  28.         System.out.println("Item map: " + itemMap);
  29.         // 输出:Item map: {1=Item{id=1, name='Apple'}, 2=Item{id=2, name='Banana'}, 3=Item{id=3, name='Orange'}}
  30.     }
  31. }
复制代码
在这个例子中,.collect(Collectors.toMap(Item::getId, item -> item)) 将对象列表转换为一个 Map,此中键为对象的 ID,值为对象本身。
示例4:自界说收集器

偶尔候,我们需要根据特定的需求创建自界说的收集器。例如,假设我们希望将列表中的字符串连接成一个以逗号分隔的字符串:
  1. import java.util.Arrays;
  2. import java.util.List;
  3. import java.util.stream.Collectors;
  4. public class CollectExamples {
  5.     public static void main(String[] args) {
  6.         List<String> letters = Arrays.asList("a", "b", "c", "d");
  7.         String result = letters.stream()
  8.                                .collect(Collectors.joining(", "));
  9.         System.out.println("Concatenated string: " + result);
  10.          // 输出:Concatenated string: a, b, c, d
  11.     }
  12. }
复制代码
在这个例子中,.collect(Collectors.joining(", ")) 使用了 joining 方法来将流中的字符串连接成一个以逗号分隔的单个字符串。
这些例子展示了 collect 方法在日常编程中的实际应用,通过符合的收集器,可以轻松地将流中的元素转换为我们想要的数据结构或格式。
2,常见的收集器

Java 提供了丰富的预界说收集器,通过 Collectors 工具类可以方便地使用这些收集器。以下是一些常见的收集器示例:
将元素收集为 Set
  1. Set<String> wordSet = words.stream()
  2.                            .collect(Collectors.toSet());
  3. System.out.println(wordSet);
  4. // 输出:[apple, banana, grape, orange, kiwi]
复制代码
将元素收集为 Map
假设我们有一个对象列表,我们想要将列表中的对象按照某个属性收集到一个 Map 中,以属性值作为键,对象列表作为值。
  1. class Person {
  2.     private String name;
  3.     private int age;
  4.     // 省略构造方法和其他方法
  5. }
  6. List<Person> people = Arrays.asList(
  7.     new Person("Alice", 30),
  8.     new Person("Bob", 25),
  9.     new Person("Charlie", 35)
  10. );
  11. Map<String, Person> nameToPersonMap = people.stream()
  12.                                             .collect(Collectors.toMap(Person::getName, person -> person));
  13. System.out.println(nameToPersonMap);
复制代码
这段代码将根据 Person 对象的 name 属性将对象收集到一个 Map 中,键为 name,值为 Person 对象本身。
3,自界说收集器

除了使用预界说的收集器外,还可以通过实现 Collector 接口来创建自界说的收集器,以满意特定的需求。自界说收集器需要实现 Supplier, BiConsumer, BinaryOperator, Characteristics 接口方法。
例如,假设我们要将流中的字符串连接成一个单独的字符串:
  1. List<String> letters = Arrays.asList("a", "b", "c", "d");
  2. String result = letters.stream()
  3.                        .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
  4.                        .toString();
  5. System.out.println(result);
  6. // 输出:abcd
复制代码
在这个例子中,我们通过 StringBuilder::new 提供了一个初始的累加器,然后使用 StringBuilder::append 将每个元素连接到累加器上,最后通过 StringBuilder::toString 获得最终的字符串效果。
4,留意事项和使用场景

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

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

Stream 的 collect 方法是一个强大且灵活的工具,用于将流中的元素收集到差别范例的效果容器中。通过预界说的收集器或自界说的方式,可以满意各种差别的需求,使得聚集操纵变得简洁和高效。在实际开发中,充分利用 collect 方法可以或许大大简化代码,提高代码的可读性和维护性,是 Java 8 引入的函数式编程风格的紧张体现之一。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

欢乐狗

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表