JAVA8:Collector集合方法
文章目录
首先创建一个实体类
public class Student {
private String name;
private Integer age;
private Integer score;
}
List<Student> studentList = new ArrayList<>(Arrays.asList(
new Student("小白", 20, 90),
new Student("小黑", 21, 95),
new Student("小红", 22, 80),
new Student("小明", 22, 82)));
一、toList()
- 将流中所有元素收集到一个 List 中
List<String> studentNameList = studentList.stream().map(Student::getName).collect(toList());
二、toMap()、toConcurrentMap()
- 将流中所有元素收集到一个 Map 中
该方法最多
有四个参数:
1、Function<? super T, ? extends K> keyMapper
用于生成key
2、Function<? super T, ? extends U> valueMapper
用于生成value
3、BinaryOperator mergeFunction
合并函数,BinaryOperator
继承自Function传入两个参数返回一个参数,常用作key相同的合并
4、Supplier mapSupplier
供给性函数,创建具体的对象必须是Map类型的实现,如HashMap::new。
//toMap 两个参数
Map<String, Integer> toMap1 = studentList.stream().collect(toMap(Student::getName, Student::getAge));
//toMap 三个参数方法,若出现key相同的,则对value进行操作,这儿做的是合并操作
Map<Integer, String> toMap2 = studentList.stream().collect(toMap(Student::getAge, Student::getName, (x, y) -> x + y));
//toMap 四个参数,供给性函数,创建对象 等价于 new ConcurrentHashMap
Map<Integer, String> toMap3 = studentList.stream().collect(toMap(Student::getAge, Student::getName, (x, y) -> y, ConcurrentHashMap::new));
三、toSet()
- 将流中所有元素收集到一个 Set 中,并去除重复项
//toSet() 转换成Set 所以重复的数据会去重
Set<String> toSet = studentList.stream().map(Student::getName).collect(Collectors.toSet());
四、groupingBy()
-
根据流中元素的某个属性值对流中元素进行分组,并将该属性值作为结果 Map 的 key
该方法有三个参数:
1、Function<? super T, ? extends K> classifier
流中依据的分组的key
2、Supplier mapFactory
最后返回的数据结构,必须是个Map
3、Collector<? super T, A, D> downstream
再次一个Collector,可以做一些其他的操作,若counting或根据多个字段分组
//groupingBy() 一个参数,选择哪个字段进行分组 Map<Integer, List<Student>> groupingBy1 = studentList.stream().collect(Collectors.groupingBy(Student::getAge)); //groupingBy() 两个参数,分组字段 和 再次传入Collector,可以做一些操作如 计算每个组的个数 Map<Integer, Long> groupingBy2 = studentList.stream().collect(Collectors.groupingBy(Student::getAge, Collectors.counting())); //groupingBy() 三个参数 分组字段 和 map数据类型,额外的Collectors操作 Map<Integer, Long> groupingBy3 = studentList.stream().collect(Collectors.groupingBy(Student::getAge, HashMap::new, Collectors.counting()));
五、counting()
- 计算流中的个数
Long counting = studentList.stream().collect(Collectors.counting());
六、joining()
- 连接流中每个元素,最后生成字符串
该方法有三个参数:
1、CharSequence delimiter
字符串之间的分割符,如 , 分割 结果就是 xxx,xxx,xxx
2、CharSequence prefix
拼接的前缀
3、CharSequence suffix
拼接的后缀
//全部拼接起来
String joining1 = studentList.stream().map(Student::getName).collect(Collectors.joining());
//joining() 连接 只能是String类型以及派生类 一个参数:在数据之间拼接 , 如 xxx,xxx,xxx
String joining2 = studentList.stream().map(Student::getName).collect(Collectors.joining(","));
//joining() 连接 在数据的开头以及结束拼接,数据之间用,拼接
//开始{小白,小黑,小红,小明}结束
String joining3 = studentList.stream().map(Student::getName).collect(Collectors.joining(",", "开始{", "}结束"));
七、summarizing+XXX
- 获取流最大值、最小值、求和、元素数量(size)
有一下几种方法:
1、summarizingInt
2、summarizingLong
3、summarizingDouble
//IntSummaryStatistics{count=4, sum=85, min=20, average=21.250000, max=22}
IntSummaryStatistics summarizingInt = studentList.stream().collect(Collectors.summarizingInt(Student::getAge));
八、averaging+XXX
- 计算流中的平均值
有以下几种方法:
1、averagingInt()
2、averagingLong()
3、averagingDouble()
Double averagingInt = studentList.stream().collect(Collectors.averagingInt(Student::getAge));
九、summing+XXX
- 计算流中元素属性字段的总和
有以下几种方法:
1、summingDouble()
2、summingInt()
3、summingLong()
Integer summingAge = studentList.stream().collect(Collectors.summingInt(Student::getAge));
十、reducing()
- 将流中的元素归约为单个值
有三个参数:
1、U identity
初始值
2、Function<? super T, ? extends U> mapper
中间执行函数,传入一个值,返回一个值,对所有的元素执行函数
3、BinaryOperator op
操作函数,传入两个值,返回一个值
//reducing 一个参数:求和
Integer reducing1 = studentList.stream().map(Student::getAge).collect(Collectors.reducing(Integer::sum)).orElse(1);
//reducing 两个参数,初始值、具体操作,这儿是拼接到了一起
String reducing2 = studentList.stream().map(Student::getName).collect(Collectors.reducing("哈哈哈", (x, y) -> x + y));
//reducing 三个参数:初始值、中间函数这儿全部扩大一倍、累加
Integer reducing3 = studentList.stream().map(Student::getAge).collect(Collectors.reducing(0, h -> h * 2, Integer::sum));
十一、maxBy()、minBy()
- 求出最大值或最小值,若有多个最大值(最小值),只会返回其中之一
Student maxBy = studentList.stream().collect(Collectors.maxBy(Comparator.comparing(Student::getAge))).orElse(null);
十二、partitioningBy()
- 根据流中每个元素应用谓词的结果来对元素进行分组 (只会分为 true 和 false 两组)
有两个参数:
1、Predicate<? super T> predicate
断言函数,返回boolean,根据该函数进行分组
2、Collector<? super T, A, D> downstream
分组后得额外操作
//partitioningBy 断言分组,如age<22的为一组,>=22的为一组
Map<Boolean, List<Student>> partitioningBy1 = studentList.stream().collect(Collectors.partitioningBy(x -> x.getAge() < 22));
//partitioningBy 后面可再次跟一个Collectors操作,如求断言分组之后的平均值
Map<Boolean, Double> partitioningBy2 = studentList.stream().collect(Collectors.partitioningBy(x -> x.getAge() < 22, Collectors.averagingInt(Student::getAge)));
十三、toCollection()
- 将流中所有元素收集到容器
一个参数:
1、Supplier collectionFactory
供给函数,只能是Collection的子类,如ArrayList,HashSet等
studentList.stream().collect(Collectors.toCollection(HashSet::new));
十四、collectingAndThen()
- 包裹一个收集器,对其结果应用转换函数
- 该方法有两个参数
- Collector<T,A,R> downstream
- 收集器
- Function<R,RR> finisher
- 转换函数
- Collector<T,A,R> downstream
Integer listSize = studentList.stream().collect(collectingAndThen(toList(), List::size));
完整代码
public class CollectorsTest {
public static void main(String[] args) {
List<Student> studentList = new ArrayList<>(Arrays.asList(
new Student("小白", 20, 90),
new Student("小黑", 21, 95),
new Student("小红", 22, 80),
new Student("小明", 22, 82)));
//toList() 默认是arraylist
List<Integer> toList = studentList.stream().map(Student::getAge).collect(toList());
//toMap 传入Function
Map<String, Integer> toMap1 = studentList.stream().collect(toMap(Student::getName, Student::getAge));
//toMap 第三个参数,若出现key相同的,则对value进行操作,这儿做的是合并操作
Map<Integer, String> toMap2 = studentList.stream().collect(toMap(Student::getAge, Student::getName, (x, y) -> x + y));
//toMap 第四个参数,供给性函数,创建对象 等价于 new ConcurrentHashMap
Map<Integer, String> toMap3 = studentList.stream().collect(toMap(Student::getAge, Student::getName, (x, y) -> x + y, ConcurrentHashMap::new));
//groupingBy() 一个参数选择哪个字段进行分组
Map<Integer, List<Student>> groupingBy1 = studentList.stream().collect(Collectors.groupingBy(Student::getAge));
//groupingBy() 两个参数,分组字段 和 再次传入Collector,可以做一些操作如 计算每个组的个数
Map<Integer, Long> groupingBy2 = studentList.stream().collect(Collectors.groupingBy(Student::getAge, Collectors.counting()));
//groupingBy() 三个参数 分组字段 和 map数据类型,额外的Collectors操作
Map<Integer, Long> groupingBy3 = studentList.stream().collect(Collectors.groupingBy(Student::getAge, HashMap::new, Collectors.counting()));
// 计算流中的数量个数
Long counting = studentList.stream().collect(Collectors.counting());
//joining() 连接 无参数 只能是String类型以及派生类
String joining1 = studentList.stream().map(Student::getName).collect(Collectors.joining());
//joining() 连接 只能是String类型以及派生类 一个参数:在数据之间拼接 , 如 xxx,xxx,xxx
String joining2 = studentList.stream().map(Student::getName).collect(Collectors.joining(","));
//joining() 连接 在数据的开头以及结束拼接,数据之间用,拼接
String joining3 = studentList.stream().map(Student::getName).collect(Collectors.joining(",", "开始{", "}结束"));
//toSet() 转换成Set 所以重复的数据会去重
Set<String> toSet = studentList.stream().map(Student::getName).collect(Collectors.toSet());
//summarizingInt、此外还有summarizingLong、summarizingDouble等类型 最大值,最小值,求和,平均值
IntSummaryStatistics summarizingInt = studentList.stream().collect(Collectors.summarizingInt(Student::getAge));
//averagingInt 求平均值,此外还有averagingDouble、averagingInt、averagingLong
Double averagingInt = studentList.stream().collect(Collectors.averagingInt(Student::getAge));
//summingAge 求和,此外还有summingDouble、summingLong
Integer summingAge = studentList.stream().collect(Collectors.summingInt(Student::getAge));
//reducing 合并、归约,就是将多个值合并成一个值,合并规则自己编写
Integer reducing1 = studentList.stream().map(Student::getAge).collect(Collectors.reducing(Integer::sum)).orElse(1);
//reducing 同上,只不过加上初始值
String reducing2 = studentList.stream().map(Student::getName).collect(Collectors.reducing("哈哈哈", (x, y) -> x + y));
//reducing 同上,初始值0,h扩大一倍,最后累加到一起
Integer reducing3 = studentList.stream().map(Student::getAge).collect(Collectors.reducing(0, h -> h * 2, (x, y) -> x + y));
//maxBy、minBy 求出最大值或最小值,若有多个最大值(最小值),只会返回其中之一
Student maxBy = studentList.stream().collect(Collectors.maxBy(Comparator.comparing(Student::getAge))).orElse(null);
//partitioningBy 断言分组,如age<22的为一组,>=22的为一组
Map<Boolean, List<Student>> partitioningBy1 = studentList.stream().collect(Collectors.partitioningBy(x -> x.getAge() < 22));
//partitioningBy 后面可再次跟一个Collectors操作,如求断言分组之后的平均值
Map<Boolean, Double> partitioningBy2 = studentList.stream().collect(Collectors.partitioningBy(x -> x.getAge() < 22, Collectors.averagingInt(Student::getAge)));
//collectingAndThen
Boolean collectingAndThen = studentList.stream().collect(Collectors.collectingAndThen(toList(), List::isEmpty));
}
}