Collectors.toMap Duplicate key problem of Stream in Java8

1.Background

When the project was deployed, the compilation passed, but it never ran. After seeing the error log, I found:
Insert image description here

Caused by: java.lang.IllegalStateException: Duplicate key TaxiCarpoolCommonConfig

Error code:

Map<String, TaxiCarpoolCommonConfig> taxiCarpoolConfigMap = configList.stream().collect(Collectors.toMap(TaxiCarpoolCommonConfig::getRouteId, e -> e));

The reason is that when I use stream to convert the list into a Map, one of the RouteIds is repeated, causing a conversion error.

2.Cause analysis

Let’s look directly at the specific implementation of toMap:
Insert image description here

You can see that the currently called toMap method has two parameters

1.keyMapper:Key 的映射函数。
2.valueMapper:Value 的映射函数。
3.mergeFunction:当 Key 冲突时,调用的合并方法。
4.mapSupplier:Map 构造器,在需要返回特定的 Map 时使用。`

The toMap method mainly merges through the merge method.
Insert image description here

The merge method will determine whether the same key exists. If it exists, an exception will be thrown.
Insert image description here

3.Solution

If your business requires that keys must never be repeated, you can include it in the try catch code block during operation and use exception logic.

    public static void main(String[] args) {
    
    
        List<User> list = Arrays.asList(
                User.builder().id(1).name("张三").build(),
                User.builder().id(2).name("李四").build(),
                User.builder().id(2).name("王五").build()
        );
        try {
    
    
            Map<Integer, User> map = list.stream().collect(Collectors.toMap(User::getId, e -> e));
            System.out.println(map);
        }catch (Exception e){
    
    
            System.out.println("兜底逻辑");
        }
    }

If repetition is allowed, just pick one of the repeated scenarios and pass

Map<Integer, User> map = list.stream().collect(Collectors.toMap(User::getId, e -> e,(a,b)->a));

The way to take the first

Before adding:

    public static void main(String[] args) {
    
    
        List<User> list = Arrays.asList(
                User.builder().id(1).name("张三").build(),
                User.builder().id(2).name("李四").build(),
                User.builder().id(2).name("王五").build()
        );
        Map<Integer, User> map = list.stream().collect(Collectors.toMap(User::getId, e -> e));
        System.out.println(map);
    }

Insert image description here

After adding:

    public static void main(String[] args) {
    
    
        List<User> list = Arrays.asList(
                User.builder().id(1).name("张三").build(),
                User.builder().id(2).name("李四").build(),
                User.builder().id(2).name("王五").build()
        );
        Map<Integer, User> map = list.stream().collect(Collectors.toMap(User::getId, e -> e, (a, b) -> a));
        System.out.println(map);
    }

Insert image description here

Guess you like

Origin blog.csdn.net/zhiyikeji/article/details/134717861