Stream 的核心在于Collectors,即对处理后的数据进行收集。Collectors 提供了非常多且强大的API,可以将最终的数据收集成List、Set、Map,甚至是更复杂的结构(这三者的嵌套组合)。

Collectors 提供了很多的 API,有很多都是一些函数的重载
大概可以分为以下三大类,如下:

  1. 数据收集
  2. 聚合规约
  3. 前后处理

一、数据处理

1、集合转Map

有时候我们需要把集合中的数据转换成Map,就像下图中的数据
image.png
我们更多的时候需要的是下面这种形式的Map
image.png

我们可以通过Java8提供的流操作来实现这种操作

上述的例子我们可以通过一句话来搞定

list.stream().collect(Collectors.toMap(Student::getId,Student::getName);

当然,如果希望得到的Mapvalue是对象本身的时候,可以这么写

list.stream().collect(Collectors.toMap(Student::getId,Function.identity())); 或者 list.stream().collect(Collectors.toMap(Student::getId, e -> e));

image.png

关于Collectors.toMap()

image.png

该方法一共三个重载方法

  1. toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper);
  2. toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper,
  3. BinaryOperator<U> mergeFunction);
  4. toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper,
  5. BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier);

主要涉及到以下四个参数

  1. keyMapper Key的映射函数
  2. valueMapper Value的映射函数
  3. mergeFunctionKey 冲突的时候,调用的合并方法(解决哈希冲突的方法)
  4. mapSupplier Map的构造器,在需要返回特定的Map的时候使用

比如说我们需要将上述的StudentList转换成HashMap
如果直接使用上面的写法,会抛出异常,因为转换的过程中 key 会出现冲突的现象

所以这个时候我们就需要把合并函数作为参数指定进去,告诉其出现哈希冲突的时候如何进行合并
假设我们现在处理冲突的方式就是保留第一个元素,
那么就可以这么写

  1. HashMap<Integer, String> map = list.stream()
  2. .collect(Collectors.
  3. toMap(Student::getId, Student::getName, (s1, s2) -> s2, HashMap::new));

image.png

程序运行的时候就把相同**key** 但是是第二个出现的元素删除掉了
image.png