java8 Collectors
记录一下 java8 Collectors 收集器使用详解。
1.Collectors.toList()
List<String> result = givenList.stream()
.collect(toList());
2.Collectors.toSet()
Set<String> result = givenList.stream()
.collect(toSet());
3.Collectors.toMap()
toMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction, Supplier mapSupplier)
The arguments are as follows. Function keyMapper
: It generates key for Map
. Function valueMapper
: It generates value for Map
. BinaryOperator mergeFunction
: This is optional. The usability of merge function is to handle the situation of duplicate Map
keys. Using BinaryOperator
we can merge the values of duplicate keys. If we do not pass this argument, then by default it throws IllegalStateException
in case of duplicate keys. Supplier mapSupplier
: This is optional. It returns a Map
in which data is filled as key/value. If we do not pass map supplier then the default supplier will return HashMap
. If we want to get any other instance such as LinkedHashMap
, we need to pass supplier as LinkedHashMap::new
.
3.1 toMap(Function keyMapper, Function valueMapper
ListToMap1.java
package com.concretepage; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; public class ListToMap1 { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("Mohan"); list.add("Sohan"); list.add("Mahesh"); Map<String, Object> map = list.stream().collect(Collectors.toMap(Function.identity(), s->s)); map.forEach((x, y) -> System.out.println("Key: " + x +", value: "+ y)); } }
output
Key: Mohan, value: Mohan
Key: Mahesh, value: Mahesh
Key: Sohan, value: Sohan
ListToMap2.java
package com.concretepage; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class ListToMap2 { public static void main(String[] args) { List<Person> list = new ArrayList<>(); list.add(new Person(100, "Mohan")); list.add(new Person(200, "Sohan")); list.add(new Person(300, "Mahesh")); Map<Integer, String> map = list.stream() .collect(Collectors.toMap(Person::getId, Person::getName)); map.forEach((x, y) -> System.out.println("Key: " + x +", value: "+ y)); } }
output
Key: 100, value: Mohan Key: 200, value: Sohan Key: 300, value: Mahesh
3.2 toMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction)
ListToMapWithBinaryOperator.java
package com.concretepage; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class ListToMapWithBinaryOperator { public static void main(String[] args) { List<Person> list = new ArrayList<>(); list.add(new Person(100, "Mohan")); list.add(new Person(100, "Sohan")); list.add(new Person(300, "Mahesh")); Map<Integer, String> map = list.stream() .collect(Collectors.toMap(Person::getId, Person::getName, (x, y) -> x+", "+ y)); map.forEach((x, y) -> System.out.println("Key: " + x +", value: "+ y)); } }
output
Key: 100, value: Mohan, Sohan
Key: 300, value: Mahesh
3.3 toMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction, Supplier mapSupplier)
ListToMapWithSupplier.java
package com.concretepage; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.stream.Collectors; public class ListToMapWithSupplier { public static void main(String[] args) { List<Person> list = new ArrayList<>(); list.add(new Person(100, "Mohan")); list.add(new Person(100, "Sohan")); list.add(new Person(300, "Mahesh")); LinkedHashMap<Integer, String> map = list.stream() .collect(Collectors.toMap(Person::getId, Person::getName, (x, y) -> x+", "+ y, LinkedHashMap::new)); map.forEach((x, y) -> System.out.println("Key: " + x +", value: "+ y)); } }
output
Key: 100, value: Mohan, Sohan
Key: 300, value: Mahesh
4. Collectors.toCollection()
可以转成具体的实现
List<String> result = givenList.stream() .collect(toCollection(LinkedList::new))
5. Collectors.partitioningBy()
判断true、false 返回两个集合
Map<Boolean, List<Developer>> youngerThan30 = team. stream(). collect(Collectors.partitioningBy(d -> d.getAge() < 30)); System.out.println("Developers younger than thirty are using: " + youngerThan30.get(true).stream(). map(d -> d.getFavoriteLanguage()). collect(Collectors.toSet())); //Output: Developers younger than thirty are using: [java] System.out.println("Developers older than thirty are using: " + youngerThan30.get(false).stream(). map(d -> d.getFavoriteLanguage()). collect(Collectors.toSet())); //Output: Developers older than thirty are using: [logo, javascript]
6.Collectors.groupingBy()
<T,K,A,D> Collector<T,?,Map<K,D>> groupingBy(Function<? super T,? extends K> classifier, Collector<? super T,A,D> downstream)
Map<Integer, List<Person>> peropleByAge = people.filter(p -> p.age > 12).collect(Collectors.groupingBy(p -> p.age, Collectors.toList()));
Map<Integer, List<String>> peropleByAge = people.collect(Collectors.groupingBy(p -> p.age, Collectors.mapping((Person p) -> p.name, Collectors.toList())));
Map<String, Integer> sumAgeByName = people.collect(Collectors.groupingBy(p -> p.name, Collectors.reducing(0, (Person p) -> p.age, Integer::sum))); /* 或者使用summingInt方法 */ sumAgeByName = people.collect(Collectors.groupingBy(p -> p.name, Collectors.summingInt((Person p) -> p.age)));
Map<String,Long> map = list.stream().collect(groupingBy(Person::getName,counting()));
7.Collectors.joininng()
String result = givenList.stream()
.collect(joining(" "));
String result = givenList.stream()
.collect(joining(" ", "PRE-", "-POST"));
8.Collectors.counting()
Long result = givenList.stream()
.collect(counting());
9.Collectors.reduce()
9.1 reduce(BinaryOperator accumulator)
package com.concretepage; import java.util.Arrays; public class ReduceDemo1 { public static void main(String[] args) { int[] array = {23,43,56,97,32}; Arrays.stream(array).reduce((x,y) -> x+y).ifPresent(s -> System.out.println(s)); Arrays.stream(array).reduce(Integer::sum).ifPresent(s -> System.out.println(s)); Arrays.stream(array).reduce(StatisticsUtility::addIntData).ifPresent(s -> System.out.println(s)); } }
package com.concretepage; public class StatisticsUtility { public static int addIntData(int num1, int num2) { return num1 + num2; } }
9.2 reduce(T identity, BinaryOperator<T> accumulator)
ackage com.concretepage; import java.util.Arrays; public class ReduceDemo2 { public static void main(String[] args) { int[] array = {23,43,56,97,32}; //Set start value. Result will be start value + sum of array. int startValue = 100; int sum = Arrays.stream(array).reduce(startValue, (x,y) -> x+y); System.out.println(sum); sum = Arrays.stream(array).reduce(startValue, Integer::sum); System.out.println(sum); sum = Arrays.stream(array).reduce(startValue, StatisticsUtility::addIntData); System.out.println(sum); } }
9.3 reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
package com.concretepage; import java.util.Arrays; import java.util.List; public class ReduceDemo3 { public static void main(String[] args) { List<Integer> list2 = Arrays.asList(2, 3, 4); //Here result will be 2*2 + 2*3 + 2*4 that is 18. int res = list2.parallelStream().reduce(2, (s1, s2) -> s1 * s2, (p, q) -> p + q); System.out.println(res); List<String> list1 = Arrays.asList("Mohan", "Sohan", "Ramesh"); String result = list1.parallelStream().reduce("-", (s1, s2) -> s1 + s2, (p, q) -> p + q); System.out.println(result); } }
output
18 -Mohan-Sohan-Ramesh
10.Collectors.collectingAndThen()
将收集到的结果转换成另一种形式
public class CollectingAndThenExample { public static void main (String[] args) { Stream<String> s = Stream.of("apple", "banana", "orange"); List<String> synchronizedList = s.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::synchronizedList)); System.out.println(synchronizedList); } }
public class CollectingAndThenExample { public static void main(String[] args) { List<Integer> list = Arrays.asList(1,2,3,4); Double result = list.stream().collect(Collectors.collectingAndThen(Collectors.averagingLong(v->v*2), s-> s*s)); System.out.println(result); } }
11.Collectors.summarizingDouble/Long/Int()
统计数据时常用
getAverage(): It returns the average of all accepted value.
getCount(): It calculates the count of all element.
getMax(): It returns the maximum value.
getMin(): It returns the minimum value.
getSum(): It returns the sum of all elements.
accept(): It adds the element into the summary information.
combine(): It combines two summary statistics.
11.1 primitive data type
public class SummaryStatisticsWithPrimitiveDataType { public static void main(String[] args) { System.out.println("---DoubleSummaryStatistics---"); DoubleSummaryStatistics dstats = DoubleStream.of(5.33d,2.34d,5.32d,2.31d,3.51d). collect(DoubleSummaryStatistics::new, DoubleSummaryStatistics::accept, DoubleSummaryStatistics::combine); System.out.println("Max:"+dstats.getMax()+", Min:"+dstats.getMin()); System.out.println("Count:"+dstats.getCount()+", Sum:"+dstats.getSum()); System.out.println("Average:"+dstats.getAverage()); System.out.println("---LongSummaryStatistics---"); LongSummaryStatistics lstats = LongStream.of(51l,23l,53l,23l,35l). collect(LongSummaryStatistics::new, LongSummaryStatistics::accept, LongSummaryStatistics::combine); System.out.println("Max:"+lstats.getMax()+", Min:"+lstats.getMin()); System.out.println("Count:"+lstats.getCount()+", Sum:"+lstats.getSum()); System.out.println("Average:"+lstats.getAverage()); System.out.println("---IntSummaryStatistics---"); IntSummaryStatistics istats = IntStream.of(51,22,50,27,35). collect(IntSummaryStatistics::new, IntSummaryStatistics::accept, IntSummaryStatistics::combine); System.out.println("Max:"+istats.getMax()+", Min:"+istats.getMin()); System.out.println("Count:"+istats.getCount()+", Sum:"+istats.getSum()); System.out.println("Average:"+istats.getAverage()); } }
11.2 with objects
public class SummaryStatisticsDemoWithObject { public static void main(String[] args) { System.out.println("--DoubleSummaryStatistics--"); List<Rectangle> list = Rectangle.getRectangle(); DoubleSummaryStatistics dstats = list.stream() .collect(Collectors.summarizingDouble(Rectangle::getWidth)); System.out.println("Max:"+dstats.getMax()+", Min:"+dstats.getMin()); System.out.println("Count:"+dstats.getCount()+", Sum:"+dstats.getSum()); System.out.println("Average:"+dstats.getAverage()); System.out.println("--IntSummaryStatistics--"); list = Rectangle.getRectangle(); IntSummaryStatistics istats = list.stream() .collect(Collectors.summarizingInt(Rectangle::getLength)); System.out.println("Max:"+istats.getMax()+", Min:"+istats.getMin()); System.out.println("Count:"+istats.getCount()+", Sum:"+istats.getSum()); System.out.println("Average:"+istats.getAverage()); System.out.println("--LongSummaryStatistics--"); list = Rectangle.getRectangle(); LongSummaryStatistics lstats = list.stream(). collect(Collectors.summarizingLong(Rectangle::getId)); System.out.println("Max:"+lstats.getMax()+", Min:"+lstats.getMin()); System.out.println("Count:"+lstats.getCount()+", Sum:"+lstats.getSum()); System.out.println("Average:"+lstats.getAverage()); } }
12. Collectors.averagingDouble/Long/Int()
求平均值
12.1 averagingDouble
public class AveragingDoubleExample { public static void main(String[] args) { List<Integer> list = Arrays.asList(1,2,3,4); Double result = list.stream().collect(Collectors.averagingDouble(d->d*2)); System.out.println(result); } }
12.2 averagingInt
public class AveragingIntExample { public static void main(String[] args) { List<Integer> list = Arrays.asList(1,2,3,4); Double result = list.stream().collect(Collectors.averagingInt(v->v*2)); System.out.println(result); } }
12.3 averagingLong
public class AveragingLongExample { public static void main(String[] args) { List<Integer> list = Arrays.asList(1,2,3,4); Double result = list.stream().collect(Collectors.averagingLong(v->v*2)); System.out.println(result); } }
13. maxBy/minBy
求最大值、最小值
public class MaxByMinBy { public static void main(String[] args) { Student s1 = new Student("Shyam", 22,"A"); Student s2 = new Student("Ram",23,"A"); Student s3 = new Student("Mohan",22,"B"); Student s4 = new Student("Ramesh",21,"B"); List<Student> list = Arrays.asList(s1,s2,s3,s4); Comparator<Student> ageComparator = Comparator.comparing(Student::getAge); //Using BinaryOperator.maxBy System.out.println("---BinaryOperator.maxBy---"); Map<String, Optional<Student>> eldestByClass = list.stream().collect(Collectors.groupingBy(Student::getClassName, Collectors.reducing(BinaryOperator.maxBy(ageComparator)))); eldestByClass.forEach((k,v)->System.out.println("Class:"+k+" Age:"+ ((Optional<Student>)v).get().getAge()+" Name:"+((Optional<Student>)v).get().getName())); //Using BinaryOperator.minBy System.out.println("---BinaryOperator.minBy---"); Map<String, Optional<Student>> youngestByClass = list.stream().collect(Collectors.groupingBy(Student::getClassName, Collectors.reducing(BinaryOperator.minBy(ageComparator)))); youngestByClass.forEach((k,v)->System.out.println("Class:"+k+" Age:"+ ((Optional<Student>)v).get().getAge()+" Name:"+((Optional<Student>)v).get().getName())); } }
请尝试网页搜索