为什么 copy 下来运行就报错,空指针,不清楚在网上的例子是怎么跑的
studentList = studentList.stream().collect(
Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getName))), ArrayList::new));
不知道为啥 string 类型字段就报错空指针,int 没错。
就是为了要去重重复对象,重复对象的判断条件是某个字段的值相同。找了好多都是这么写的,但是一跑就报错。很神奇。
1
AoEiuV020CN 2022-07-06 16:34:01 +08:00
最好上个完整一点点的代码,
然后是哪个对象在哪里空了,期望是什么, 这里 stream 可读性很糟糕,不如 for 循环,或者 addAll , |
2
luxinfl OP @AoEiuV020CN 我搞出来了,tm 是别人传的数据有问题。。一个列表里面有个对象搞错字段了。。。
|
3
nothingistrue 2022-07-06 17:04:09 +08:00
原理是,利用 Set 不允许添加重复元素的特性(添加重复元素时忽略,不是报错)来去重。具体操作是,将当前集合的所有元素尝试全部放入一个 Set 中(用哪个 Set 的实现类取决于如何判重),然后在将完成的 Set 转换回原来的集合,在将元素放入到 Set 中的时候,重复元素会被排除掉。但是你抄这段代码可读性是真特么差。
|
4
nothingistrue 2022-07-06 17:13:24 +08:00
尝试换一种写法:
studentList = new TreeSet<>(Comparator.comparing(Student::getName)).addAll(studentList).stream().collect(Collectors.toList()) |
5
zhuangzhuang1988 2022-07-06 17:20:00 +08:00
还是写简单的 foreach 吧
这样看真难看懂 《 effective java 》里也有 stream 的讨论,不要无脑 stream |
6
codingadog 2022-07-06 17:21:01 +08:00
数据量不大的话不如直接 removeIf 。
Set<String> tmp = new HashSet<>(); studentList.removeIf(student -> !tmp.add(student.getName())); |
7
Leviathann 2022-07-06 17:23:00 +08:00
换个库把,stream 除了 parallel 功能,其他完全没 eclipse collection 好用,性能也不如,java 官方的视频都说 eclipse collection 的抽象程度更高且性能也更好
|
8
nothingistrue 2022-07-06 17:28:09 +08:00
好吧,我写错了,addAll 不能链式操作,要想一句代码就完成的话,只能使用原先那段很难看的代码。为了可读性建议拆分语句如下:
TreeSet<Student> tempSet = new TreeSet<>(Comparator.comparing(Student::getName)); tempSet.addAll(studentList); studentList = new ArrayList(tempSet); // 或者 studentList = tempSet.stream().collect(Collectors.toList()); |
9
xinhochen 2022-07-06 17:42:20 +08:00
我觉得这样写更容易理解一些:
Set<String> filter = new HashSet<>(); List<Student> result = studentList.stream().filter(o -> filter.add(o.getName())).collect(Collectors.toList()); |
10
rpish 2022-07-06 17:45:58 +08:00
好奇问下,大家项目开发中 stream 用得多吗?
|
11
Red998 2022-07-06 17:55:44 +08:00 1
用的很多 jdk8 stream 流用的很多
|
12
chendy 2022-07-06 18:04:08 +08:00
studentList = new ArrayList<>(new HashSet<>(studentList));
|
13
mazai 2022-07-06 18:06:20 +08:00
只是因为 students 中 name 有 null 的学生吧。 还有只是去重不用这么麻烦,重写 Student 对象的 hashcode 和 equals 方法,studentList.stream().distinct().collect(Collectors.toList()); 就行了
|
14
git00ll 2022-07-06 18:41:46 +08:00
这么写可读性贼差
|
15
golangLover 2022-07-06 19:22:15 +08:00 via Android
@mazai 同意有 null 的解释
但不同意重写 equal. 可能我只是需要比较这个属性一次 |
16
potatowish 2022-07-06 19:28:24 +08:00 via iPhone
@git00ll 可以抽一个常用的方法出来,每次这么写一堆确实难受
|
17
lmshl 2022-07-06 21:42:24 +08:00
|
18
wolfie 2022-07-07 11:32:55 +08:00
骚操作 new ArrayList(toMap(getName()).values())
|
19
Anshay 2022-07-07 11:39:39 +08:00
直接 studentList.stream().distinct.toCollect.....即可,前提是有自己编写了 studentList 中的 equals 方法和 hashCode 方法。
|
20
mazai 2022-07-07 14:19:56 +08:00
@golangLover equals 和 hashcode 具体选取哪些字段重写还是看业务,哪几个字段能代表学生的唯一性,那就重写哪几个字段
|
21
issakchill 2022-07-07 14:46:29 +08:00
streamEx 有些方法还挺好用的 也自带根据某字段去重的方法
|
22
golangLover 2022-07-08 21:29:58 +08:00 via Android
@mazai 。。你是不可能一两次比较就重写字段的
|