collect
分组和分区
public class StreamTest04 {
public static void main(String[] args) {
List<String> list1 = Arrays.asList("hi", "hello", "你好");
List<String> list2 = Arrays.asList("张三", "李四", "王五");
List<String> collect = list1.stream().flatMap(l1 -> list2.stream().map(l2 -> l1 + ":" + l2)).collect(Collectors.toList());
collect.stream().forEach(System.out::println);
// hi:张三
// hi:李四
// hi:王五
// hello:张三
// hello:李四
// hello:王五
// 你好:张三
// 你好:李四
// 你好:王五
// ------------1.按年龄分组,并返回每组总数----------------
List<User> users=Arrays.asList(
new User("tom",11,87),
new User("jim",11,88),
new User("join",12,90),
new User("tax",13,78)
);
Map<Integer, Long> fzOne = users.stream().collect(Collectors.groupingBy(e -> e.getAge(), Collectors.counting()));
System.out.println(fzOne);
//{11=2, 12=1, 13=1}
// ------------2.按年龄分组,并返回每组的分数平均值----------------
Map<Integer, Double> fzTwo= users.stream().collect(Collectors.groupingBy(e -> e.getAge(), Collectors.averagingDouble(User::getScore)));
System.out.println(fzTwo);
//{11=87.5, 12=90.0, 13=78.0}
}
}
分区: 分区(partitioningBy)可以看成是一种特殊的分组 ,分区只能分为两组 ,即成立某种条件的和不成立某种条件的
// ------------按照成绩是否大于90分组----------------
List<User> userList =Arrays.asList(
new User("tom",11,87),
new User("jim",11,98),
new User("join",12,90),
new User("tax",13,78)
);
Map<Boolean, List<User>> c1 = userList.stream().collect(Collectors.partitioningBy(e -> e.getScore() >= 90));
System.out.println(c1);
//{
// false=[User(name=tom, age=11, score=87), User(name=tax, age=13, score=78)],
// true =[User(name=jim, age=11, score=98), User(name=join, age=12, score=90)]
// }
Map<Boolean, Long> c2 = userList.stream().collect(Collectors.partitioningBy(e -> e.getScore() >= 90, Collectors.counting()));
System.out.println(c2);
//{false=2, true=2}
收集器:collect
Collector是专门用来作为Stream的collect方法的参数的。 而Collectors是作为生产具体Collector的工具类。
Collector主要包含五个参数,它的行为也是由这五个参数来定义的,如下所示:
public interface Collector<T, A, R> {
// supplier参数用于生成结果容器,容器类型为A
Supplier<A> supplier();
// accumulator用于消费元素,也就是归纳元素,这里的T就是元素,它会将流中的元素一个一个与结果容器A发生操作
BiConsumer<A, T> accumulator();
// combiner用于两个两个合并并行执行的线程的执行结果,将其合并为一个最终结果A
BinaryOperator<A> combiner();
// finisher用于将之前整合完的结果R转换成为A
Function<A, R> finisher();
// characteristics表示当前Collector的特征值,这是个不可变Set
Set<Characteristics> characteristics();
}
Collectors是一个工具类,是JDK预实现Collector的工具类,它内部提供了多种Collector,如:
toCollection
将流中的元素全部放置到一个集合中返回,这里使用Collection,泛指多种集合。
toSet
将流中的元素放置到一个列表集合中去。这个列表默认为ArrayList。
joining
joining的目的是将流中的元素全部以字符序列的方式连接到一起,可以指定连接符,甚至是结果的前后缀。
public class CollectorsTest {
public static void joiningTest(List<String> list){
// 无参方法
String s = list.stream().collect(Collectors.joining());
System.out.println(s);
// 指定连接符
String ss = list.stream().collect(Collectors.joining("-"));
System.out.println(ss);
// 指定连接符和前后缀
String sss = list.stream().collect(Collectors.joining("-","S","E"));
System.out.println(sss);
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
joiningTest(list);
}
}
console:
1234567891101212121121asdaa3e3e3e2321eew
123-456-789-1101-212121121-asdaa-3e3e3e-2321eew
S123-456-789-1101-212121121-asdaa-3e3e3e-2321eewE
mapping
这个映射是首先对流中的每个元素进行映射,即类型转换,然后再将新元素以给定的Collector进行归纳。
public class CollectorsTest {
public static void mapingTest(List<String> list){
List<Integer> ll = list.stream().limit(5).collect(Collectors.mapping(Integer::valueOf,Collectors.toList()));
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789","1101","111","asdaa","3e3e3e","2321eew");
mapingTest(list);
}
}
collectingAndThen
该方法是在归纳动作结束之后,对归纳的结果进行再处理。
public class CollectorsTest {
public static void collectingAndThenTest(List<String> list){
int length = list.stream().collect(Collectors.collectingAndThen(Collectors.toList(),e -> e.size()));
System.out.println(length);
}
public static void main(String[] args) {
List<String> list = Arrays.asList("123","456","789");
collectingAndThenTest(list);
}
}
等等………
多级分组
// ------------按照成绩是否大于90分组----------------
List<User> userList =Arrays.asList(
new User("tom",11,87),
new User("jim",11,98),
new User("join",12,90),
new User("tax",13,90)
);
// 先按照成绩分组,在按照年龄分组:
Map<Integer, Map<Integer, List<User>>> cc = userList.stream().collect(Collectors.groupingBy(User::getScore, Collectors.groupingBy(User::getAge)));
System.out.println(cc);
console:
{
98={11=[User(name=jim, age=11, score=98)]},
87={11=[User(name=tom, age=11, score=87)]},
90={
12=[User(name=join, age=12, score=90)],
13=[User(name=tax, age=13, score=90)]
}
}
//先按照年龄分组,再求分数最高的
Map<Integer, User> ccc = userList.stream().collect(Collectors.groupingBy(User::getAge, Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparingInt(User::getScore)), Optional::get)));
System.out.println(ccc);
console:
{
11=User(name=jim, age=11, score=98),
12=User(name=join, age=12, score=90),
13=User(name=tax, age=13, score=90)
}
给个饭钱?
- Post link: http://sovzn.github.io/2022/12/03/collect/
- Copyright Notice: All articles in this blog are licensed under unless otherwise stated.
若没有本文 Issue,您可以使用 Comment 模版新建。
GitHub Issues