2010-10-01 15 views

Respuesta

9
// create the thing to store the sub lists 
Map<Integer, List<MyObject>> subs = new HashMap<Integer, List<MyObject>>(); 

// iterate through your objects 
for(MyObject o : list){ 

    // fetch the list for this object's id 
    List<MyObject> temp = subs.get(o.getId()); 

    if(temp == null){ 
     // if the list is null we haven't seen an 
     // object with this id before, so create 
     // a new list 
     temp = new ArrayList<MyObject>(); 

     // and add it to the map 
     subs.put(o.getId(), temp); 
    } 

    // whether we got the list from the map 
    // or made a new one we need to add our 
    // object. 
    temp.add(o); 
} 
+0

gracias esta solución me parece elegante. – james

+1

+1 - para sangrar correctamente el código y agregar comentarios –

2

Pasa por los elementos, comprueba sus valores id y colócalos en Hashtable con id como la clave. Eso es O (N), que es tan eficiente como lo que obtendrás.

+0

¿Y qué hay del valor? –

+0

@Kirk - Eso depende de cómo lo use el OP. Con un objeto tan trivial podría ser conveniente tener 'nombre' como valor, sin embargo, en muchas situaciones, tendría más sentido que el valor fuera el objeto en sí: no es una pregunta a la que pueda responder sin más contexto. –

1
ArrayList<MyObject> list=new ArrayList<MyObject>(); 
//fill Objects.. 
HashMap<Integer,ArrayList<MyObject>> hash=new HashMap<Integer,ArrayList<MyObject>>(); 
for(MyObject elem:list)//iterate the list 
{ 
ArrayList<MyObject> tmp=null; //temporary variable 
if((tmp=hash.get(elem.getId()))==null) // check if id already present in map 
{ 
    tmp=new ArrayList<MyObject>(); 
    hash.put(elem.getId(),tmp); //if not put a new array list 
} 
names.add(elem); //if present add the name to arraylist 
} 
+0

+1, el valor es una lista. –

+0

nombres nunca se vuelve no nulo en esta solución en el caso de que tenga que agregar una nueva ArrayList. –

+0

@Mark: No probé el código. Gracias por señalar. – Emil

8

Usando Guava:

ListMultimap<Integer, MyObject> myObjectsById = Multimaps.index(myObjects, 
    new Function<MyObject, Integer>() { 
     public Integer apply(MyObject myObject) { 
     return myObject.id; 
     } 
    }); 
+1

O, al usar Java 8: ListMultimap myObjectsById = Multimaps.index (myObjects, MyObject :: getId); Pero entonces también podrías omitir la guayaba por completo y usar la respuesta de Damien O'Reilly –

2

El uso de JDK 1.8:

List<MyObject> objects= new ArrayList(); 
Map<Integer, List<MyObject>> obejctMap = new HashMap(); 
objects.stream().map(MyObject::getId).distinct().forEach(id -> obejctMap .put(id, 
       objects.stream().filter(object -> id.equals(object.getId())).collect(Collectors.toList()))); 
3

Si está utilizando JDK 1.8, puede utilizar una solución elegante como:

Map<Integer, List<MyObject>> myObjectsPerId = 
    myObjects.stream().collect(Collectors.groupingBy(MyObject::getId)); 
Cuestiones relacionadas