使用迭代优化HashMap

时间:2017-01-06 03:51:55

标签: 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.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);
}

上面引用的addIntern方法

private static void addIntern(Map<String,Map<String,String>> internalMap, String val2, Integer val1,
    String val3,String val4,String type,String id) {
    String key = id+"##"+val4;
    if (internalMap.get(key) == null) {
        internalMap.put(key, new HashMap<String,String>());
    }
    internalMap.get(key).put("val3", val3);
    internalMap.get(key).put("val2", val2);


    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());
    }
}

4 个答案:

答案 0 :(得分:5)

resultSet;

调整抓取大小
resultSet.setFetchSize(100);

你当然可以简化你的添加方法(每个get都是一个O(1)调用,但是它们相加),比如

private static void addIntern(Map<String, Map<String, String>> internalMap, String val2, Integer val1, String val3,
        String val4, String type, String id) {
    String key = id + "##" + val4;
    Map<String, String> kMap;
    if (internalMap.containsKey(key)) {
        kMap = internalMap.get(key);
    } else {
        kMap = new HashMap<>();
        internalMap.put(key, kMap);
    }
    kMap.put("val3", val3);
    kMap.put("val2", val2);
    if ("create".equals(type) || "update".equals(type) || "delete".equals(type)) {
        kMap.put(type, val1.toString());
    }
}

答案 1 :(得分:1)

由于无法减少迭代次数,因此无法进行优化。

但是我可以看到一个可以做到的改变

 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或更多。

这适用于type只能包含create/update/delete值的情况。如果它有更多,你可以放一个if来检查它是否等于3中的任何一个。

答案 2 :(得分:0)

试试这个。 (Java 8)

private static void addIntern(Map<String,Map<String,String>> internalMap,
    String val2, Integer val1,
    String val3,String val4,String type,String id) {
    String key = id+"##"+val4;
    Map<String, String> valueMap = internalMap.computeIfAbsent(key, k -> new HashMap<>());
    valueMap.put("val3", val3);
    valueMap.put("val2", val2);
    if("create".equals(type) || "update".equals(type) || "delete".equals(type))
        valueMap.put(type, val1.toString());
}

答案 3 :(得分:0)

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

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

使用默认初始容量时,由于添加了300000个项目,因此必须多次重新设置internalMap。