Java Stream API 示例 (三)

11.toCollection:将流中的元素收集到给定的集合类型中。

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");  
Collection<String> collectedNames = names.stream()  
    .collect(Collectors.toCollection(ArrayList::new));  
System.out.println(collectedNames); // 输出: [Alice, Bob, Charlie]

12.groupingByConcurrent:类似于 groupingBy,但使用并发映射来存储结果,适用于并行流。

List<Person> people = ...;  
ConcurrentMap<String, List<Person>> genderMap = people.parallelStream()  
    .collect(Collectors.groupingByConcurrent(Person::getGender));

13.partitioningBy:根据给定的谓词对流中的元素进行分区,结果是一个包含两个列表的映射,一个列表包含满足谓词的元素,另一个包含不满足的元素。

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);  
Map<Boolean, List<Integer>> partitionedNumbers = numbers.stream()  
    .collect(Collectors.partitioningBy(n -> n % 2 == 0));  
System.out.println(partitionedNumbers); // 输出: {false=[1, 3, 5], true=[2, 4]}

14.mapping:对流中的元素应用一个给定的函数,并将结果收集到一个新的容器中。这通常与其他收集器一起使用。

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");  
List<Integer> nameLengths = names.stream()  
    .collect(Collectors.mapping(String::length, Collectors.toList()));  
System.out.println(nameLengths); // 输出: [5, 3, 7]

15.Collectors.of

import java.util.ArrayList;  
import java.util.Collection;  
import java.util.List;  
import java.util.function.BiConsumer;  
import java.util.function.Function;  
import java.util.function.Supplier;  
import java.util.stream.Collector;  
  
public class CustomCollectorExample {  
  
    public static void main(String[] args) {  
        List<Person> people = List.of(  
                new Person("Alice", 30),  
                new Person("Bob", 25),  
                new Person("Charlie", 35)  
        );  
  
        // 使用自定义收集器  
        List<Person> collectedPeople = people.stream()  
                .collect(customPersonListCollector());  
  
        System.out.println(collectedPeople);  
    }  
  
    // 自定义收集器  
    public static Collector<Person, ?, List<Person>> customPersonListCollector() {  
        return Collector.of(  
                // 供应商:创建一个空的列表作为初始容器  
                ArrayList::new,  
  
                // 累加器:将元素添加到列表中,并在添加前打印  
                (list, person) -> {  
                    System.out.println("Adding: " + person);  
                    list.add(person);  
                },  
  
                // 合并器(可选):并行流中合并两个列表  
                (left, right) -> {  
                    left.addAll(right);  
                    return left;  
                },  
  
                // 完成器(可选):转换最终容器为所需类型,这里直接返回列表  
                Function.identity()  
        );  
    }  
}

在这个示例中,customPersonListCollector 方法返回一个 Collector 实例,该实例配置了自定义的初始容器(使用 ArrayList::new 创建的列表)、累加器(将元素添加到列表并打印)、合并器(用于并行流中合并两个列表)和完成器(直接返回列表)。

运行这个程序时,你会看到每个 Person 对象在添加到列表中之前都被打印出来,最后打印出整个收集到的 Person 列表。

注意,虽然在这个简单的例子中我们没有利用并行流(即没有创建竞争条件),但在使用自定义收集器与并行流时,需要确保你的合并器是线程安全的。在上面的例子中,ArrayList 的 addAll 方法是线程安全的,因为它在内部进行了适当的同步(尽管在单个线程环境中这不是必需的)。然而,在更复杂的情况下,你可能需要更仔细地管理线程安全。

16.collectingAndThen

import java.util.Arrays;  
import java.util.List;  
import java.util.stream.Collectors;  
  
public class CollectingAndThenExample {  
  
    public static void main(String[] args) {  
        List<String> strings = Arrays.asList("apple", "banana", "cherry");  
  
        // 使用 collectingAndThen 来收集并转换结果  
        String concatenatedString = strings.stream()  
                .collect(Collectors.collectingAndThen(  
                        // 第一个参数是现有的收集器,这里我们收集到一个列表中  
                        Collectors.toList(),  
                        // 第二个参数是一个完成函数,它接受收集到的结果(这里是List<String>),并返回一个新的结果  
                        // 在这里,我们使用String.join来连接列表中的所有字符串  
                        list -> String.join(", ", list)  
                ));  
  
        System.out.println(concatenatedString); // 输出: apple, banana, cherry  
    }  
}

在这个示例中,collectingAndThen 方法接受两个参数:

  1. 第一个参数是一个 Collector,它定义了如何收集流中的元素。在这个例子中,我们使用 Collectors.toList() 来收集元素到一个 List 中。

  2. 第二个参数是一个函数,它接收收集器的结果(在这个例子中是 List<String>),并返回一个新的结果。在这个例子中,我们传递了一个 lambda 表达式,它使用 String.join 方法将列表中的所有字符串连接成一个单独的字符串,每个字符串之间用逗号加空格分隔。

collectingAndThen 方法非常适合于在收集过程之后对结果进行简单转换的场景,而无需创建全新的收集器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值