Skip to content

Collector

基本概念

收集器:Collector 可以把流(Stream)中的元素收集成某种结果,比如 ListSetMap、字符串、统计结果等。

最常见的使用方式是:

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); // TomJerryRose

joining(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, Rose

joining(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); // 3

summingInt(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); // 12

averagingInt(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.0

maxBy(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()); // Jerry

minBy(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()); // Tom

groupingBy(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]