对列表的去重处理,Java 8 在 Stream
接口上提供了类似于 SQL 语句那样的 distinct()
方法,不过它也只能基于对象整体比较来去重,即通过 equals/hashCode 方法。distinct
方法的功效与以往的 new ArrayList(new HashSet(books))
差不多。用起来是
List<Book> unique = book.stream().distinct().collect(Collectors.toList())
并且这种去重方式需要在模型类中同时实现 equals 和 hashCode 方法。
回到实际项目中来,我们很多时候的需求是要根据对象的某个属性来去重。比如接下来的一个实例,一个 books 列表中存在 ID 一样,name 却不同的 book, 我们认为这是重复的,所以需要根据 book 的 id 属性对行去重。在 collect 的时候用到的方法是 collectinAndThen(...)
, 下面是简单代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
import java.util.*; import static java.util.stream.Collectors.collectingAndThen; import static java.util.stream.Collectors.toCollection; public class Deduplication { public static void main(String[] args) { List<Book> books = Arrays.asList( new Book(12, "Sun Java"), new Book(12, "Oracle Java"), new Book(15, "Scala") ); List<Book> unique = books.stream().collect( collectingAndThen(toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.id))), ArrayList::new)); unique.forEach(book -> System.out.printf("book[id: %s, name: %s]\n", book.id, book.name)); } } class Book { public final Integer id; public final String name; public Book(Integer id, String name) { this.id = id; this.name = name; } } |
执行后打印出
book[id: 12, name: Sun Java]
book[id: 15, name: Scala]
成功去重,换个名照样能认出来,还不依赖于 equals/hashCode 方法。
链接: Remove duplicates from a list of objects based on property in Java 8
本文链接 https://yanbin.blog/java-8-list-deduplication-with-lambda/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
哈哈哈
可是这样子类中的成员变量就暴露出来了,无法使用private,这种要怎么解决?
Comparator.comparing(o -> o.id)
中使用 getter 方法就可以。感谢
这样就可以去重了,没有直接import
`List unique = personList.stream().collect(Collectors.collectingAndThen(
Collectors.toCollection(()->new TreeSet(Comparator.comparing(Person::getSize))),ArrayList::new ));
直接 import 什么?
我也有头像吧
简单一点呀,在外面 new 一个
Set<Integer> ids
books.stream().filter(book -> ids.add(book.getId())).collect(Collectors.toList);
如果还想过滤 name,再 new 一个 Set,然后 filter() 一次
不过这样会有 垃圾变量
filter() 过滤 id 的话每次要判断 id 存不存在
给我解决了mockito修改私有属性的问题,就是想评论一下这个神奇的博客,博主是男生还是女生呀
多谢光顾本博客,也就是一直延续了作笔记的习惯,能帮大家解决到问题,倍感荣幸。何来神奇之友,评论里就能看到我年轻时的头像啊,不可能存在性别难以分辨的问题吧。