创建arraylist的hashmap的最佳方法
我有.txt格式的一百万行数据。 格式很简单。 对于每一行:
USER1,值1 用户2,值2 用户3,值3 USER1,VALUE4 ...
你知道我的意思。 对于每个用户,它可能会出现多次,或只出现一次(您永远不会知道)。 我需要找出每个用户的所有值。 因为用户可能会随机出现,所以我使用Hashmap来做。 即:HashMap(key:String,value:ArrayList)。 但是要向arrayList添加数据,我必须经常使用HashMap get(key)来获取arrayList,为它添加值,然后将其放回HashMap。 我觉得效率不高。 谁知道更好的方法呢?
您无需将ArrayList重新添加回Map。 如果ArrayList已经存在,那么只需将值添加到它。
改进的实现可能如下所示:
Map> map = new HashMap>();
处理每一行时:
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);
2014年4月的后续行动 – 当我对Google Guava的知识有限时,我在2009年写了原始答案。 鉴于Google Guava所做的一切,我现在建议使用其Multimap
而不是重新发明它。
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"));
输出:
[value4, value1] [value2] [value3]
使用Google Collections中的Multimap。 它允许同一个键的多个值
https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Multimap.html
HashMap中的ArrayList值是引用。 你不需要“把它放回HashMap”。 您正在对作为HashMap中的值已存在的对象进行操作。
如果您不想导入库。
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; } } }
我想你想要的是Multimap。 你可以从apache的commons集合或google-collections中获取它。
http://commons.apache.org/collections/
http://code.google.com/p/google-collections/
“集合类似于Map,但可以将多个值与一个键相关联。如果您使用相同的键但不同的值调用put(K,V)两次,则multimap包含从键到两个值的映射。”
我找不到任何简单的方法。 MultiMap并不总是可用的选项。 所以我写了一些东西。
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; } }
从Java 8
您可以使用map.computeIfAbsent
Collection values = map.computeIfAbsent(user, k -> new ArrayList<>()); values.add(value);
如果使用LinkedList而不是ArrayList会更快,因为ArrayList在接近容量时需要resize。
您还需要适当地估计要创建的包装集合(HashMap或Multimap)的容量,以避免重复的重复。
如前所述, MultiMap
是您的最佳选择。
根据您的业务要求或数据文件的约束,您可能需要考虑对其进行一次性排序,以使其更加优化以进行加载。