How to split an HashMap in Java

蹲街弑〆低调 提交于 2020-02-01 20:19:12

问题


I was wondering if it is possible to split a HashMap into smaller sub-maps.

In my case I have a HashMap of 100 elements and I would like to create 2 (or more) smaller HashMaps from the original one, the first containing the Entries from 0 to 49, the second containing the Entries from 50 to 99.

Map <Integer, Integer> bigMap = new HashMap <Integer, Integer>();

//should contains entries from 0 to 49 of 'bigMap'
Map <Integer, Integer> smallMap1 = new HashMap <Integer, Integer>(); 


//should contains entries from 50 to 99 of 'bigMap'
Map <Integer, Integer> smallMap2 = new HashMap <Integer, Integer>();

Any suggestions? Many thanks!


回答1:


Do you have to use HashMap?

TreeMap is really good for this kind of things. Here's an example.

TreeMap<Integer, Integer> sorted = new TreeMap<Integer, Integer>(bigMap);

SortedMap<Integer, Integer> zeroToFortyNine = sorted.subMap(0, 50);
SortedMap<Integer, Integer> fiftyToNinetyNine = sorted.subMap(50, 100);



回答2:


You'll basically need to iterate over the entries in bigMap, and make a decision as to whether they should be added to smallMap1 or smallMap2.




回答3:


As the HashMap is unordered (entries may come in any order), it makes no sense to exactly split it. We can simply use the alternating boolean flag.

boolean b = false;
for (Map.Entry e: bigMap.entrySet()) {
  if (b)
    smallMap1.put(e.getKey(), e.getValue());
  else
    smallMap2.put(e.getKey(), e.getValue());
  b = !b;
}



回答4:


Iterate over the bigMap with for (Entry<Integer, Integer> entry : bigMap.entrySet()), and increment an i to check whether you have to add the entry in the first small map or in the second one.




回答5:


Here is a solution with a SortedMap:

public static <K, V> List<SortedMap<K, V>> splitMap(final SortedMap<K, V> map, final int size) {
    List<K> keys = new ArrayList<>(map.keySet());
    List<SortedMap<K, V>> parts = new ArrayList<>();
    final int listSize = map.size();
    for (int i = 0; i < listSize; i += size) {
        if (i + size < listSize) {
            parts.add(map.subMap(keys.get(i), keys.get(i + size)));
        } else {
            parts.add(map.tailMap(keys.get(i)));
        }
    }
    return parts;
}



回答6:


for (Map.Entry<Integer,Integer> entry : bigMap.entrySet()) {
   // ...
}

is the fastest way to iterate through your original map. You'd then use the Map.Entry key to decide which new map to populate.




回答7:


This was one of the functions which did the work me, I hope its helpful for others. This one works irrespective of the Object/primitive stored as key.

The TreeMap approach suggested above would work only if the keys are primitives, ordered and in exact sequence of index..

    public List<Map<Integer, EnrichmentRecord>> splitMap(Map<Integer, EnrichmentRecord> enrichmentFieldsMap,
            int splitSize) {

        float mapSize = enrichmentFieldsMap.size();
        float splitFactorF = splitSize; 
        float actualNoOfBatches = (mapSize / splitFactorF);
        double noOfBatches = Math.ceil(actualNoOfBatches);



        List<Map<Integer, EnrichmentRecord>> listOfMaps = new ArrayList<>();

        List<List<Integer>> listOfListOfKeys = new ArrayList<>();


        int startIndex = 0;
        int endIndex = splitSize;

        Set<Integer> keys = enrichmentFieldsMap.keySet();
        List<Integer> keysAsList = new ArrayList<>();
        keysAsList.addAll(keys);

        /*
         * Split the keys as a list of keys,  
         * For each key sub list add to a Primary List - listOfListOfKeys
         */
        for (int i = 0; i < noOfBatches; i++) {
            listOfListOfKeys.add(keysAsList.subList(startIndex, endIndex));         
            startIndex = endIndex;
            endIndex = (int) (((endIndex + splitSize) > mapSize) ? mapSize : (endIndex + splitSize));
        }

         /**
         * For Each list of keys, prepare a map
         *
         **/
        for(List<Integer> keyList: listOfListOfKeys){
            Map<Integer,EnrichmentRecord> subMap = new HashMap<>();
            for(Integer key: keyList){
                subMap.put(key,enrichmentFieldsMap.get(key));
            }
            listOfMaps.add(subMap);
        }

        return listOfMaps;
    }


来源:https://stackoverflow.com/questions/14629496/how-to-split-an-hashmap-in-java

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!