问题
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