Java 用迭代优化HashMap

Java 用迭代优化HashMap,java,jdbc,collections,hashmap,Java,Jdbc,Collections,Hashmap,我有一个ResultSet,其中包含300K条记录,我正在执行以下操作来迭代它(以及收集到的其他操作)。完成此过程大约需要2分钟。有没有办法优化它 Map<String,Map<String,String>> internalMap = new HashMap<String,Map<String,String>>(); while (resultSet.next()) { final Integer val1 = resultSet.

我有一个
ResultSet
,其中包含300K条记录,我正在执行以下操作来迭代它(以及收集到的其他操作)。完成此过程大约需要2分钟。有没有办法优化它

Map<String,Map<String,String>> internalMap  = new HashMap<String,Map<String,String>>(); 

while (resultSet.next()) {
    final Integer val1 = resultSet.getInt("val1");
    final String val2 = resultSet.getString("val2");
    final String val3 = resultSet.getString("val3");
    final String val4 = resultSet.getString("val4");
    final String type = resultSet.getString("type");
    final String id = resultSet.getString("id");

    addIntern(internalMap,val2,val1,val3,val4,type,id);
}

由于无法减少迭代次数,您将无法进行太多优化

但有一个改变,我可以看出这是可以做到的

 if("create".equals(type)){
    internalMap.get(key).put("create", val1.toString());
 }
 if("update".equals(type)){
    internalMap.get(key).put("update", val1.toString());
 }
 if("delete".equals(type)){
    internalMap.get(key).put("delete", val1.toString());
 }
以上内容也可以写成以下内容

internalMap.get(key).put(type, val1.toString());
如果进行检查,这将删除300k或更多


当您的
类型
只能包含
创建/更新/删除
值时,这将起作用。如果它有更多,你可以用一个
If
来检查它是否等于3个中的任何一个。

你将无法进行太多优化,因为你无法减少迭代次数

但有一个改变,我可以看出这是可以做到的

 if("create".equals(type)){
    internalMap.get(key).put("create", val1.toString());
 }
 if("update".equals(type)){
    internalMap.get(key).put("update", val1.toString());
 }
 if("delete".equals(type)){
    internalMap.get(key).put("delete", val1.toString());
 }
以上内容也可以写成以下内容

internalMap.get(key).put(type, val1.toString());
如果进行检查,这将删除300k或更多


当您的
类型
只能包含
创建/更新/删除
值时,这将起作用。如果它有更多,您可以放置一个
If
来检查它是否等于3个中的任何一个。

结果集调整提取大小

resultSet.setFetchSize(100);
当然,您可以简化add方法(每个get都是一个
O(1)
调用,但它们相加),比如

private static void addIntern(映射内部映射,字符串val2,整数val1,字符串val3,
字符串val4,字符串类型,字符串id){
字符串键=id+“##”+val4;
Map kMap;
if(internalMap.containsKey(键)){
kMap=internalMap.get(key);
}否则{
kMap=新的HashMap();
内部映射。put(键,kMap);
}
kMap.put(“val3”,val3);
kMap.put(“val2”,val2);
如果(“创建”.equals(类型)| |“更新”.equals(类型)| |“删除”.equals(类型)){
kMap.put(type,val1.toString());
}
}

从您的
结果集调整提取大小

resultSet.setFetchSize(100);
当然,您可以简化add方法(每个get都是一个
O(1)
调用,但它们相加),比如

private static void addIntern(映射内部映射,字符串val2,整数val1,字符串val3,
字符串val4,字符串类型,字符串id){
字符串键=id+“##”+val4;
Map kMap;
if(internalMap.containsKey(键)){
kMap=internalMap.get(key);
}否则{
kMap=新的HashMap();
内部映射。put(键,kMap);
}
kMap.put(“val3”,val3);
kMap.put(“val2”,val2);
如果(“创建”.equals(类型)| |“更新”.equals(类型)| |“删除”.equals(类型)){
kMap.put(type,val1.toString());
}
}
试试这个。(爪哇8)

private static void addIntern(映射内部映射,
字符串val2,整数val1,
字符串val3、字符串val4、字符串类型、字符串id){
字符串键=id+“##”+val4;
Map valueMap=internalMap.computeIfAbsent(key,k->newHashMap());
valueMap.put(“val3”,val3);
valueMap.put(“val2”,val2);
如果(“创建”.equals(类型)| |“更新”.equals(类型)| |“删除”.equals(类型))
put(type,val1.toString());
}
试试这个。(爪哇8)

private static void addIntern(映射内部映射,
字符串val2,整数val1,
字符串val3、字符串val4、字符串类型、字符串id){
字符串键=id+“##”+val4;
Map valueMap=internalMap.computeIfAbsent(key,k->newHashMap());
valueMap.put(“val3”,val3);
valueMap.put(“val2”,val2);
如果(“创建”.equals(类型)| |“更新”.equals(类型)| |“删除”.equals(类型))
put(type,val1.toString());
}

如果有足够的堆空间可用,设置映射初始容量可能会有所帮助:

Map<String,Map<String,String>> internalMap  = new HashMap<String,Map<String,String>>(300000*2); 
Map internalMap=newhashmap(300000*2);

通过使用默认初始容量,internalMap必须重新刷新多次,因为您要添加300000个项目。

如果您有足够的可用堆空间,设置映射初始容量可能会有所帮助:

Map<String,Map<String,String>> internalMap  = new HashMap<String,Map<String,String>>(300000*2); 
Map internalMap=newhashmap(300000*2);

通过使用默认的初始容量,internalMap必须重新刷新多次,因为您要添加300000个项目。

看起来您需要的是
Map
,而不是
Map
@4castle,但我们只是在输入值。因此,将其用作对象或贴图,两者将具有相同的效果。对吗?使用
映射
会占用更多内存,并且对可以存储的值类型的灵活性会降低。例如,您已经必须将
val1
转换为
String
。为什么要将整个数据集存储在内存中,而不是查询它?您应该分析您的程序,看看什么花费了最多的时间。例如,尝试使用探查器。这里的各种答案都集中在使用更好的数据结构,或者改进
addIntern
的代码上。但事实上,我们不知道时间将何去何从。它可能与数据结构无关。我猜瓶颈是在
resultSet.next()
中从数据库获取数据的延迟,但这只是一个猜测。看起来您需要
Map
而不是
Map
@4castle,但我们只是在输入值。因此,将其用作对象或贴图,两者将具有相同的效果。对吗?使用
映射
会占用更多内存,并且对可以存储的值类型的灵活性会降低。例如,您已经必须将
val1
转换为
String
。为什么要将整个数据集存储在内存中,而不是查询它?您应该分析您的程序,看看什么花费了最多的时间。例如,尝试使用探查器。这里的各种答案都集中在使用更好的数据结构,或者改进
addIntern
的代码上。但事实上,我们不知道时间将何去何从。它可能与数据结构无关。我猜瓶颈是在
resultSet.next()
中从数据库获取数据的延迟,但这只是一个猜测。