一 概述
Collectors是Collector规范的实现,并不是接口意义上的实现。该类中提供了许多有用的聚合操作,比如讲元素累积到集合中、通过指定的规则总结元素。
一些常见的实例如下:
// 累积名字属性到一个集合中
List<String> list = people.stream().map(Person::getName).collect(Collectors.toList());
// 累积名字属性到一个TreeSet中
Set<String> set = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));
// 将元素转为String,并串联他们,中间的分隔符是逗号
String joined = things.stream()
.map(Object::toString)
.collect(Collectors.joining(", "));
// 见员工的工资求和
int total = employees.stream()
.collect(Collectors.summingInt(Employee::getSalary)));
// 将员工按部门分组
Map<Department, List<Employee>> byDept
= employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment));
// 求出各部门的薪资总和
Map<Department, Integer> totalByDept
= employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment,
Collectors.summingInt(Employee::getSalary)));
// 按照分数及格与否对学生分区
Map<Boolean, List<Student>> passingFailing =
students.stream()
.collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
二 常用静态工具方法
Collector<T, ?, C> toCollection(Supplier<C> collectionFactory)
含义:将元素聚合成Collection
泛型含义:
T 输入的元素的类型
C 聚合结果的Collection类型
参数含义:Supplier接口的作用是不接受参数,返回C类型,collectionFactory的含义就是提供聚合的结果集合,通过该参数我们可以构造ArrayList、Set等等
实例分析:
public class StreamTest {
public static void main(String[] args) {
List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android","Kotlin","World");
ArrayList<Integer> collect = stringList.stream()
.map(String::length)//将字符串转为长度
.collect(Collectors.toCollection(ArrayList::new));//聚合至ArrayList
System.out.println(collect);
TreeSet<Integer> treeSet = stringList.stream()
.map(String::length)
.collect(Collectors.toCollection(TreeSet::new));//聚合至TreeSet
System.out.println(treeSet);
//TreeSet的特点是 无序和唯一
}
}
Collector<T, ?, List<T>> toList()
含义:将元素聚合成ArrayList,是上述的方法的特殊化
泛型含义:
T 输入的元素的类型和结果集合的元素类型
实例分析:
public class StreamTest {
public static void main(String[] args) {
List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android","Kotlin","World");
List<Integer> collect = stringList.stream()
.map(String::length)//将元素转为长度
.collect(Collectors.toList());//生成ArrayList集合
System.out.println(collect);
}
}
Collector<T, ?, Set<T>> toSet()
含义:将元素聚合成HashSet,是上述的方法的特殊化
泛型含义:
T 输入的元素的类型和结果集合的元素类型
实例分析:
public class StreamTest {
public static void main(String[] args) {
List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
Set<Integer> collect = stringList.stream()
.map(String::length)//将元素转为长度
.collect(Collectors.toSet());//生成HashSet集合
System.out.println(collect);
}
}
Collector<CharSequence, ?, String> joining()
含义:拼接输入元素到一个String中,是有序的
实例分析:
public class StreamTest {
public static void main(String[] args) {
List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
String collect = stringList.stream()
.collect(Collectors.joining());
System.out.println(collect);
//结果 HelloJavaJDKAndroidKotlinWorld 按着元素的顺序拼接
}
}
Collector<CharSequence, ?, String> joining(CharSequence delimiter)
含义:以指定的分隔符,有序的拼接输入元素到一个String
参数含义:delimiter就是分隔符,比如元素是a和b,分隔符是、。拼接后的结果是a、b
实例分析:
public class StreamTest {
public static void main(String[] args) {
List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
String collect = stringList.stream()
.collect(Collectors.joining("、"));
System.out.println(collect);
结果 Hello、Java、JDK、Android、Kotlin、World
}
}
Collector<CharSequence, ?, String> joining(CharSequence delimiter,
CharSequence prefix, CharSequence suffix)
含义:以指定的分隔符、前缀和后缀,有序的拼接输入元素到一个String
参数含义:delimiter就是分隔符,prefix是前缀,suffix是后缀。比如元素是a和b,分隔符是、,前缀是[,后缀是]。拼接后的结果是[a、b]
实例分析:
public class StreamTest {
public static void main(String[] args) {
List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
String collect = stringList.stream()
.collect(Collectors.joining("、","[","]"));
System.out.println(collect);
结果 [Hello、Java、JDK、Android、Kotlin、World]
}
}
Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper, Collector<? super U, A, R> downstream)
含义:将一个Collector的类型进行转换,在进行元素聚合之前,使用mapper参数将每一个输入的T类型的元素转换为U类型。mapping函数常用于多级分区和多级分组
泛型含义:
T 输入的元素的类型
U downstream的输入类型,也就是mapper的结果类型
A downstream的中间聚合的类型
R 聚合的结果类型
参数含义:Function接口的作用是接受一个T类型的参数,返回U类型,mapper的含义就是装换流中元素,downstream接受转换后的类型,downstream的聚合结果是R类型,同返回值的结果聚合类型一致。约等于 downstream的结果就是该函数返回的结果
实例分析:
public class StreamTest {
public static void main(String[] args) {
List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
List<Integer> collect = stringList.stream()
.collect(Collectors.mapping(String::length, Collectors.toList()));
//将集合的元素转为长度,同时聚合至list,
//Collectors.toList()的结果就是整个链的结果
System.out.println(collect);
结果 [5, 4, 3, 7, 6, 5]
}
}
Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream, Function<R,RR> finisher)
含义:对参数的Collector的聚合结果进行终端转换。比如downstream的聚合结果是List,通过finisher的转换行为将其转为Class类型
泛型含义:
T 输入的元素的类型
A downstream的中间聚合的类型
R downstream聚合的结果类型
RR downstream的聚合结果转换后的最终类型
参数含义:downstream进行聚合操作,操作的结果是R类型。finisher的接受一个参数,返回一个结果,接受downstream的R类型的聚合结果,返回一个RR类型的结果
实例分析:
public class StreamTest {
public static void main(String[] args) {
List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
Class<? extends List> collect = stringList.stream()
.collect(
//首先将元素聚合至list
//然后将List类型转为Class
//最终聚合的结果就是Class对象
Collectors.collectingAndThen(Collectors.toList(), it -> it.getClass())
);
System.out.println(collect);
结果就是 class java.util.ArrayList
}
}
Collector<T, ?, Long> counting()
含义:计算出输入元素的个数,如果没有输入元素,结果就是0
泛型含义:
T 输入的元素的类型
Long 结算的结果是Long
实例分析:
public class StreamTest {
public static void main(String[] args) {
List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
Long collect = stringList.stream()
.collect(Collectors.counting());
System.out.println(collect);
//结果就是 6
}
}
Collector<T, ?, Optional<T>>
minBy(Comparator<? super T> comparator)
含义:根据参数中的比较器计算出输入元素中逻辑意义最小的元素
泛型含义:
T 输入的元素的类型
Optional<T> 结果元素,设计的意义是避免空指针异常
参数含义:comparator比较器
实例分析:
public class StreamTest {
public static void main(String[] args) {
List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
Optional<String> collect = stringList.stream()
//比较器比较的是字符串的长度
.collect(Collectors.minBy(Comparator.comparingInt(String::length)));
System.out.println(collect.orElse(""));
//结果就是 JDK
}
}
Collector<T, ?, Integer> summingInt(ToIntFunction<? super T> mapper)
含义:根据参数的mapper将T类型的元素,转为Integer,然后求和。
泛型含义:
T 输入的元素的类型
Integer 求和的结果是Integer
参数含义:mapper转换器,用于将T转为Integer
实例分析:
public class StreamTest {
public static void main(String[] args) {
List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
Integer collect = stringList.stream()
//将字符串转为其长度,然后聚合其和
.collect(Collectors.summingInt(String::length));
System.out.println(collect);
//结果就是 字符串的总长度
}
}
Collector<T, ?, Double> averagingDouble(ToDoubleFunction<? super T> mapper)
含义:根据参数的mapper将T类型的元素,转为Double,然后求出所有Double的平均值。
泛型含义:
T 输入的元素的类型
Double 平均值的结果是Double
参数含义:
mapper转换器,用于将T转为Double
实例分析:
public class StreamTest {
public static void main(String[] args) {
List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
Double collect = stringList.stream()
//将字符串转为其长度,然后聚合其平均值
.collect(Collectors.averagingDouble(String::length));
System.out.println(collect);
//结果就是 字符串的平均值
}
}
Collector<T, ?, T> reducing(T identity, BinaryOperator<T> op)
含义:使用identity初始值和op函数对输入的元素进行聚合操作
泛型含义:
T 输入的元素的类型和结果类型
参数含义:
identity是聚合的初始值,op是聚合函数。比如元素求和:identity就是0,op的行为就是累加
实例分析:
public class StreamTest {
public static void main(String[] args) {
List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
String collect = stringList.stream()
//元素的拼接,初始值为“”,left就是上次聚合的结果 right就是新的输入元素
.collect(Collectors.reducing("", (left, right) -> left + right));
System.out.println(collect);
//结果就是 字符串的拼接结果
}
}
groupingByConcurrent、groupingBy、partitioningBy
含义:对输入的元素分组和分区
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,Function<? super T, ? extends U> valueMapper, BinaryOperator<U> mergeFunction , Supplier<M> mapSupplier )
含义:将流中的元素聚合至Map,keyMapper将元素转为Map的Key,valueMapper将元素转为Map的value,mergeFunction用于处理key相同的情况,mapSupplier用于构造聚合结果Map
泛型含义:
T 输入的元素的类型
K 聚合结果Map的key的类型
U 聚合结果Map的value的类型
M 聚合结果Map类型
参数含义:
keyMapper:接受一个T类型的参数,输出一个K类型的结果,用于将元素转为Map的key
valueMapper:接受一个T类型的参数,输出一个U类型的结果,用于将元素转为Map的value
mergeFunction:接受两个U类型的参数,返回一个U类型的结果,当key出现重复时,此参数用于将两个value转为一个新value
mapSupplier:构造聚合的Map
实例分析:
public class StreamTest {
public static void main(String[] args) {
List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
//以字符串长度为key,字符串本身为value
//如果两个key重复了,将两个字符串的拼接作为其value
//聚合结果是HashMap
HashMap<Integer, String> collect = stringList.stream()
.collect(Collectors.toMap(String::length,//key
it -> it,//value
(left, right) -> left + right,//处理key重复
HashMap::new));//构造聚合结果
System.out.println(collect);
结果就是 {3=JDK, 4=Java, 5=Hello, 6=Kotlin, 7=Android}
}
}
Collector<T, ?, IntSummaryStatistics> summarizingInt(ToIntFunction<? super T> mapper)
含义:将流中元素聚合为一个IntSummaryStatistics,IntSummaryStatistics封装了许多常见的数值操作:求和、均值以及最值等
泛型含义:
T 输入的元素的类型
参数含义:
mapper:接受一个T类型,返回一个Integer
实例分析:
public class StreamTest {
public static void main(String[] args) {
List<String> stringList = Arrays.asList("Hello", "Java", "JDK", "Android", "Kotlin", "World");
IntSummaryStatistics collect = stringList.stream()
.collect(Collectors.summarizingInt(String::length));
//平均字符串的长度
System.out.println(collect.getAverage());
//字符串的个数
System.out.println(collect.getCount());
//字符串长度的总和
System.out.println(collect.getSum());
}
}
网友评论