Java Collectors类

时间:2020-02-23 14:36:27  来源:igfitidea点击:

Java Collectors是一个实用程序类,提供了Collector接口的许多有用的实现。
Collector实现与Stream collect()方法一起使用。
此类在Java 8中与Stream API一起引入。
Collector 是最终类,所有方法都是静态的,这些方法返回 Collector 实例。

Java Collector 方法

一些流行的Java Collectors方法是:

  • toCollection(Supplier)
  • toList()
  • toSet()
  • toMap(Function, Function)
  • joining()
  • mapping(Function, Collector)
  • filtering(Predicate, Collector)
  • collectingAndThen(Collector, Function)
  • counting()
  • minBy(Comparator)
  • maxBy(Comparator)
  • summingInt(ToIntFunction), summingLong(ToLongFunction), summingDouble(ToDoubleFunction)
  • averagingInt(ToIntFunction), averagingLong(ToLongFunction), averagingDouble(ToDoubleFunction)
  • groupingBy(Function)
  • groupingByConcurrent(Function)
  • partitioningBy(Predicate)
  • reducing(BinaryOperator)
  • summarizingInt(ToIntFunction)

在下一节中,我将广泛使用lambda表达式和方法引用。
因此,如果您不熟悉它们,那么首先阅读这些教程并不是一个坏主意。

  • Java Lambda表达式
  • Java方法参考类型和示例

Java Collector 示例

让我们用简单的示例来看一下Collectors函数的示例。

1. toCollection(Supplier)

此函数返回一个 Collector ,该 Collector 将输入元素累积到一个集合中。

List<String> strList = Arrays.asList("a", "b", "c", "b", "a");

//toCollection()
Collection<String> strCollection = strList.parallelStream().collect(Collectors.toCollection(HashSet::new));
System.out.println(strCollection); //[a, b, c]

Set<String> strSet = strList.parallelStream().collect(Collectors.toCollection(HashSet::new));
System.out.println(strSet); //[a, b, c]

List<String> strList1 = strList.parallelStream().sorted(String::compareToIgnoreCase)
		.collect(Collectors.toCollection(ArrayList::new));
System.out.println(strList1); //[a, a, b, b, c]

2. Java Collector toList()

它返回一个 Collector ,该 Collector 将输入元素累积到新的列表中。

List<String> strList = Arrays.asList("a", "b", "c", "b", "a");

List<String> uppercaseList = strList.parallelStream().map(String::toUpperCase).collect(Collectors.toList());
System.out.println(uppercaseList); //[A, B, C, B, A]

List<String> uppercaseUnmodifiableList = strList.parallelStream().map(String::toUpperCase)
		.collect(Collectors.toUnmodifiableList());
System.out.println(uppercaseUnmodifiableList); //[A, B, C, B, A]

3. Java Collector toSet()

此方法返回将输入元素累积到新Set中的 Collector 。

List<String> strList = Arrays.asList("a", "b", "c", "b", "a");

Set<String> uppercaseSet = strList.parallelStream().map(String::toUpperCase).collect(Collectors.toSet());
System.out.println(uppercaseSet); //[A, B, C]

Set<String> uppercaseUnmodifiableSet = strList.parallelStream().map(String::toUpperCase)
		.collect(Collectors.toUnmodifiableSet());
System.out.println(uppercaseUnmodifiableSet); //[A, B, C]

4. Java Collector toMap(Function,Function)

此静态方法返回 Collector ,以将输入元素累积到新的Map中。
我们必须指定映射函数以生成映射键和值。

Map<String, String> map = Stream.of("a", "b", "c")
		.collect(Collectors.toMap(Function.identity(), String::toUpperCase));
System.out.println(map); //{a=A, b=B, c=C}

//Duplicate Keys will throw: Exception in thread "main"
//java.lang.IllegalStateException: Duplicate key a (attempted merging values A
//and A)
Map<String, String> mapD = Stream.of("a", "b", "c", "b", "a")
		.collect(Collectors.toMap(Function.identity(), String::toUpperCase, String::concat));
