Lowercase all HashMap keys

前端 未结 4 1245
夕颜
夕颜 2021-02-12 14:17

I \'ve run into a scenario where I want to lowercase all the keys of a HashMap (don\'t ask why, I just have to do this). The HashMap has some millions of entries.

At fir

4条回答
  •  傲寒
    傲寒 (楼主)
    2021-02-12 14:23

    You cannot remove the entry while iterating over the map. You will have a ConcurentModificationException if you try to do this.

    As the issue is an OutOfMemoryError, not a performance error, using parallel stream will not help either.

    Despite some task on the Stream API will be done lately, this will still lead to have two maps in memory at some point so you will still have the issue.

    To workaround it, I only saw two ways :

    • Give more memory to your process (by increasing -Xmx on the Java command line). Memory is cheap these days ;)
    • Split the map and work in chunks : for example you divide the size of the map by ten and you process one chunck at a time and delete the processed entries before processing the new chunk. By this instead of having two times the map in memory you will just have 1.1 times the map.

    For the split algorithm, you can try someting like this using the Stream API :

    Map toMap = new HashMap<>();            
    int chunk = fromMap.size() / 10;
    for(int i = 1; i<= 10; i++){
        //process the chunk
        List> subEntries = fromMap.entrySet().stream().limit(chunk)
            .collect(Collectors.toList());  
    
        for(Entry entry : subEntries){
            toMap.put(entry.getKey().toLowerCase(), entry.getValue());
            fromMap.remove(entry.getKey());
        }
    }
    

提交回复
热议问题