Is there a no-duplicate List implementation out there?
So here's what I did eventually. I hope this helps someone else.
class NoDuplicatesList<E> extends LinkedList<E> {
@Override
public boolean add(E e) {
if (this.contains(e)) {
return false;
}
else {
return super.add(e);
}
}
@Override
public boolean addAll(Collection<? extends E> collection) {
Collection<E> copy = new LinkedList<E>(collection);
copy.removeAll(this);
return super.addAll(copy);
}
@Override
public boolean addAll(int index, Collection<? extends E> collection) {
Collection<E> copy = new LinkedList<E>(collection);
copy.removeAll(this);
return super.addAll(index, copy);
}
@Override
public void add(int index, E element) {
if (this.contains(element)) {
return;
}
else {
super.add(index, element);
}
}
}
Here is what I did and it works.
Assuming I have an ArrayList
to work with the first thing I did was created a new LinkedHashSet
.
LinkedHashSet<E> hashSet = new LinkedHashSet<E>()
Then I attempt to add my new element to the LinkedHashSet
. The add method does not alter the LinkedHasSet
and returns false if the new element is a duplicate. So this becomes a condition I can test before adding to the ArrayList
.
if (hashSet.add(E)) arrayList.add(E);
This is a simple and elegant way to prevent duplicates from being added to an array list. If you want you can encapsulate it in and override of the add method in a class that extends the ArrayList
. Just remember to deal with addAll
by looping through the elements and calling the add method.
There's no Java collection in the standard library to do this. LinkedHashSet<E>
preserves ordering similarly to a List
, though, so if you wrap your set in a List
when you want to use it as a List
you'll get the semantics you want.
Alternatively, the Commons Collections (or commons-collections4
, for the generic version) has a List
which does what you want already: SetUniqueList
/ SetUniqueList<E>
.