La mejor forma de crear un hashmap de arraylist

Tengo un millón de filas de datos en formato .txt. el formato es muy simple. Por cada fila:

 usuario1, valor1
 usuario2, valor2
 usuario3, valor3
 usuario1, valor4
 ...

Sabes a lo que me refiero. Para cada usuario, podría aparecer muchas veces, o aparecer solo una vez (nunca se sabe). Necesito encontrar todos los valores para cada usuario. Debido a que el usuario puede aparecer de forma aleatoria, utilicé Hashmap para hacerlo. Es decir: HashMap (clave: String, valor: ArrayList). Pero para agregar datos al arrayList, tengo que usar constantemente HashMap get (key) para obtener el arrayList, agregarle valor y luego ponerlo nuevamente en HashMap. Siento que no es tan eficiente. ¿Alguien sabe una mejor manera de hacer eso?

No necesita volver a agregar ArrayList a su mapa. Si ArrayList ya existe, solo agregue su valor.

Una implementación mejorada podría ser similar a:

Map> map = new HashMap>(); 

al procesar cada línea:

 String user = user field from line String value = value field from line Collection values = map.get(user); if (values==null) { values = new ArrayList(); map.put(user, values) } values.add(value); 

Seguimiento de abril de 2014 : escribí la respuesta original en 2009 cuando mi conocimiento de Google Guava era limitado. A la luz de todo lo que hace Google Guava, ahora recomiendo usar su Multimap lugar de reinventarlo.

 Multimap values = HashMultimap.create(); values.put("user1", "value1"); values.put("user2", "value2"); values.put("user3", "value3"); values.put("user1", "value4"); System.out.println(values.get("user1")); System.out.println(values.get("user2")); System.out.println(values.get("user3")); 

Productos:

 [value4, value1] [value2] [value3] 

Use Multimap de Google Collections. Permite múltiples valores para la misma clave

https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Multimap.html

Los valores de ArrayList en su HashMap son referencias. No necesita “volver a ponerlo en HashMap”. Está operando en el objeto que ya existe como un valor en HashMap.

Si no quieres importar una biblioteca.

 package util; import java.util.ArrayList; import java.util.HashMap; import java.util.List; /** * A simple implementation of a MultiMap. This implementation allows duplicate elements in the the * values. (I know classes like this are out there but the ones available to me didn't work). */ public class MultiMap extends HashMap> { /** * Looks for a list that is mapped to the given key. If there is not one then a new one is created * mapped and has the value added to it. * * @param key * @param value * @return true if the list has already been created, false if a new list is created. */ public boolean putOne(K key, V value) { if (this.containsKey(key)) { this.get(key).add(value); return true; } else { List values = new ArrayList<>(); values.add(value); this.put(key, values); return false; } } } 

Creo que lo que quieres es el Multimap. Puedes obtenerlo de la colección commons de apache, o google-collections.

http://commons.apache.org/collections/

http://code.google.com/p/google-collections/

“colección similar a un mapa, pero que puede asociar varios valores con una sola tecla. Si llama put (K, V) dos veces, con la misma clave pero diferentes valores, el multimap contiene asignaciones de la clave para ambos valores”.

No pude encontrar ninguna manera fácil. MultiMap no siempre es una opción disponible. Entonces escribí algo así.

 public class Context extends HashMap { public V addMulti(K paramK, V paramV) { V value = get(paramK); if (value == null) { List list = new ArrayList(); list.add(paramV); put(paramK, paramV); } else if (value instanceof List) { ((List)value).add(paramV); } else { List list = new ArrayList(); list.add(value); list.add(paramV); put(paramK, (V) list); } return paramV; } } 

Desde Java 8 puedes usar map.computeIfAbsent

https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#computeIfAbsent-K-java.util.function.Function-

 Collection values = map.computeIfAbsent(user, k -> new ArrayList<>()); values.add(value); 

Sería más rápido si utilizara una Lista Vinculada en lugar de una Lista de Arrays, ya que la Lista de Arreglos necesitará cambiar el tamaño cuando se acerque a la capacidad.

También querrá estimar de forma adecuada la capacidad de la colección de envoltura (HashMap o Multimap) que está creando para evitar un reajuste repetitivo.

Como ya se mencionó, MultiMap es su mejor opción.

Dependiendo de los requisitos de su empresa o de las limitaciones del archivo de datos, le recomendamos que realice una clasificación única para optimizar el proceso de carga.

Intereting Posts