有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java用迭代优化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) 个答案

  1. # 1 楼答案

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

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

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

  2. # 2 楼答案

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

    但我能看到一个变化,这是可以做到的

     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中的任何一个

  3. # 3 楼答案

    resultSet调整获取大小

    resultSet.setFetchSize(100);
    

    当然,您可以简化add方法(每个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());
        }
    }
    
  4. # 4 楼答案

    试试这个。(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());
    }