查看源码会发现toMap()有三个方法:图方便我标记为①②③
参数分别是2个,3个,4个。
第一个方法示例:
将一个list对象 处理成一个 map
Map<Integer, String> map = list.stream()
.collect(Collectors.toMap(Person::getId, Person::getName));
一般情况下是没有问题的,但是当list中存在重复对象时,就有问题了,以下为①源码:
public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
}
private static <T> BinaryOperator<T> throwingMerger() {
return (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); };
}
可以看到①tomap方法调用的是③tomap方法,第三个参数是一个函数,第四个是放入的Map。
接下来看③方法源码:
public static <T, K, U, M extends Map<K, U>>
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction,
Supplier<M> mapSupplier) {
BiConsumer<M, T> accumulator
= (map, element) -> map.merge(keyMapper.apply(element),
valueMapper.apply(element), mergeFunction);
return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
}
其中有个merge()方法,如果有key重复,就按照函数方法走,那么①tomap方法只有两参数,函数方法是源码定的,就是throwingMerger(),这段代码就是抛个异常。
所以。。。。。用Collectors.toMap()的第一个方法处理重复值的时候会抛异常。
那怎么处理呢,就是将遇到重复值时的换一个函数处理。②方法就派上用场了。
Map<Integer, String> map = list.stream()
.collect(Collectors.toMap(Person::getId, Person::getName,(oldValue, newValue) -> newValue));
如果遇上重复值,使用新的value进行替换。
如果还需要排序输出就需要用上③方法,放到指定类型LinkedHashMap中
Map<Integer, String> map = list.stream().sorted(Map.Entry.comparingByKey())
.collect(Collectors.toMap(Person::getId, Person::getName,(oldValue, newValue) -> newValue),LinkedHashMap::New);
阐述的不是很完善,自己通过代码能够更全面的了解!