System.out.println(mapD); //{a=AA, b=BB, c=C}

//above are HashMap, use below to create different types of Map
TreeMap<String, String> mapTree = Stream.of("a", "b", "c", "b")
		.collect(Collectors.toMap(Function.identity(), String::toUpperCase, String::concat, TreeMap::new));
System.out.println(mapTree); {a=A, b=BB, c=C}

5. Java Collector join()

它返回一个 Collector ,该 Collector 将输入的CharSequence元素连接到一个新字符串中。
很少有重载方法可以指定定界符和后缀/前缀字符串。

String concat = Stream.of("a", "b").collect(Collectors.joining());
System.out.println(concat); //ab

String csv = Stream.of("a", "b").collect(Collectors.joining(","));
System.out.println(csv); //a,b

String csv1 = Stream.of("a", "b").collect(Collectors.joining(",", "[", "]"));
System.out.println(csv1); //[a,b]

String csv2 = Stream.of("a", new StringBuilder("b"), new StringBuffer("c")).collect(Collectors.joining(","));
System.out.println(csv2); //a,b

6. Java Collector 映射(函数, Collector )

此方法返回一个 Collector ,该 Collector 将函数应用于输入元素,然后将其累加到给定的 Collector 。

Set<String> setStr = Stream.of("a", "a", "b")
		.collect(Collectors.mapping(String::toUpperCase, Collectors.toSet()));
System.out.println(setStr); //[A, B]

Set<String> setStr1 = Stream.of("a", "a", "b")
		.collect(Collectors.flatMapping(s -> Stream.of(s.toUpperCase()), Collectors.toSet()));
System.out.println(setStr1); //[A, B]

7.过滤(谓词, Collector )

它返回一个 Collector ,该 Collector 将谓词应用于输入元素,如果谓词返回true,则将它们累加到给定的 Collector 。

List<String> strList2 = List.of("1", "2", "10", "100", "20", "999");
Set<String> set = strList2.parallelStream()
		.collect(Collectors.filtering(s -> s.length() < 2, Collectors.toSet()));
System.out.println(set); //[1, 2]

8. collectionAndThen(Collector,Function)

此静态方法返回一个 Collector ,该 Collector 将输入元素累积到给定的 Collector 中,然后执行附加的整理功能。

List<String> strList2 = List.of("1", "2", "10", "100", "20", "999");

List<String> unmodifiableList = strList2.parallelStream()
		.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
System.out.println(unmodifiableList); //[1, 2, 10, 100, 20, 999]

9. counting()

该函数返回一个 Collector ,该 Collector 对输入元素的数量进行计数。

Long evenCount = Stream.of(1, 2, 3, 4, 5).filter(x -> x % 2 == 0).collect(Collectors.counting());
System.out.println(evenCount); //2

10. minBy(比较器)

它返回一个 Collector ,该 Collector 根据给定的比较器返回最小元素。

Optional<Integer> min = Stream.of(1, 2, 3, 4, 5).collect(Collectors.minBy((x, y) -> x - y));
System.out.println(min); //Optional[1]

11. maxBy(比较器)

此方法返回一个 Collector ,该 Collector 根据给定的比较器返回最大元素。

Optional<Integer> max = Stream.of(1, 2, 3, 4, 5).collect(Collectors.minBy((x, y) -> y - x));
System.out.println(max); //Optional[5]

12. summingInt(ToIntFunction)

此静态方法返回一个 Collector ,该 Collector 生成应用于输入元素的整数函数的总和。
long和double都有类似的功能-summingLong(ToLongFunction)和summingDouble(ToDoubleFunction)。

List<String> strList3 = Arrays.asList("1", "2", "3", "4", "5");
Integer sum = strList3.parallelStream().collect(Collectors.summingInt(Integer::parseInt));
System.out.println(sum); //15

