Java 创建 arraylist 哈希图的最佳方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1010879/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best way to create a hashmap of arraylist
提问by
I have one million rows of data in .txt format. the format is very simple. For each row:
我有一百万行 .txt 格式的数据。格式非常简单。对于每一行:
user1,value1 user2,value2 user3,value3 user1,value4 ...
You know what I mean. For each user, it could appear many times, or appear only once (you never know). I need to find out all the values for each user. Because user may appear randomly, I used Hashmap to do it. That is: HashMap(key: String, value: ArrayList). But to add data to the arrayList, I have to constantly use HashMap get(key) to get the arrayList, add value to it, then put it back to HashMap. I feel it is not that very efficient. Anybody knows a better way to do that?
你知道我的意思。对于每个用户,它可能出现多次,也可能只出现一次(你永远不知道)。我需要找出每个用户的所有值。因为用户可能随机出现,所以我用Hashmap来做。即:HashMap(key: String, value: ArrayList)。但是要将数据添加到arrayList,我必须不断使用HashMap get(key) 获取arrayList,为其添加值,然后将其放回HashMap。我觉得效率不是很高。有人知道更好的方法吗?
采纳答案by Steve Kuo
You don't need to re-add the ArrayList back to your Map. If the ArrayList already exists then just add your value to it.
您不需要将 ArrayList 重新添加回您的地图。如果 ArrayList 已经存在,那么只需将您的值添加到它。
An improved implementation might look like:
改进的实现可能如下所示:
Map<String, Collection<String>> map = new HashMap<String, Collection<String>>();
while processing each line:
在处理每一行时:
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);
Follow-up April 2014- I wrote the original answer back in 2009 when my knowledge of Google Guava was limited. In light of all that Google Guava does, I now recommend using its Multimap
instead of reinvent it.
2014年4 月跟进——我在 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"));
Outputs:
输出:
[value4, value1]
[value2]
[value3]
回答by akf
it would be faster if you used a LinkedList instead of an ArrayList, as the ArrayList will need to resize when it nears capacity.
如果使用 LinkedList 而不是 ArrayList 会更快,因为 ArrayList 在接近容量时需要调整大小。
you will also want to appropriately estimate the capacity of the wrapping collection (HashMap or Multimap) you are creating to avoid repetitive rehashing.
您还需要适当地估计您正在创建的包装集合(HashMap 或 Multimap)的容量,以避免重复重新散列。
回答by Yoni Roit
Use Multimap from Google Collections. It allows multiple values for the same key
使用 Google Collections 中的 Multimap。它允许同一个键有多个值
https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Multimap.html
https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Multimap.html
回答by anthony
The ArrayList values in your HashMap are references. You don't need to "put it back to HashMap". You're operating on the object that already exists as a value in the HashMap.
HashMap 中的 ArrayList 值是引用。您不需要“将其放回 HashMap”。您正在对已作为 HashMap 中的值存在的对象进行操作。
回答by kctang
i think what you want is the Multimap. You can get it from apache's commons collection, or google-collections.
我想你想要的是Multimap。您可以从 apache 的 commons 集合或 google-collections 中获取它。
http://commons.apache.org/collections/
http://commons.apache.org/collections/
http://code.google.com/p/google-collections/
http://code.google.com/p/google-collections/
"collection similar to a Map, but which may associate multiple values with a single key. If you call put(K, V) twice, with the same key but different values, the multimap contains mappings from the key to both values."
“类似于 Map 的集合,但它可能将多个值与单个键相关联。如果您调用 put(K, V) 两次,使用相同的键但不同的值,则多重映射包含从键到两个值的映射。”
回答by aberrant80
As already mentioned, MultiMap
is your best option.
如前所述,MultiMap
是您最好的选择。
Depending on your business requirements or constraints on the data file, you may want to consider doing a one-off sorting of it, to make it more optimised for loading.
根据您的业务需求或对数据文件的限制,您可能需要考虑对其进行一次性排序,以使其更适合加载。
回答by Ankur
I Could not find any easy way. MultiMap is not always an option available. So I wrote something this.
我找不到任何简单的方法。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;
}
}
回答by Stuart Clark
If you don't want to import a library.
如果您不想导入库。
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<K, V> extends HashMap<K, List<V>> {
/**
* 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<V> values = new ArrayList<>();
values.add(value);
this.put(key, values);
return false;
}
}
}
回答by ilopezluna
Since Java 8
you can use map.computeIfAbsent
由于Java 8
您可以使用map.computeIfAbsent
Collection<String> values = map.computeIfAbsent(user, k -> new ArrayList<>());
values.add(value);