Collectors方法详解

Collectors方法详解

零、准备

  • 本文的解释是基于JDK11版本,JDK8之后新增的方法会标识出来。
  • Collectors类是java.util.stream下的类,主要作用就是对流的处理,需要明确一点的是该类的方法与stream类中有一些方法作用相同,比如说stream.count()stream.collect(Collectors.counting())。这里相同的两个方法使用场景不同:比如说当你想分组时计数则就需要用到Collectors.counting()方法了。
  • 我们创建两个用于演示的集合liststuList
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Student{
int age;
String name;
String gender;
//构造
//set get
}
Student s1 = new Student(11,"s1","man");
Student s2 = new Student(18,"s2","man");
Student s3 = new Student(16,"s3","woman");


ArrayList<Student> stuList = new ArrayList<>(Arrays.asList(s1,s2,s3));
ArrayList<String> list = new ArrayList<>(Arrays.asList("1","2","7.34"));

一、计算操作

1.求平均数

  • Collectors.averagingDouble();
  • Collectors.averagingLong();
  • Collectors.averagingInt();
1
2
3
4
5
6
//将String转成Double求平均数
Double res = list.stream().collect(Collectors.averagingDouble(Double::parseDouble));
//将list中元素做处理再转成Double求平均数
Double res1 = list.stream().collect(Collectors.averagingDouble(d -> Double.parseDouble(d) *2));
//同理有averagingInt,不过他返回一个Float
//同理有averagingLong,他返回一个Double

2.求总和

  • Collectors.summingInt();
  • Collectors.summingLong();
  • Collectors.summingDouble();
1
Integer res7 = list.stream().collect(Collectors.summingInt(Integer::parseInt));

3.求个数

  • Collectors.counting();

    用于统计流中元素的个数。(因为在流的处理中会对集合的元素个数有影响,当流没结束时,直接获取集合size会出现问题)
    不过他返回的类型是Long

1
2
Long res2 = list.stream().collect(Collectors.counting());
//在没有对集合进行例如filter等操作时,他是相等于直接获取size()的

4.求最大最小值

  • Collectors.maxBy();
  • Collectors.minBy();

​ 接受一个比较器(比较方式)作为参数,用于计算流中所有元素的最大值和最小值。

1
stuList.stream().collect(Collectors.maxBy(Comparator.comparingInt((Student o) -> o.age)));

5.汇总

返回一个统计对象IntSummaryStatistics,该对象里包含【平均值,最大值,总和,最小值,长度】

  • Collectors.summarizingInt();
  • Collectors.summarizingLong();
  • Collectors.summarizingDouble();
1
2
3
4
5
6
IntSummaryStatistics res8 = stuList.stream().collect(Collectors.summarizingInt(Student::getAge));
res8.getAverage();
res8.getCount();
res8.getMax();
res8.getMin();
res8.getSum();

二、处理操作

1.映射规约

  • Collectors.mapping();

  • Collectors.reducing();

    maping 方法指将一个流中的内容进行映射变换操作,reducing方法指对流中数据进行规约处理操作。

1
2
3
4
5
6
List<String> stuNameList = Stream.of(studentA,studentB,studentC)
.collect(Collectors.mapping(Student::getName,Collectors.toList()));
Optional<Integer> res = Stream.of(studentA, studentB, studentC)
.map(student -> student.name.length())
.collect(Collectors.reducing(Integer::sum));
Integer resInt = res.get();
  • Collectors.collectingAndThen();

    集合先进行第一个参数 map(映射)操作,再进行第二个参数的reduce(归约)操作。

1
2
3
//下例是将数组中元素先 *2 再求平均数的一个操作。
Double res4 = list.stream().
collect(Collectors.collectingAndThen(Collectors.averagingDouble(Double::parseDouble),d -> d *2));

2.处理

  • Collectors.joining();

    可以以顺序拼接元素。我们可以传递可选的拼接字符串、前缀和后缀。

1
2
String res6 = list.stream().collect(Collectors.joining("-","[","]"));
//res6 = [1-2-7.34]
  • Collectors.groupingBy();

    对集合进行分组操作

1
Map<String, List<Student>> res5 = stuList.stream().collect(Collectors.groupingBy(Student::getGender));
  • Collectors.groupingByConcurrent();
    相对于groupingBy(),它更能满足:不要求顺序(无序),更需要并发的分组操作。

  • Collectors.filtering(); Java 9

    Collectors.filtering()方法类似于Stream filter()方法,后者用于过滤输入元素,但两者的使用场景不同。Stream filter()在stream链接方法中使用,而Collectors.filtering()方法被设计和 groupingBy一起使用。

  • Collectors.flatMapping(); Java9

    它允许我们处理嵌套的集合,在其中再进行流处理

  • Collectors.partitioningBy();

    是一种将流的元素始终分为两部分的方法。

1
2
Map<Boolean, List<Student>> stdByClass =
stuList.stream().collect(Collectors.partitioningBy(s -> s.getAge() > 15));

三、转化操作

1.基本转化

  • Collectors.toCollection();

    返回一个Collection集合,(集合层次结构中的基类)

  • Collectors.toMap();

  • Collectors.toSet();

  • Collectors.toList();

2.其他

  • Collectors.toConcurrentMap();

    返回一个支持并发的Map,代价则是它是无序的。

  • Collectors.toUnmodifiableList(); java10

  • Collectors.toUnmodifiableSet();

  • Collectors.toUnmodifiableMap();

    返回一个不可变的集合,即不能对它进行增删改操作。与stream.toList();一样。