JAVA8: stream中Collections.toMap()

查看源码会发现toMap()有三个方法:图方便我标记为①②③
参数分别是2个,3个,4个。
在这里插入图片描述
第一个方法示例:
将一个list对象 处理成一个 map<Integer, String>

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

阐述的不是很完善,自己通过代码能够更全面的了解!

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java 8的Collectors.toMap方法可以将Stream的元素转换为一个Map对象。该方法有三个参数:keyMapper,valueMapper和mergeFunction。其,keyMapper用于将Stream的元素转换为Map的key,valueMapper用于将Stream的元素转换为Map的value,mergeFunction用于处理当key重复时的冲突情况。 下面是一个例子,假设我们有一个List对象,其包含多个Person对象,每个Person对象都有一个唯一的id属性和一个name属性。我们可以使用Collectors.toMap方法将List转换为一个以id为key,以Person对象为value的Map对象: ```java List<Person> personList = new ArrayList<>(); // 假设我们已经将多个Person对象添加到了personList Map<Integer, Person> personMap = personList.stream() .collect(Collectors.toMap(Person::getId, Function.identity())); ``` 在上面的例子,Person::getId表示将Person对象的id属性作为Map的key,Function.identity()表示将Person对象本身作为Map的value。如果我们想要将Person对象的name属性作为Map的value,可以这样写: ```java Map<Integer, String> personMap = personList.stream() .collect(Collectors.toMap(Person::getId, Person::getName)); ``` 如果我们的List有重复的id,那么上面的代码将会抛出IllegalStateException异常。为了避免这种情况,我们可以使用mergeFunction参数来处理冲突。例如,如果我们想要将重复的id的Person对象合并为一个List,可以这样写: ```java Map<Integer, List<Person>> personMap = personList.stream() .collect(Collectors.toMap(Person::getId, Collections::singletonList, (list1, list2) -> { List<Person> resultList = new ArrayList<>(list1); resultList.addAll(list2); return resultList; })); ``` 在上面的代码Collections::singletonList表示将Person对象转换为只包含一个元素的List,mergeFunction参数则表示将两个List合并为一个List。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值