List 转 Map 之 Collectors.toMap()

@Data
public class User {
// 用户ID
private long id;

// 用户名称
private String name;

public User(long id, String name) {
this.id = id;
this.name = name;
}
}


/**
* List 转 Map 之 Collectors.toMap()
*/
public class ToMapDemo {

public static void main(String[] args) {

List<User> users = Arrays.asList(
new User(101, "Jack"),
new User(102, "Kreas"),
new User(103, "Marry"),
new User(104, "Timi"),
new User(105, "Alice"));

// 1. 在该 List 集合中找出 id = 102,id =104 这两个用户的话。

User user102 = null;
User user104 = null;

//常规方法
for (User user : users) {
if (user.getId() == 102){
user102 = user;
}

if (user.getId() == 104){
user104 = user;
}
}

System.out.println("id = 102 的用户 : " + JSON.toJSONString(user102));
System.out.println("id = 104 的用户 : " + JSON.toJSONString(user104));
System.out.println("------------------------------------------------");

//2.把 List 转成 以 id 为键,对象为值的方式存于Map中。
HashMap<Long, User> userMap = new HashMap<>();
for (User user : users) {
userMap.put(user.getId(),user);
}
System.out.println("id = 102 的用户 : " + JSON.toJSONString(userMap.get(102L)) );
System.out.println("id = 104 的用户 : " + JSON.toJSONString(userMap.get(104L)) );

System.out.println("------------------------------------------------");

//【2】引入 Collectors.toMap()
//Java8 中,list 转 map
// 利用 Java 8 stream 特性对集合进行操作,最后采用 Collectors.toMap() 将List 转为 Map。

Map<Long, User> collect =
users.stream().collect(Collectors.toMap(User::getId, x -> x));

System.out.println("id = 102 的用户 : " + JSON.toJSONString(userMap.get(102L)) );
System.out.println("id = 104 的用户 : " + JSON.toJSONString(userMap.get(104L)) );

System.out.println("代码看起来就精简了许多,从最初的13行代码变化到6行代码,再到最后的3行代码。");
System.out.println("------------------------------------------------");


//推展 :
//【3.1】常见方式:
// 1. List 转 Map,值为对象:
Map<Long, User> collect1 = users.stream().collect(Collectors.toMap(User::getId, x -> x));
//2.List 转 Map,值为属性:
Map<Long, String> collect2 = users.stream().collect(Collectors.toMap(User::getId, x -> x.getName()));
Map<Long, String> collect22 = users.stream().collect(Collectors.toMap(User::getId, User::getName));
//3.List 转 Map,值为属性,且二次加工:
// 姓名值后面统一加上一个 "_OK"字符
Map<Long, String> collect3 = users.stream().collect(Collectors.toMap(User::getId, x -> x.getName() + "_OK"));

System.out.println("collect1 : " + JSON.toJSONString(collect1));
System.out.println("collect2 : " + JSON.toJSONString(collect2));
System.out.println("collect22 : " + JSON.toJSONString(collect22));
System.out.println("collect3 : " + JSON.toJSONString(collect3));
System.out.println("------------------------------------------------");


// 【3.2】注意事项:
// 1. map 中的 key 值不能重复
List<User> users2 = Arrays.asList(
new User(101, "Jack"),
new User(102, "Kreas"),
new User(104, "Marry"),
new User(104, "Timi"),
new User(105, "Alice"));
//id不重复情况
Map<Long, String> collect4 = users.stream().collect(Collectors.toMap(User::getId, User::getName));
// 新的集合 users2 id 103改为104 id重复情况
/**
* 抛出异常
* java.lang.IllegalStateException: Duplicate key 104 (attempted merging values Marry and Timi)
* Map的 key不能为重复的
*/
// Map<Long, String> collect5 = users2.stream().collect(Collectors.toMap(User::getId, User::getName));
System.out.println("collect3 : " + JSON.toJSONString(collect4));
// System.out.println("collect3 : " + JSON.toJSONString(collect5));
System.out.println("------------------------------------------------");

// 异常解决办法
// 解决办法 :1 在 Collectors.toMap() 方法里增加一个 Lamda表达式 发现有重复直接用第一个值
Map<Long, User> collect55 = users2.stream().collect(Collectors.toMap(User::getId,
u -> u, (x, y) -> x));
System.out.println("collect3 : Timi没有输出 : " + JSON.toJSONString(collect55));

// 采用覆盖原则,如果发现一个有重复的键,则自动覆盖之前值
Map<Long, User> collect6 = users2.stream().collect(Collectors.toMap(User::getId,
u -> u, (x, y) -> y));
System.out.println("collect3 : Marry没有输出 : " + JSON.toJSONString(collect6));
// 唯一的区别就是选择的取值不同,没错,如果要想保留前面的数据就取参数1,要想保留后面的数据就取参数2。
System.out.println("------------------------------------------------");

// 当 Map值的类型是String类型,我们可以将所有ID相同的值连接,然后存放于Map中
// 当 Timi 和 Marry 都想保留的时候
Map<Long, String> collect7 = users2.stream().collect(Collectors.toMap(User::getId,
o -> o.getName(), (x, y) -> x + "," + y));
System.out.println("collect3 : Marry没有输出 : " + JSON.toJSONString(collect7));
System.out.println("------------------------------------------------");

// 值不能为空 情况
//如果存在值为null 的情况 抛出 java.lang.NullPointerException
List<User> users3 = Arrays.asList(
new User(101, "Jack"),
new User(102, "Kreas"),
new User(103, "Marry"),
new User(104, "Timi"),
new User(105, null));
// Map<Long, String> collect8 = users3.stream().collect(Collectors.toMap(User::getId,
// User::getName));
// System.out.println("collect8 : 抛出空指针 : " + JSON.toJSONString(collect8));

// 解决办法 : 将null值默认为空字符串
Map<Long, String> collect9 = users3.stream().collect(Collectors.toMap(User::getId,
o -> {
String str = o.getName() == null ? "" : o.getName();
return str;
}));

System.out.println("collect9 : : " + JSON.toJSONString(collect9));

}

}


