IndexedList: A hybrid of a Java List and a Map

If been working on legacy data import code in the last months with a lot of code searching for exisiting objects in lists. I realized I needed a different collection to speed up searching for identifiers and couldn’t find any standard collection that matches my needs. I basically need an index like Maps.uniqueIndex() from the Google Collections Library provides but it should be updating dynamically and not only be generated once.

To summarize my requirements:

  • A List (ArrayList) which can be modified as usual
  • A way to find objects (contains and get) in constant time by a custom attribute (like a HashMap)
  • No reliance on equals() and hashcode() because they cover more attributes (an can not be changed)

The LinkedHashMap seems to almost fit the bill but it is not a true List and therefore not a great drop in replacement.

What I’m using right now is a wrapper around a List which maintains an additional HashMap to find objects by the index criterium. The index is automatically updated whenever the list is modified. This is an example on how I use it:

// function to index Persons by their social security number
Function<Person, String> getSsnrForPerson = new Function<Person, String>() {
  String apply(Person person) {
    return person.getSocialSecurityNumber();
  }
}

To create an indexed list for an empty ArrayList<Person> with an index on a person’s social security number you can then easily use the Class UniqueIndexedList:

UnqiueIndexedList<Person, String> myList =
  UnqiueIndexedList.create(getSsnrForPerson);

Of course all the usual methods of the List<Person> interface can be used as usual:

myList.add(somePerson);
myList.add(anotherPerson);
myList.get(i);
myList.iterator();

Additionaly there are  methods to access objects by index:

boolean personIsInList = myList.containsByIndex("34897634853");
Person p = myList.getByIndex("34897634853");

The code for the list implementation currently resides here:

It is basically a hybrid of a List and a special index-Map and works well so far. I am sure that finding objects in list for a given attribute is a very common usecase. Why hasn’t anyone solved this yet? Are there (better) alternatives that I’ve missed?

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>