Java 创建arraylist的hashmap的最佳方法
我有一百万行.txt格式的数据。格式很简单。对于每行: user1,value1 user2,value2 user3,value3 user1,value4 ... user1,value1 user2,value2 user3,value3 user1,value4 ...Java 创建arraylist的hashmap的最佳方法,java,data-structures,collections,arraylist,hashmap,Java,Data Structures,Collections,Arraylist,Hashmap,我有一百万行.txt格式的数据。格式很简单。对于每行: user1,value1 user2,value2 user3,value3 user1,value4 ... user1,value1 user2,value2 user3,value3 user1,value4 ... 你知道我的意思。对于每个用户,它可能会出现很多次,或者只出现一次(你永远不知道)。我需要找出每个用户的所有值。因为用户可能随机出现,所以我使用Hashmap来实现。即:HashMap(key:String,value:A
你知道我的意思。对于每个用户,它可能会出现很多次,或者只出现一次(你永远不知道)。我需要找出每个用户的所有值。因为用户可能随机出现,所以我使用Hashmap来实现。即:HashMap(key:String,value:ArrayList)。但要向arrayList添加数据,我必须不断使用HashMap get(key)来获取arrayList,向其添加值,然后将其放回HashMap。我觉得效率不是很高。有人知道更好的方法吗 如果使用LinkedList而不是ArrayList,速度会更快,因为ArrayList在接近容量时需要调整大小
您还需要适当估计正在创建的包装集合(HashMap或Multimap)的容量,以避免重复的重新灰化 使用谷歌收藏中的多重地图。它允许同一个键有多个值
HashMap中的ArrayList值是引用。你不需要“把它放回HashMap”。您正在对HashMap中已作为值存在的对象进行操作。我认为您需要的是多重映射。您可以从apache的commons集合或google集合中获得它 “收集类似于地图,但 它可以关联多个值 只需一个键。如果调用put(K, 五) 两次,用同一把钥匙,但是 不同的值,多重映射 包含从键到两者的映射 价值观。”
无需将ArrayList重新添加回地图。如果ArrayList已经存在,那么只需将您的值添加到它 改进的实现可能如下所示:
Map<String, Collection<String>> map = new HashMap<String, Collection<String>>();
产出:
[value4, value1]
[value2]
[value3]
如前所述,
MultiMap
是您的最佳选择
取决于您的业务需求或对数据文件的约束,您可能需要考虑对其进行一次性排序,以使其更适合于加载。
< P>我找不到任何简单的方法。“多重贴图”并不总是可用的选项。所以我写了一些东西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;
}
}
公共类上下文扩展HashMap{
public V addMulti(K参数,V参数){
V值=get(参数K);
如果(值==null){
列表=新的ArrayList();
列表。添加(paramV);
put(paramK,paramV);
}else if(列表的值实例){
((列表)值)。添加(paramV);
}否则{
列表=新的ArrayList();
列表。添加(值);
列表。添加(paramV);
put(参数,(V)列表);
}
返回参数v;
}
}
如果您不想导入库
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;
}
}
}
package-util;
导入java.util.ArrayList;
导入java.util.HashMap;
导入java.util.List;
/**
*多重映射的简单实现。此实现允许在中复制元素
*价值观。(我知道像这样的课程还有很多,但我能上的那些课程不起作用)。
*/
公共类多重映射扩展HashMap{
/**
*查找映射到给定键的列表。如果没有,则创建一个新的列表
*映射并向其添加了值。
*
*@param-key
*@param值
*@如果已创建列表,则返回true;如果创建新列表,则返回false。
*/
公共布尔putOne(K键,V值){
如果(this.containsKey(key)){
this.get(key).add(value);
返回true;
}否则{
列表值=新的ArrayList();
增加(价值);
这个.put(键、值);
返回false;
}
}
}
自Java 8以来,您可以使用map.computeIfAbsent
Collection values=map.computeIfAbsent(用户,k->new ArrayList());
增加(价值);
其他答案都是正确的。我只是不想使用外部库。ArrayList几乎肯定会有更好的平均性能,即使调整大小也是如此。当您希望所有操作的时间大致相同时,LinkedList是一个不错的选择,例如,它们涉及到UI中,您不希望用户执行操作时出现随机延迟。这应该是一个注释
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;
}
}
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;
}
}
}
Collection<String> values = map.computeIfAbsent(user, k -> new ArrayList<>());
values.add(value);