Eric’s post about the LinkedHashSet got me thinking about some code I’ve recently written to provide an ArrayList that operates like a set. I wasn’t aware of the LinkedHashSet, but I think I implemented something with similar functionality called a UniqueArrayList. It looks very simple:
public class UniqueArrayListextends ArrayList { /** * Only add the object if there is not * another copy of it in the list */ public boolean add(T obj) { for (int i = 0; i < size(); i++) { if (obj.equals(get(i))) { return false; } } return super.add(obj); } public boolean addAll(Collection extends T> c) { boolean result = true; for (T t : c) { if (!add(t)) { result = false; } } return result; } }
I wanted a List that would only allow an object to be added to itself if there were not another duplicate within, and this completed that objective. When I decided to write this code, I remember trying to decide whether I wanted to make a List unique or provide order to a Set. I guess the Java API has already provided order to a set with their LinkedHashSet, so maybe I should get rid of this object and replace all of them with LinkedHashSets.
I also create a UniqueOverridingList that would actually override equal objects as they were added. This was useful when I needed to process a lot of objects, but only keep the latest version of the object as I was processing.
public class UniqueOverridingListextends ArrayList { public enum LAST_RESULT { ADD, OVERRIDE, NOTHING; } private LAST_RESULT lastResult; public boolean add(T obj) { for (int i = 0; i < size(); i++) { if (obj.equals(get(i))) { set(i, obj); lastResult = LAST_RESULT.OVERRIDE; return true; } } boolean b = super.add(obj); if (b) { lastResult = LAST_RESULT.ADD; } else { lastResult = LAST_RESULT.NOTHING; } return b; } public boolean addAll(Collection extends T> c) { boolean result = true; for (T t : c) { if (!add(t)) { result = false; } } return result; } public LAST_RESULT getLastResult() { return lastResult; } }
After waiting and reading the comments on Eric’s blog, I see that my classes may act more accordingly if I add the equals() and hashcode() methods to them. The equals method should take an incoming List and compare it element by element to the current list.
