Skip to content

输出为list

要将Stream的输出转换为List,可以使用collect()方法和Collectors.toList()收集器。collect()方法是一个终端操作,用于将流中的元素累积到一个集合中。

以下是一个示例,演示如何将Stream的输出转换为List:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> evenNumbers = numbers.stream().filter(n -> n % 2 == 0);
List<Integer> evenList = evenNumbers.collect(Collectors.toList());

在这个示例中,我们首先创建了一个包含整数的列表。然后,我们使用stream()方法创建一个Stream,并使用filter()方法过滤出偶数。接下来,我们使用collect()方法和Collectors.toList()收集器将过滤后的Stream转换为一个新的List。

输出为数组

要将Stream的输出转换为数组,可以使用toArray()方法。toArray()方法是一个终端操作,用于将流中的元素收集到一个数组中。

以下是一个示例,演示如何将Stream的输出转换为数组:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> evenNumbers = numbers.stream().filter(n -> n % 2 == 0);
Integer[] evenArray = evenNumbers.toArray(Integer[]::new);

在这个示例中,我们首先创建了一个包含整数的列表。然后,我们使用stream()方法创建一个Stream,并使用filter()方法过滤出偶数。接下来,我们使用toArray()方法将过滤后的Stream转换为一个新的Integer数组。注意,我们传递了一个方法引用Integer[]::new作为参数,用于创建新数组。

数组为Map

要将Stream的输出转换为Map,您可以使用Collectors.toMap()方法。toMap()方法接受两个参数,一个表示键的函数和一个表示值的函数。它将这些函数应用于Stream中的元素,并将结果收集到一个Map中。 以下是一个示例:

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
Map<String, Integer> nameLengths = names.stream()
        .collect(Collectors.toMap(name -> name, name -> name.length()));

在这个示例中,我们首先创建了一个包含字符串的列表。然后,我们使用stream()方法创建一个Stream,并使用collect()方法和Collectors.toMap()将每个字符串映射到其长度。结果是一个包含每个字符串及其长度的Map。 如果Stream中存在重复的键,toMap()方法将抛出一个IllegalStateException。

为了解决这个问题,您可以使用toMap()方法的重载版本,它接受一个合并函数作为第三个参数,用于解决键冲突。

以下是一个具有重复键的示例:

List<String> names = Arrays.asList("Alice", "Bob", "Alice");
Map<String, Integer> nameLengths = names.stream()
        .collect(Collectors.toMap(name -> name, name -> name.length(), (existingValue, newValue) -> existingValue));

在这个示例中,我们将重复的键解决为保留已存在的值。

分组输出

要将Stream的输出按照某个属性进行分组,您可以使用Collectors.groupingBy()方法。groupingBy()方法接受一个表示分组条件的函数,并将Stream中的元素按照该条件进行分组。

以下是一个示例:

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

Map<String, List<Person>> peopleByNames = people.stream()
        .collect(Collectors.groupingBy(Person::getName));

在这个示例中,我们首先创建了一个包含Person对象的列表。Person类有两个属性,name和age。然后,我们使用stream()方法创建一个Stream,并使用collect()方法和Collectors.groupingBy()按照name属性将Person对象分组。结果是一个Map,其中键是name属性的值,而值是具有相同name属性的Person对象的列表。

如果您想进一步对分组结果进行处理,例如对每个分组进行计数或求和,您可以使用Collectors.groupingBy()方法的重载版本,它接受一个下游收集器作为第二个参数。以下是一个示例,对分组结果进行计数:

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

Map<String, Long> countByNames = people.stream()
        .collect(Collectors.groupingBy(Person::getName, Collectors.counting()));

在这个示例中,我们使用Collectors.counting()作为下游收集器,对每个分组进行计数。结果是一个Map,其中键是name属性的值,而值是该分组中的元素数量。