Long sumL = Stream.of("12", "23").collect(Collectors.summingLong(Long::parseLong));
System.out.println(sumL); //35

Double sumD = Stream.of("1e2", "2e3").collect(Collectors.summingDouble(Double::parseDouble));
System.out.println(sumD); //2100.0

13. averagingInt(ToIntFunction)

它返回一个 Collector ,该 Collector 产生应用于输入元素的整数函数的算术平均值。
长整型和双精度型也有类似的功能– averagingLong(ToLongFunction)和averagingDouble(ToDoubleFunction)。

List<String> strList4 = Arrays.asList("1", "2", "3", "4", "5");
Double average = strList4.parallelStream().collect(Collectors.averagingInt(Integer::parseInt));
System.out.println(average); //3.0

Double averageL = Stream.of("12", "23").collect(Collectors.averagingLong(Long::parseLong));
System.out.println(averageL); //17.5

Double averageD = Stream.of("1e2", "2e3").collect(Collectors.averagingDouble(Double::parseDouble));
System.out.println(averageD); //1050.0

14. Java Collector 分组(按功能)

此方法返回在输入元素上实现"分组依据"操作的 Collector 。
最终结果是一个HashMap。
很少有重载的方法来指定Supplier(最终Map类型,默认为HashMap)和Collector(Value List类型,默认为ArrayList)。

Map<Integer, List<Integer>> mapGroupBy = Stream.of(1, 2, 3, 4, 5, 4, 3)
		.collect(Collectors.groupingBy(x -> x * 10));
System.out.println(mapGroupBy); //{50=[5], 20=[2], 40=[4, 4], 10=[1], 30=[3, 3]}

15. groupingByConcurrent(函数)

它的工作方式与groupingBy() Collector 相同。
唯一的区别是 Collector 是并发且无序的。
它比groupingBy() Collector 具有更好的性能,但是将不保留其顺序。

Map<Integer, List<Integer>> mapGroupBy = Stream.of(1, 2, 3, 4, 5, 4, 3)
		.collect(Collectors.groupingByConcurrent(x -> x * 10));
System.out.println(mapGroupBy); //{50=[5], 20=[2], 40=[4, 4], 10=[1], 30=[3, 3]}

16. partitioningBy(谓词)

此方法返回一个 Collector ,该 Collector 根据谓词对输入元素进行分区,并将它们组织成Map <Boolean,List <T >>。

Map<Boolean, List<Integer>> mapPartitionBy = Stream.of(1, 2, 3, 4, 5, 4, 3)
		.collect(Collectors.partitioningBy(x -> x % 2 == 0));
System.out.println(mapPartitionBy); //{false=[1, 3, 5, 3], true=[2, 4, 4]}

17. Java Collector精简(BinaryOperator)

它返回一个 Collector ,该 Collector 在指定的BinaryOperator下执行其输入元素的缩减。
这主要用于多级归约中,例如使用groupingBy()和partitioningBy()方法指定下游Collector。

Map<Boolean, Optional<Integer>> reducing = Stream.of(1, 2, 3, 4, 5, 4, 3).collect(Collectors.partitioningBy(
		x -> x % 2 == 0, Collectors.reducing(BinaryOperator.maxBy(Comparator.comparing(Integer::intValue)))));
System.out.println(reducing); //{false=Optional[5], true=Optional[4]}

18. summarizingInt(ToIntFunction)

它返回一个 Collector ,该 Collector 将一个产生int的映射函数应用于每个输入元素,并返回结果统计值的摘要,例如最小值,最大值,平均值,计数和计数。

IntSummaryStatistics summarizingInt = Stream.of("12", "23", "35")
  .collect(Collectors.summarizingInt(Integer::parseInt));
System.out.println(summarizingInt);
//IntSummaryStatistics{count=3, sum=70, min=12, average=23.333333, max=35}