views:

117

answers:

2

Hi there

I have page gets given an ArrayList<Document> where each document has a property called type.

I don't know the number of unique types or documents.

I want to sort this ArrayList into a HashMap<type, document[]> but am having some trouble getting my head around it.

Some pseudo-code would like like

for (int i = 0; i < documents.size(); i++) 
{
   if there is an array for documents[i].type
   add to this array
   else create a new array for this type
   add document[i].type and the array of documents with matching type to the hashmap
}

I know this is the wrong approach and clearly won't work. I am open to any suggestions.

Thank you

+7  A: 
// create the map to store stuff, note I'm using a List instead of an array
// in my opinion it's a bit cleaner
Map<String, List<Document>> map = new HashMap<String, List<Document>>();

// now iterate through each document
for(Document d : documents){

    // check to see if this type is already known
    List<Document> list = map.get(d.type);

    if(list == null){
        // list is null when it wasn't found in the map
        // this is a new type, create a new list
        list = new ArrayList<Document>();

        // store the list in the map
        map.put(d.type, list);
    }

    // finally, whether we got a hit or a miss, we want
    // to add this document to the list for this type
    list.add(d);
}
Mark E
+1 for adding useful comments
Ibrahim
+2  A: 

I think rather than sorting by type, the term you're looking for is indexing by type. Guava's Multimap interface is designed for mapping keys to multiple values without all the hassle of dealing with the collections of values. In particular, Guava has a method that's designed to do exactly what you're trying to do:

List<Document> documents = ...
ImmutableListMultimap<Type, Document> typeIndex = Multimaps.index(documents,
    new Function<Document, Type>() {
      public Type apply(Document input) {
        return input.getType();
      }
    });

for(Type type : typeIndex.keySet()) {
  ImmutableList<Document> documentsWithType = typeIndex.get(type);
  ...
}

This is pretty much the same as doing:

ListMultimap<Type, Document> typeIndex = ArrayListMultimap.create();
for(Document document : documents) {
  typeIndex.put(document.getType(), document);
}

except that the resulting multimap is immutable. Note also that the above is almost exactly equivalent to Mark's example.

ColinD