Collectors类作为Collector接口对应的工具类,除提供了对应的实现类(CollectorImpl)以外,还提供了各种快速生成Collector实例的工具方法.
toList/toSet/(toCollection)
无入参, 转set集合、List集合或自定义的集合
@Test
public void test1() {
// 转Set集合
Set<String> set = Stream.of("ZH", "cn", "hello", "Word").collect(Collectors.toSet());
// 转List集合
List<String> list = Stream.of("ZH", "cn", "hello", "Word").collect(Collectors.toList());
// 特定转换
LinkedList linkedList = Stream.of("ZH", "cn", "hello", "Word").collect(Collectors.toCollection(()->{
return new LinkedList<>();
}));
}
toMap/toConcurrentMap及各种重载形式
此两类方法之间为是否并发的区别,最终结果分别为Map和ConcurrentMap,同时各自有三种重载形式
入参说明
keyMapper: 将stream内部元素映射为key的表达式
valueMapper: 将stream内部元素映射为value的表达式
mergeFunction: 当同一个key对应的value冲突时,重新映射的表达式
mapSupplier: map的supplier
// 只需要提供key的生成器和value生成器
public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
}
// 只需要提供key的生成器、value生成器、同一个key对应的value冲突时,重新映射的表达式
public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction) {
return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
}
// 只需要提供key的生成器、value生成器、同一个key对应的value冲突时,重新映射的表达式、map的生成方法
public static <T, K, U, M extends Map<K, U>>
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction,
Supplier<M> mapSupplier) {
BiConsumer<M, T> accumulator
= (map, element) -> map.merge(keyMapper.apply(element),
valueMapper.apply(element), mergeFunction);
return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
}
示例:
/**
* toMap/toConcurrentMap及各种重载形式
*/
@Test
public void testToMap() {
List<Person> listPerson = new ArrayList<>();
listPerson.add(new Person(10, "张三"));
listPerson.add(new Person(12, "李四"));
listPerson.add(new Person(14, "王五"));
// 简单API的使用
Map result = listPerson.stream().collect(Collectors.toMap(
// key的生成
(item) -> {
return item.getId();
},
// value的生成
(item) -> {
return item;
}));
System.out.println(result);//{10=Person(id=10, name=张三), 12=Person(id=12, name=李四), 14=Person(id=14, name=王五)}
listPerson.add(new Person(14, "王麻子"));
// 复杂API的使用
result = listPerson.stream().collect(Collectors.toMap(
// 将stream内部元素映射为key的表达式
(item) -> item.getId(),
// 将stream内部元素映射为value的表达式
(item) -> item,
// 同一个key对应的value冲突时,重新映射的表达式
(item1Value, item2Value) -> {
if (item1Value.getName().length() > item2Value.getName().length()) {
return item1Value;
} else {
return item2Value;
}
},
// map的构造器
() -> {
return new TreeMap();
}));
System.out.println(result);//{10=Person(id=10, name=张三), 12=Person(id=12, name=李四), 14=Person(id=14, name=王麻子)}
}
joining 连接器
将steam里的元素连接成一个String
@Test
public void testJoining() {
String result = Stream.of("ZH", "cn", "hello", "Word").collect(Collectors.joining());
System.out.println(result);//ZHcnhelloWord
// 连接符、前缀、后缀
result = Stream.of("ZH", "cn", "hello", "Word").collect(Collectors.joining("-", "pre", "fix"));
System.out.println(result);//preZH-cn-hello-Wordfix
}
reducing及其重载形式,maxBy,minBy
reducing表示对steam里的元素做运算,最终等到一个值。
identity:初值,设置一个steam元素与外部比较的一个初始值。
mapper: 将stream内部类型映射为U类型的方法
BinaryOperator:op两个U类型值合并运算的方法
// 直接对steam里的元素做合并运算,比较类型即为steam里的类型
public static <T> Collector<T, ?, Optional<T>> reducing(BinaryOperator<T> op){
}
// 设置一个初始值,直接对steam里的元素做合并运算
public static <T> Collector<T, ?, T> reducing(T identity, BinaryOperator<T> op){
}
// identity设置一个初始值, mapper将steam里的元素转成合并运算的对象,op合并运算的方法
public static <T, U> Collector<T, ?, U> reducing(U identity, Function<? super T, ? extends U> mapper, BinaryOperator<U> op){
}
示例:
@Test
public void testReducing1() {
Stream<String> stream = Stream.of("ZH", "cn", "hello", "Word");
Optional<String> op1 = stream.collect(Collectors.reducing((item1, item2) -> {
if (item1.compareTo(item2) >= 0) {
return item1;
} else {
return item2;
}
}));
System.out.println(op1.get());//hello
}
@Test
public void testReducing2() {
Stream<String> stream = Stream.of("ZH", "cn", "hello", "Word");
String init = "WWW";
String s1 = stream.collect(Collectors.reducing(init, (item1, item2) -> {
if (item1.compareTo(init) > 0) {
return item1;
} else {
return init;
}
}));
System.out.println(s1);//WWW
}
@Test
public void testReducing3() {
Stream<String> stream = Stream.of("ZH", "cn", "hello", "Word");
Person person = new Person();
Person p1 = stream.collect(Collectors.reducing(
// 初始值
person,
// 将stream内部类型转化成合并运算的对象(Person)
(item) -> {
Person personItem = new Person();
personItem.setName(item);
personItem.setId(item.length());
return personItem;
},
// 根据转换后的值做合并运算
(item1, item2) -> {
if (item1.getId() > item2.getId()) {
return item1;
} else {
return item2;
}
}
));
System.out.println(p1);//Person(id=5, name=hello)
}
minBy maxBy 就是BinaryOperator提供的简洁方法
@Test
public void testMinBy() {
Stream<String> stream = Stream.of("ZH", "cn", "hello", "Word");
Optional<String> p1 = stream.collect(Collectors.reducing(BinaryOperator.minBy((item1, item2) -> {
return item1.compareTo(item2);
})));
System.out.println(p1.get());
}
summingLong、summingInt、summingDouble
将steam元素转成long,int,double后做累计
@Test
public void testSummingInt() {
Stream<String> stream = Stream.of("ZH", "cn", "hello", "Word");
int count = stream.collect(Collectors.summingInt(
// 将item转成统计维度的数字
(item) -> {
return item.length();
}));
System.out.println(count);
}
averagingInt/averagingDouble/averagingLong
将steam元素转成long,int,double后做平均值
@Test
public void testAveragingInt() {
Stream<String> stream = Stream.of("ZH", "cn", "hello", "Word");
double count = stream.collect(Collectors.averagingInt((item)->{
return item.length();
}));
System.out.println(count);
}
summarizingInt/summarizingLong/summarizingDouble
将steam元素转成long,int,double后做统计(最大,最小、平均值)
@Test
public void testSummarizingInt(){
Stream<String> stream = Stream.of("ZH", "cn", "hello", "Word");
IntSummaryStatistics intSummaryStatistics = stream.collect(Collectors.summarizingInt((item)->{
return item.length();
}));
System.out.println(intSummaryStatistics);//IntSummaryStatistics{count=4, sum=13, min=2, average=3.250000, max=5}
}
groupingBy/groupingByConcurrent及其重载形式
将steam元素分组后聚合,API有两种形式
public static <T, K, A, D>
Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,// 分组结果map的key的生成
Collector<? super T, A, D> downstream) {//分组结果map的value的生成
}
public static <T, K, D, A, M extends Map<K, D>>
Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier,// 分组结果map的key的生成
Supplier<M> mapFactory,// 分组结果map的生成
Collector<? super T, A, D> downstream) {//分组结果map的value的生成
}
示例:
@Test
public void testGroupingBy1() {
Stream<String> stream = Stream.of("ZH", "cn", "hello", "Word");
Map<String, Long> stat = stream.collect(Collectors.groupingBy(
// key的生成方法
(item) -> {
return item.toUpperCase();
},
// value的内容
Collectors.counting()));
System.out.println(stat);//{WORD=1, HELLO=1, CN=1, ZH=1}
}
@Test
public void testGroupingBy2() {
List<Person> listPerson = new ArrayList<>();
listPerson.add(new Person(10, "张三"));
listPerson.add(new Person(12, "李四"));
listPerson.add(new Person(14, "王五"));
listPerson.add(new Person(16, "王麻子"));
TreeMap obj = listPerson.stream().collect(Collectors.groupingBy(
// key的生成方法
(item) -> {
return item.getName().substring(0, 1);
},
// 返回Map的生成方法
() -> {
return new TreeMap();
},
// Map的Value内容
Collectors.toList()));
System.out.println(obj);//{张=[Person(id=10, name=张三)], 李=[Person(id=12, name=李四)], 王=[Person(id=14, name=王五), Person(id=16, name=王麻子)]}
}
网友评论