如何使用Java Stream将User列表转换为含SSNs、IDs双键的列表值Map
问题:将User列表转换为包含SSNs和IDs的Map
我有一个User(id, ssn, name)类型的列表,需要把它转换成包含两个键("SSNs"、"IDs")的Map,其中"SSNs"对应SSN字符串列表,"IDs"对应ID整数列表。
示例输入
List.of(new User(1, "ssn1", "user1"), new User(2, "ssn2", "user2"), new User(3, "ssn3", "user3"))
期望输出
Map with 2 keys("SSNs","IDs") and list as value "SSNs" - List("ssn1","ssn2","ssn3") "IDs" - List(1,2,3)
当前代码
public class Test { public static void main(String[] args) { List<User> users = List.of(new User(1, "ssn1", "user1"), new User(2, "ssn2", "user2"), new User(3, "ssn3", "user3")); Map<String, List<Object>> userMap = users.stream().collect(Collectors.groupingBy(User::getSsn)); } } class User { public int getId() { return id; } public String getSsn() { return ssn; } public String getName() { return name; } int id; String ssn; String name; public User(int id, String ssn, String name) { this.id = id; this.ssn = ssn; this.name = name; } }
**更新:**已将List<User>更新为List<Object>。
解决方案
当前代码使用Collectors.groupingBy(User::getSsn)是按SSN值分组,得到的是键为SSN、值为对应User列表的Map,和需求不符。以下是几种符合需求的实现方式:
方法一:手动遍历构建Map(兼容所有Java版本)
最直观的方式,遍历一次列表填充两个集合后放入Map:
public static void main(String[] args) { List<User> users = List.of(new User(1, "ssn1", "user1"), new User(2, "ssn2", "user2"), new User(3, "ssn3", "user3")); Map<String, List<Object>> userMap = new HashMap<>(); List<Object> ids = new ArrayList<>(); List<Object> ssns = new ArrayList<>(); for (User user : users) { ids.add(user.getId()); ssns.add(user.getSsn()); } userMap.put("IDs", ids); userMap.put("SSNs", ssns); // 验证输出 System.out.println(userMap); }
方法二:两次Stream收集(Java 8+)
写法简洁,通过两次Stream分别收集ID和SSN列表:
public static void main(String[] args) { List<User> users = List.of(new User(1, "ssn1", "user1"), new User(2, "ssn2", "user2"), new User(3, "ssn3", "user3")); Map<String, List<Object>> userMap = new HashMap<>(); userMap.put("IDs", users.stream().map(User::getId).collect(Collectors.toList())); userMap.put("SSNs", users.stream().map(User::getSsn).collect(Collectors.toList())); System.out.println(userMap); }
方法三:使用Collectors.teeing单次遍历(Java 12+)
通过teeing收集器在一次Stream遍历中同时完成两种收集,效率更高:
public static void main(String[] args) { List<User> users = List.of(new User(1, "ssn1", "user1"), new User(2, "ssn2", "user2"), new User(3, "ssn3", "user3")); Map<String, List<Object>> userMap = users.stream() .collect(Collectors.teeing( Collectors.mapping(User::getId, Collectors.toList()), Collectors.mapping(User::getSsn, Collectors.toList()), (ids, ssns) -> { Map<String, List<Object>> map = new HashMap<>(); map.put("IDs", ids); map.put("SSNs", ssns); return map; } )); System.out.println(userMap); }
内容的提问来源于stack exchange,提问作者Jericho
相关产品推荐
相关产品推荐