结果:

id = 102 的用户 : {"id":102,"name":"Kreas"}
id = 104 的用户 : {"id":104,"name":"Timi"}
------------------------------------------------
id = 102 的用户 : {"id":102,"name":"Kreas"}
id = 104 的用户 : {"id":104,"name":"Timi"}
------------------------------------------------
id = 102 的用户 : {"id":102,"name":"Kreas"}
id = 104 的用户 : {"id":104,"name":"Timi"}
代码看起来就精简了许多,从最初的13行代码变化到6行代码,再到最后的3行代码。
------------------------------------------------
collect1 : {101:{"id":101,"name":"Jack"},102:{"id":102,"name":"Kreas"},103:{"id":103,"name":"Marry"},104:{"id":104,"name":"Timi"},105:{"id":105,"name":"Alice"}}
collect2 : {101:"Jack",102:"Kreas",103:"Marry",104:"Timi",105:"Alice"}
collect22 : {101:"Jack",102:"Kreas",103:"Marry",104:"Timi",105:"Alice"}
collect3 : {101:"Jack_OK",102:"Kreas_OK",103:"Marry_OK",104:"Timi_OK",105:"Alice_OK"}
------------------------------------------------
collect3 : {101:"Jack",102:"Kreas",103:"Marry",104:"Timi",105:"Alice"}
------------------------------------------------
collect3 : Timi没有输出 : {101:{"id":101,"name":"Jack"},102:{"id":102,"name":"Kreas"},104:{"id":104,"name":"Marry"},105:{"id":105,"name":"Alice"}}
collect3 : Marry没有输出 : {101:{"id":101,"name":"Jack"},102:{"id":102,"name":"Kreas"},104:{"id":104,"name":"Timi"},105:{"id":105,"name":"Alice"}}
------------------------------------------------
collect3 : Marry没有输出 : {101:"Jack",102:"Kreas",104:"Marry,Timi",105:"Alice"}
------------------------------------------------
collect9 : : {101:"Jack",102:"Kreas",103:"Marry",104:"Timi",105:""}

Process finished with exit code 0

posted @ 2021-08-09 11:46  逆水涵  阅读(681)  评论(0)    收藏  举报