首页 > 解决方案 > 使用Lamda在地图中复制时如何处理异常

问题描述

如何在使用 Lamda 复制地图时处理异常。

List<Person> person = Arrays.asList(
                new Person("Charles","Dickens",60),
                new Person("Dickens","Charles",60),
                new Person("Lewis","Charles",60),
                new Person("Charles","Dickens",60),
                new Person("abc","abc",20));;

            //applying toMap to collect 
        Map<Object, Object> peronMap = person.stream().limit(5)
                        .collect(Collectors.toMap(Person::getName,Person::getAge));

        System.out.println(peronMap);

这是我的清单

但我收到一个错误

Exception in thread "main" java.lang.IllegalStateException: Duplicate key 60
    at java.util.stream.Collectors.lambda$throwingMerger$0(Unknown Source)
    at java.util.HashMap.merge(Unknown Source)
    at java.util.stream.Collectors.lambda$toMap$58(Unknown Source)
    at java.util.stream.ReduceOps$3ReducingSink.accept(Unknown Source)
    at java.util.stream.SliceOps$1$1.accept(Unknown Source)
    at java.util.Spliterators$ArraySpliterator.tryAdvance(Unknown Source)
    at java.util.stream.ReferencePipeline.forEachWithCancel(Unknown Source)
    at java.util.stream.AbstractPipeline.copyIntoWithCancel(Unknown Source)

标签: java-8

解决方案


您可以使用从Java DocsCollectors.toMap获取第三个参数的重载版本:mergeFunction

如果映射的键包含重复项(根据 Object.equals(Object)),则将值映射函数应用于每个相等的元素,并使用提供的合并函数合并结果。

Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                Function<? super T, ? extends U> valueMapper,
                                BinaryOperator<U> mergeFunction)

如果存在重复键,则 BinaryOperator 的第三个参数解决合并错误:

Map<Object, Object> peronMap = person.stream().limit(5)
                    .collect(Collectors.toMap(Person::getName,
                                              Person::getAge, 
                                              (age1, age2) -> age2));

在上面的代码中,最后一个参数是BinaryOperator如果存在重复键,则采用第二个值并忽略第一个值。

例如,在您的数据中,有两个重复项new Person("Dickens","Charles",60)new Person("Charles","Dickens",60),因此当Map从流中创建时Person,会出现合并错误,因为这两个对象的键相同。如果提供了第三个参数 a mergeFunction,则说明如何解决合并错误。

在我的示例代码中,如果有两个具有相同名称的键,它将采用第二个值。

如果数据是: new Person("Charles","Dickens",60)并且new Person("Charles","Dickens",61),键是相同的Charles,但是如果您使用我的代码,61则将考虑第二个值,并且60将在 final 中丢弃第一个值Map


推荐阅读