Unique ArrayList

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 UniqueArrayList extends 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 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 UniqueOverridingList extends 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 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.

This entry was posted in Uncategorized and tagged , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*
Check out the latest GroovyMag to see an interview with me about the 1.1 release of GrailsUI: