创建arraylist的hashmap的最佳方法

时间:2009-06-18 05:17:24

标签: java data-structures collections arraylist hashmap

我有.txt格式的一百万行数据。格式很简单。对于每一行:

user1,value1
user2,value2
user3,value3
user1,value4
...

你知道我的意思。对于每个用户,它可能会出现多次,或只出现一次(您永远不会知道)。我需要找出每个用户的所有值。因为用户可能会随机出现,所以我使用了Hashmap来完成它。即:HashMap(key:String,value:ArrayList)。但是要向arrayList添加数据,我必须经常使用HashMap get(key)来获取arrayList,为它添加值,然后将其放回HashMap。我觉得效率不高。有人知道更好的方法吗?

9 个答案:

答案 0 :(得分:64)

您无需将ArrayList重新添加回Map。如果ArrayList已经存在,那么只需将值添加到它。

改进的实现可能如下所示:

Map<String, Collection<String>> map = new HashMap<String, Collection<String>>();
处理每一行时

String user = user field from line
String value = value field from line

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

2014年4月的后续行动 - 当我对Google Guava的知识有限时,我在2009年写了原始答案。鉴于Google Guava所做的一切,我现在建议使用Multimap而不是重新发明它。

Multimap<String, String> 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]

答案 1 :(得分:12)

使用Google Collections中的Multimap。它允许同一个键的多个值

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

答案 2 :(得分:4)

HashMap中的ArrayList值是引用。你不需要“把它放回HashMap”。您正在对作为HashMap中的值存在的对象进行操作。

答案 3 :(得分:4)

如果您不想导入图书馆。

@Generated

答案 4 :(得分:2)

Java 8以来,您可以使用map.computeIfAbsent

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

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

答案 5 :(得分:1)

我认为你想要的是Multimap。您可以从apache的commons集合或google-collections中获取它。

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

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

  

“类似于地图的集合,但是   这可能会关联多个值   用一把钥匙。如果你叫put(K,   V)两次,使用相同的键但是   不同的值,多​​图   包含从键到两者的映射   值“。

答案 6 :(得分:0)

我找不到任何简单的方法。 MultiMap并不总是可用的选项。所以我写了一些东西。

public class Context<K, V> extends HashMap<K, V> {

    public V addMulti(K paramK, V paramV) {
        V value = get(paramK);
        if (value == null) {
            List<V> list = new ArrayList<V>();
            list.add(paramV);
            put(paramK, paramV);
        } else if (value instanceof List<?>) {
            ((List<V>)value).add(paramV);
        } else {
            List<V> list = new ArrayList<V>();
            list.add(value);
            list.add(paramV);
            put(paramK, (V) list);
        }
        return paramV;
    }
}

答案 7 :(得分:-1)

如果使用LinkedList而不是ArrayList会更快,因为ArrayList在接近容量时需要调整大小。

您还需要适当地估计您正在创建的包装集合(HashMap或Multimap)的容量,以避免重复重复。

答案 8 :(得分:-1)

如前所述,MultiMap是您的最佳选择。

根据您的业务要求或对数据文件的限制,您可能需要考虑对其进行一次性排序,以使其更适合加载。