Collector
基本概念
收集器:Collector 可以把流(Stream)中的元素收集成某种结果,比如 List、Set、Map、字符串、统计结果等。
最常见的使用方式是:
java
stream.collect(collector)其中:
collect(...)是Stream的终止操作。Collector是收集规则。Collectors是一个工具类,用来创建各种常用的Collector。
例如:
java
List<String> list = Stream.of("Tom", "Jerry", "Rose")
.collect(Collectors.toList());Collectors 常用方法
Collectors 是 Java Stream API 中的工具类,专门提供各种现成的 Collector 实现。
toList()
- 作用:把流中的元素收集到
List中 - 返回值:
List<T>
java
List<String> names = Arrays.asList("Tom", "Jerry", "Rose");
List<String> list = names.stream()
.collect(Collectors.toList());
System.out.println(list); // [Tom, Jerry, Rose]toSet()
- 作用:把流中的元素收集到
Set中 - 返回值:
Set<T> - 注意:会自动去重
java
List<String> names = Arrays.asList("Tom", "Jerry", "Tom", "Rose");
Set<String> set = names.stream()
.collect(Collectors.toSet());
System.out.println(set); // [Tom, Jerry, Rose]toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper)
- 作用:把流中元素收集成
Map - 返回值:
Map<K, U> - 注意:如果 key 重复,会抛出异常
java
List<String> names = Arrays.asList("Tom", "Jerry", "Rose");
Map<String, Integer> map = names.stream()
.collect(Collectors.toMap(
name -> name,
String::length
));
System.out.println(map); // {Tom=3, Jerry=5, Rose=4}toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper, BinaryOperator<U> mergeFunction)
- 作用:收集成
Map,当 key 冲突时按合并规则处理 - 返回值:
Map<K, U>
java
List<String> names = Arrays.asList("Tom", "Tom", "Jerry");
Map<String, Integer> map = names.stream()
.collect(Collectors.toMap(
name -> name,
name -> 1,
Integer::sum
));
System.out.println(map); // {Tom=2, Jerry=1}joining()
- 作用:把流中的字符串拼接成一个字符串
- 返回值:
String
java
List<String> names = Arrays.asList("Tom", "Jerry", "Rose");
String result = names.stream()
.collect(Collectors.joining());
System.out.println(result); // TomJerryRosejoining(CharSequence delimiter)
- 作用:按指定分隔符拼接字符串
- 返回值:
String
java
List<String> names = Arrays.asList("Tom", "Jerry", "Rose");
String result = names.stream()
.collect(Collectors.joining(", "));
System.out.println(result); // Tom, Jerry, Rosejoining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
- 作用:按指定分隔符拼接,并添加前缀和后缀
- 返回值:
String
java
List<String> names = Arrays.asList("Tom", "Jerry", "Rose");
String result = names.stream()
.collect(Collectors.joining(", ", "[", "]"));
System.out.println(result); // [Tom, Jerry, Rose]counting()
- 作用:统计流中元素个数
- 返回值:
Long
java
List<String> names = Arrays.asList("Tom", "Jerry", "Rose");
Long count = names.stream()
.collect(Collectors.counting());
System.out.println(count); // 3summingInt(ToIntFunction<? super T> mapper)
- 作用:对映射后的
int值求和 - 返回值:
Integer
java
List<String> names = Arrays.asList("Tom", "Jerry", "Rose");
Integer sum = names.stream()
.collect(Collectors.summingInt(String::length));
System.out.println(sum); // 12averagingInt(ToIntFunction<? super T> mapper)
- 作用:对映射后的
int值求平均值 - 返回值:
Double
java
List<String> names = Arrays.asList("Tom", "Jerry", "Rose");
Double avg = names.stream()
.collect(Collectors.averagingInt(String::length));
System.out.println(avg); // 4.0maxBy(Comparator<? super T> comparator)
- 作用:按比较器规则收集出最大元素
- 返回值:
Optional<T>
java
List<String> names = Arrays.asList("Tom", "Jerry", "Rose");
Optional<String> max = names.stream()
.collect(Collectors.maxBy(Comparator.comparingInt(String::length)));
System.out.println(max.get()); // JerryminBy(Comparator<? super T> comparator)
- 作用:按比较器规则收集出最小元素
- 返回值:
Optional<T>
java
List<String> names = Arrays.asList("Tom", "Jerry", "Rose");
Optional<String> min = names.stream()
.collect(Collectors.minBy(Comparator.comparingInt(String::length)));
System.out.println(min.get()); // TomgroupingBy(Function<? super T, ? extends K> classifier)
- 作用:按照某个规则分组
- 返回值:
Map<K, List<T>>
java
List<String> names = Arrays.asList("Tom", "Jerry", "Rose", "Jack", "Bob");
Map<Integer, List<String>> map = names.stream()
.collect(Collectors.groupingBy(String::length));
System.out.println(map); // {3=[Tom, Bob], 4=[Rose, Jack], 5=[Jerry]}groupingBy(Function<? super T, ? extends K> classifier, Collector<? super T, A, D> downstream)
- 作用:先分组,再对每组继续收集
- 返回值:由下游收集器决定
java
List<String> names = Arrays.asList("Tom", "Jerry", "Rose", "Jack", "Bob");
Map<Integer, Long> map = names.stream()
.collect(Collectors.groupingBy(
String::length,
Collectors.counting()
));
System.out.println(map); // {3=2, 4=2, 5=1}partitioningBy(Predicate<? super T> predicate)
- 作用:按条件分成两组
- 返回值:
Map<Boolean, List<T>>
java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
Map<Boolean, List<Integer>> map = numbers.stream()
.collect(Collectors.partitioningBy(num -> num % 2 == 0));
System.out.println(map); // {false=[1, 3, 5], true=[2, 4, 6]}mapping(Function<? super T, ? extends U> mapper, Collector<? super U, A, R> downstream)
- 作用:先映射元素,再交给下游收集器处理
- 返回值:由下游收集器决定
java
List<String> names = Arrays.asList("Tom", "Jerry", "Rose");
List<Integer> lengths = names.stream()
.collect(Collectors.mapping(
String::length,
Collectors.toList()
));
System.out.println(lengths); // [3, 5, 4]