Collectors的使用
在java stream中的collect方法中需要使用Collectors作为参数,这一个非常强大的功能。目录简介一、数据转换二、聚合三、分组四、collectingAndThen()
简介
在java stream中的collect方法中需要使用Collectors作为参数,这一个非常强大的功能。如:
一、数据转换
我们可以将对应的数据使用流通过collect转换为我们需要的数据集合如:
toCollection(Supplier<Collection<T>> collectionSupplier)
: 将流中的元素收集到给定的集合中。toList()
: 将流中的元素收集到List
中。toSet()
: 将流中的元素收集到Set
中,自动去重。toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends V> valueMapper)
: 将流中的元素收集到Map
中,需要提供键和值的映射函数,第一个参数是keyMapper,第二个参数是valueMapper。
// 示例数据:一个包含字符串的列表
List<String> words = Arrays.asList("apple", "banana", "apple", "orange", "banana", "banana");
// 示例数据:一个包含Person对象的列表
List<Person> people = Arrays.asList(
new Person("Alice", 30, "New York"),
new Person("Bob", 25, "Los Angeles"),
new Person("Charlie", 35, "Chicago"),
new Person("David", 30, "New York"),
new Person("Emily", 28, "Los Angeles")
);
1、toCollection将收集到的数据给到指定的集合是通过参数进行设置,如:
LinkedList<String> wordsLinkedList = words.stream()
.collect(Collectors.toCollection(LinkedList::new));
上面的例子,我们转换成了LinkedList。
2、toList()
将stream转换为list。这里转换的list是ArrayList,如:
List<String> result = list.stream().collect(Collectors.toList());
3、 toSet()
将Stream转换成为set。这里转换的是HashSet,注意set中是没有重复的元素,也就是说它会自动的去重,如:
Set<String> wordsSet = words.stream().collect(Collectors.toSet());
4、toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends V> valueMapper),
将流中的元素收集到 Map
中,如:
Map<String, Integer> map = list.stream()
.collect(Collectors.toMap(String::toString, String::length));
如果stream中有重复的值,则转换会报IllegalStateException异常 ,解决如下:
// 提供一个合并函数来处理键冲突
// 在这个例子中,如果键冲突,我们选择保留较大的年龄值
Map<String, Integer> nameToAgeWithMerge = people.stream()
.collect(Collectors.toMap(
Person::getName, // 键提取函数
Person::getAge, // 值提取函数
(existingValue, newValue) -> Math.max(existingValue, newValue) // 合并函数
));
// 提供一个合并函数,选择保留较新的值
Map<String, Integer> nameToAgeWithMergeNew = people.stream()
.collect(Collectors.toMap(
Person::getName, // 键提取函数
Person::getAge, // 值提取函数
(existingValue, newValue) -> newValue // 合并函数
));
// 提供一个合并函数,选择保留旧的值
Map<String, Integer> nameToAgeWithMergeOld = people.stream()
.collect(Collectors.toMap(
Person::getName, // 键提取函数
Person::getAge, // 值提取函数
(existingValue, newValue) -> existingValue // 合并函数
));
二、聚合
聚合操作通常使用 Collectors
提供的各种聚合方法,如
- summingInt():计算总和
- averagingInt():计算平均值
- joining():字符串拼接
- counting():统计元素格个数
1、summingInt()
主要用来计算数据的总和,如:
int sum = numbers.stream()
.collect(Collectors.summingInt(Integer::intValue));
2、averagingInt()对stream中的元素做平均,如:
double average = numbers.stream()
.collect(Collectors.averagingInt(Integer::intValue));
3、joining()用来连接stream中的元素,其中它会有三种使用方式,如 :
(1)无参数
List<String> words = Arrays.asList("apple", "banana", "cherry");
// 无参数的 joining()
String joined = words.stream()
.collect(Collectors.joining());
System.out.println("Joined string: " + joined); // 输出:applebananacherry
(2 )一个参数,以“,”为每个元素间隔进行拼接
// 带一个参数的 joining()
String joinedWithDelimiter = words.stream()
.collect(Collectors.joining(", "));
System.out.println("Joined string with delimiter: " + joinedWithDelimiter); // 输出:apple, banana, cherry
(3)三个参数,第1个参数以“,”为每个元素间隔进行拼接,第2,3个分别为前缀后缀
/ 带三个参数的 joining()
String joinedWithDelimiterPrefixSuffix = words.stream()
.collect(Collectors.joining(", ", "[", "]"));
System.out.println("Joined string with delimiter, prefix, and suffix: " + joinedWithDelimiterPrefixSuffix); // 输出:[apple, banana, cherry]
4、counting()主要用来统计stream中元素的个数:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 统计流中元素的总数
long count = numbers.stream()
.collect(Collectors.counting());
System.out.println("Total count: " + count);
三、分组
分组操作通常使用 Collectors.groupingBy()
方法,它允许你根据某个条件将流中的元素分组为键值对结构。
import java.util.*;
import java.util.stream.*;
import java.util.stream.Collectors;
public class GroupingExample {
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("Alice", 30, "New York"),
new Person("Bob", 25, "Los Angeles"),
new Person("Charlie", 35, "New York"),
new Person("David", 30, "Chicago"),
new Person("Emily", 28, "Los Angeles")
);
// 按城市分组
Map<String, List<Person>> peopleByCity = people.stream()
.collect(Collectors.groupingBy(Person::getCity));
System.out.println("People grouped by City: " + peopleByCity);
// 按年龄分组并计算每个组的人数
Map<Integer, Long> peopleCountByAge = people.stream()
.collect(Collectors.groupingBy(Person::getAge, Collectors.counting()));
System.out.println("People count by Age: " + peopleCountByAge);
// 按城市和年龄分组
Map<String, Map<Integer, List<Person>>> peopleByCityAndAge = people.stream()
.collect(Collectors.groupingBy(Person::getCity,
Collectors.groupingBy(Person::getAge)));
System.out.println("People grouped by City and Age:");
peopleByCityAndAge.forEach((city, ageMap) -> {
System.out.println("City: " + city);
ageMap.forEach((age, peopleList) -> {
System.out.println(" Age: " + age + " - " + peopleList);
});
});
}
}
Collectors.partitioningBy()
是一个特别的groupingBy,PartitioningBy返回一个Map,这个Map是以boolean值为key,从而将stream分成两部分,一部分是匹配PartitioningBy条件的,一部分是不满足条件的,如:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 根据是否为偶数进行分区
Map<Boolean, List<Integer>> partitionedNumbers = numbers.stream()
.collect(Collectors.partitioningBy(n -> n % 2 == 0));
System.out.println("Partitioned Numbers: " + partitionedNumbers);
四、collectingAndThen()
collectingAndThen它允许你对流中的元素进行收集操作后,再对收集的结果进行进一步的处理,如:将流中的元素收集到一个集合后进行排序
import java.util.*;
import java.util.stream.*;
import java.util.stream.Collectors;
public class CollectingAndThenExample1 {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5);
// 将流中的元素收集到一个列表后进行排序
List<Integer> sortedNumbers = numbers.stream()
.collect(Collectors.collectingAndThen(Collectors.toList(), List::sort));
System.out.println("Sorted Numbers: " + sortedNumbers);
}
}
如:将流中的元素收集到一个集合后进行去重
import java.util.*;
import java.util.stream.*;
import java.util.stream.Collectors;
public class CollectingAndThenExample2 {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5);
// 将流中的元素收集到一个集合后进行去重
Set<Integer> uniqueNumbers = numbers.stream()
.collect(Collectors.collectingAndThen(Collectors.toSet(), Set::stream)
.mapToInt(Integer::intValue)
.boxed()
.collect(Collectors.toSet()));
System.out.println("Unique Numbers: " + uniqueNumbers);
}
}
如:将流中的对象收集到一个集合后进行过滤
import java.util.*;
import java.util.stream.*;
import java.util.stream.Collectors;
public class CollectingAndThenExample3 {
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("Alice", 30),
new Person("Bob", 25),
new Person("Charlie", 35),
new Person("David", 30),
new Person("Emily", 28)
);
// 将流中的对象收集到一个列表后,过滤出年龄大于30的人
List<Person> filteredPeople = people.stream()
.collect(Collectors.collectingAndThen(Collectors.toList(), list -> {
return list.stream()
.filter(p -> p.getAge() > 30)
.collect(Collectors.toList());
}));
System.out.println("Filtered People: " + filteredPeople);
}
}

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。
更多推荐
所有评论(0)