比较两个列表并从一个列表中删除重复项
我有一个名为 FormObject 的对象,它包含两个 ArrayList - oldBooks 和 newBooks - 两者都包含 Book 对象。
oldBooks 允许包含重复的 Book 对象 newBooks 本身不允许包含重复的 Book 对象,并且不能在 oldBooks 列表中包含 Book 对象的任何重复项。
重复 Book 的定义很复杂,我无法重写 equals 方法,因为该定义在 Book 对象的所有用途中并不通用。
我计划在 FormObject 类上有一个名为removeDuplicateNewBooks 的方法,它将执行上述功能。
您将如何实施这一点?我的第一个想法是使用 HashSets 来消除重复项,但无法覆盖 Book 对象上的 equals 意味着它不起作用。
I have an object called FormObject that contains two ArrayLists - oldBooks and newBooks - both of which contain Book objects.
oldBooks is allowed to contain duplicate Book objects
newBooks is not allowed to contain duplicate Book objects within itself and cannot include any duplicates of Book objects in the oldBooks list.
The definition of a duplicate Book is complex and I can't override the equals method as the definition is not universal across all uses of the Book object.
I plan to have a method on the FormObject class called removeDuplicateNewBooks which will perform the above functionality.
How would you go about implementing this? My first thought was to use HashSets to eliminate the duplicates but not being able to override equals on the Book object means it won't work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以使用
TreeSet
与自定义Comparator
:Comparator
构造TreeSet
您想要使用的自定义逻辑set.addAll(bookList)
现在
Set
仅包含唯一的书籍。You can use a
TreeSet
with a customComparator<Book>
:TreeSet
with aComparator
implementing the custom logic you wantset.addAll(bookList)
Now the
Set
contains only unique books.为了使新书独一无二:
围绕 Book 创建一个包装类,并根据所包含的书对象声明它的 equals / hashCode 方法:
编辑:
优化了 equals 和 hashCode,修复了 hashCode 的 bug。
现在使用集合来删除重复项:(
但是当然,带有自定义比较器的 TreeSet 答案更优雅,因为您可以使用 Book 类本身)
编辑:
(删除了对 apache commons 的引用,因为我改进的 equals / hashCode 方法更好)
For making the new books unique:
Create a wrapper class around Book and declare it's equals / hashCode methods based on the enclosed book object:
EDIT:
Optimized equals and hashCode and fixed a bug in hashCode.
Now use a set to remove duplicates:
(But of course the TreeSet answer with the custom comparator is more elegant because you can use the Book class itself)
EDIT:
(removed reference to apache commons because my improved equals / hashCode methods are better)
HashingStrategy 是您正在寻找的概念。它是一个策略接口,允许您定义 equals 和 hashcode 的自定义实现。
Eclipse Collections 包括哈希表以及基于哈希策略的迭代模式。首先,您需要创建自己的
HashingStrategy
来回答两本Books
是否相等。接下来,您将使用
distinct()
删除newBooks
中的重复项,并使用UnifiedSetWithHashingStrategy
消除列表中的重复项。distinct()
方法根据哈希策略仅返回唯一项。它返回一个列表,而不是一个集合,保留原始顺序。根据相同的哈希策略,对reject()
的调用返回另一个新列表,其中不包含该集合包含的元素。如果您可以更改 newBooks 以实现 Eclipse Collections 接口,那么您可以直接调用
distinct()
方法。注意:我是 Eclipse Collections 的提交者。
HashingStrategy is the concept you're looking for. It's a strategy interface that allows you to define custom implementations of equals and hashcode.
Eclipse Collections includes hash tables as well as iteration patterns based on hashing strategies. First, you'd create your own
HashingStrategy
to answer whether twoBooks
are equal.Next, you'd use
distinct()
to remove duplicates withinnewBooks
and aUnifiedSetWithHashingStrategy
to eliminate duplicates across the lists.The
distinct()
method returns only the unique items according to the hashing strategy. It returns a list, not a set, preserving the original order. The call toreject()
returns another new list without the elements that the set contains, according to the same hashing strategy.If you can change newBooks to implement an Eclipse Collections interface, then you can call the
distinct()
method directly.Note: I am a committer for Eclipse Collections.