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.
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.
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)
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.