Java8 - Stream API 将 List 集合转为 Map

时间:2025-03-26 08:15:50

文章目录

      • 1. 将List转为Map:key=userId, value=name
      • 2. 将List转为Map:key=userId, value=User对象
      • 3. 重复的 key 处理
      • 4. 将 id 和用户列表映射:groupingBy

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {

    private Integer userId;
    private String name;
    private String email;
}

1. 将List转为Map:key=userId, value=name

public class Main {
    public static void main(String[] args) {
        List<User> users = new ArrayList<>();
        users.add(new User(1, "user1", "email1@"));
        users.add(new User(2, "user2", "email2@"));
        users.add(new User(3, "user3", "email3@"));
        users.add(new User(4, "user4", "email4@"));

        Map<Integer, String> userIdAndName = users.stream().collect(Collectors.toMap(User::getUserId, User::getName));

        System.out.println(userIdAndName);
    }
}

输出:

{1=user1, 2=user2, 3=user3, 4=user4}

2. 将List转为Map:key=userId, value=User对象

public class Main {
    public static void main(String[] args) {
        List<User> users = new ArrayList<>();
        users.add(new User(1, "user1", "email1@"));
        users.add(new User(2, "user2", "email2@"));
        users.add(new User(3, "user3", "email3@"));
        users.add(new User(4, "user4", "email4@"));

        Map<Integer, User> userIdAndName = users.stream().collect(Collectors.toMap(User::getUserId, user->user));

        System.out.println(userIdAndName);
    }
}

输出:

{
    1=User(userId=1, name=user1, email=email1@), 
    2=User(userId=2, name=user2, email=email2@), 
    3=User(userId=3, name=user3, email=email3@), 
    4=User(userId=4, name=user4, email=email4@)
}

3. 重复的 key 处理

如果出现相同的key,那么会抛出重复key的异常,比如我们将userId为3的修改为2,则会和第二个用户冲突:

public class Main {
    public static void main(String[] args) {
        List<User> users = new ArrayList<>();
        users.add(new User(1, "user1", "email1@"));
        users.add(new User(2, "user2", "email2@"));
        users.add(new User(2, "user3", "email3@"));
        users.add(new User(4, "user4", "email4@"));

        Map<Integer, User> userIdAndName = users.stream().collect(Collectors.toMap(User::getUserId, user->user));

        System.out.println(userIdAndName);
    }
}

抛出异常:

Exception in thread "main" java.lang.IllegalStateException: Duplicate key User(userId=2, name=user2, email=email2@)
	at java.util.stream.Collectors.lambda$throwingMerger$113(Collectors.java:133)
	at java.util.stream.Collectors$$Lambda$3/780237624.apply(Unknown Source)
	at java.util.HashMap.merge(HashMap.java:1245)
	at java.util.stream.Collectors.lambda$toMap$171(Collectors.java:1320)
	at java.util.stream.Collectors$$Lambda$5/1560911714.accept(Unknown Source)
	at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502)
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
	at com.imooc.uua.rest.Main.main(Main.java:16)

支持第三个参数,对重复值进行选取:

public class Main {
    public static void main(String[] args) {
        List<User> users = new ArrayList<>();
        users.add(new User(1, "user1", "email1@"));
        users.add(new User(2, "user2", "email2@"));
        users.add(new User(2, "user3", "email3@"));
        users.add(new User(4, "user4", "email4@"));

        Map<Integer, User> userIdAndName = users.stream().collect(Collectors.toMap(
                User::getUserId,
                user->user,
                (oldValue,newValue)->newValue));

        System.out.println(userIdAndName);
    }
}

输出:

{
     1=User(userId=1, name=user1, email=email1@), 
     2=User(userId=2, name=user3, email=email3@), 
     4=User(userId=4, name=user4, email=email4@)
}

可以看到,只会出现 user3,而 user2 被覆盖掉了

4. 将 id 和用户列表映射:groupingBy

刚才上面出现重复的ID,是根据值进行覆盖,在某些情况下需要映射成列表。即:List -> Map<Integer, List>的情况。

public class Main {
    public static void main(String[] args) {
        List<User> users = new ArrayList<>();
        users.add(new User(1, "user1", "email1@"));
        users.add(new User(2, "user2", "email2@"));
        users.add(new User(2, "user3", "email3@"));
        users.add(new User(4, "user4", "email4@"));

        Map<Integer, List<User>> userIdAndName = users.stream().collect(Collectors.groupingBy(User::getUserId));

        System.out.println(userIdAndName);
    }
}

输出:

{
    1=[User(userId=1, name=user1, email=email1@)], 
    2=[User(userId=2, name=user2, email=email2@), 
       User(userId=2, name=user3, email=email3@)], 
    4=[User(userId=4, name=user4, email=email4@)]
}