【问题标题】:How to handle exception while duplicate in map with Lamda [duplicate]使用 Lambda 在地图中重复时如何处理异常 [重复]
【发布时间】:2019-12-28 00:13:18
【问题描述】:

如何在使用 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


    【解决方案1】:

    您可以使用Collectors.toMap 的重载版本,它从Java Docs 中获取第三个参数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), 有两个重复项,因此当从 Person 流创建 Map 时会出现合并错误,因为这两个对象的键相同.如果提供了第三个参数 mergeFunction,则说明如何解决合并错误。

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

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

    【讨论】:

    • 能否请您详细说明“Person::getName,Person::getAge, (p1, p2) -> p2)”
    • @shiv 添加了一些解释
    猜你喜欢
    • 2018-01-03
    • 2020-05-20
    • 2019-01-19
    • 1970-01-01
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    • 2021-04-13
    • 1970-01-01
    相关资源
    最近更新 更多