Stream超级好,Map也很酷,但一定要答应我别用toMap()
共 7531字,需浏览 16分钟
·
2024-07-04 08:00
因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享
点击关注#互联网架构师公众号,领取架构师全套资料 都在这里
上一篇:2T架构师学习资料干货分享
JDK 8
中 Java
引入了让人欲罢不能的 stream
流处理,可以说已经成为了我日常开发中不可或缺的一部分。
collect(Collectors.toList())
或者 collect(Collectors.toSet())
。你可能会想,toList
和 toSet
都这么便捷顺手了,当又怎么能少得了 toMap()
呢。
答应我,一定打消你的这个想法,否则这将成为你噩梦的开端(开玩笑,为了节目效果)。
让我们先准备一个用户实体类。
@Data
@AllArgsConstructor
public class User {
private int id;
private String name;
}
假设有这么一个场景,你从数据库读取 User
集合,你需要将其转为 Map
结构数据,key
和 value
分别为 user
的 id
和 name
。
很快,你啪的一下就写出了下面的代码:
public class UserTest {
@Test
public void demo() {
List<User> userList = new ArrayList<>();
// 模拟数据
userList.add(new User(1, "Alex"));
userList.add(new User(1, "Beth"));
Map<Integer, String> map = userList.stream()
.collect(Collectors.toMap(User::getId, User::getName));
System.out.println(map);
}
}
运行程序,你已经想好了开始怎么摸鱼,结果啪的一下 IllegalStateException
报错就拍你脸上,你定睛一看怎么提示 Key
值重复。
作为优秀的八股文选手,你清楚的记得 HashMap
对象 Key
重复是进行替换。你不信邪,断点一打,堆栈一看,硕大的 uniqKeys
摆在了面前,凭借四级 424
分的优秀战绩你顿时菊花一紧,点开一看,谁家好人 map key
还要去重判断啊。
好好好,这么玩是吧,你转身打开浏览器一搜,原来需要自己手动处理重复场景,啪的一下你又重新改了一下代码:
public class UserTest {
@Test
public void demo() {
List<User> userList = new ArrayList<>();
// 模拟数据
userList.add(new User(1, "Alex"));
userList.add(new User(2, null));
Map<Integer, String> map = userList.stream()
.collect(Collectors.toMap(User::getId, User::getName, (oldData, newData) -> newData));
System.out.println(map);
}
}
再次执行程序,你似乎已经看到知乎的摸鱼贴在向你招手了,结果啪的一下 NPE
又拍在你那笑容渐渐消失的脸上。
public class UserTest {
@Test
public void demo() {
List<User> userList = new ArrayList<>();
// 模拟数据
userList.add(new User(1, "Alex"));
userList.add(new User(1, "Beth"));
userList.add(new User(2, null));
Map<Integer, String> map = userList.stream()
.collect(Collectors.toMap(
User::getId,
it -> Optional.ofNullable(it.getName()).orElse(""),
(oldData, newData) -> newData)
);
System.out.println(map);
}
}
优雅,真是太优雅了,又是 Stream
又是 Optional
,可谓是狠狠拿捏技术博文的 G
点了。
TM
不是一个循环就万事大吉了吗,不信邪的你回归初心,回归了 for
循环的怀抱,又写了一版。
public class UserTest {
@Test
public void demo() {
List<User> userList = new ArrayList<>();
// 模拟数据
userList.add(new User(1, "Alex"));
userList.add(new User(1, "Beth"));
userList.add(new User(2, null));
Map<Integer, String> map = new HashMap<>();
userList.forEach(it -> {
map.put(it.getId(), it.getName());
});
System.out.println(map);
}
}
for
循环,换上 Stream
与 Optional
不羁的外衣,安心的提交了代码,这口细糠一定也要让好同事去尝一尝。
就这,你就要抛弃 toMap?你这让设计 toMap 的人,脸往哪搁。
解决的办法有很多,其中最简单的之一就是,给它第三个合并参数,解决冲突。因为Collectors.toMap
这个方法其实是有三个参数的,第一个是key
,第二个是value
,第三个是发生冲突的合并规则。默认采用的就是冲突之后抛出异常的处理。
最后,关注公众号互联网架构师,在后台回复:2T,可以获取我整理的 Java 系列面试题和答案,非常齐全。
如果这篇文章对您有所帮助,或者有所启发的话,帮忙扫描上方二维码关注一下,您的支持是我坚持写作最大的动力。