Reputation: 71
My app will receive a Hashmap<String,Object>
from another application.
Is there any way to trim the string keys without iterating the hashmap which leads to performance downgrade becoz Hashmap may contain a lot of real data entries.
Thanks
Upvotes: 2
Views: 8550
Reputation: 418317
One thing to note beforehand:
The map might contain 2 keys where the first is the trimmed version of the second. By doing what you want, it would overwrite/remove one of them from the map! E.g. the map might contain the keys "a "
and "a"
, and by trimming the keys one of them will disappear!
HashMap
does not provide any way to manipulate keys without iterating over them.
You can either "copy" the entries to a new map with keys trimmed (as with @RuchiraGayanRanaweera's solution), or you can do it in the same map like this:
Solution #1: Duplicate entry set and replace the different keys
So what you may do is iterate over the entries, and trim the keys. This also means that if the trimmed key is not equal to the original, you have to remove the entry with the old key and put it again with the new one. You only need to replace the entry if the trimmed version is different:
Map<String, Object> map = new HashMap<>();
for (Entry<String, Object> entry : new HashSet<>(map.entrySet())) {
String trimmed = entry.getKey().trim();
if (!trimmed.equals(entry.getKey())) {
map.remove(entry.getKey());
map.put(trimmed, entry.getValue());
}
}
Note that it is necessary to create a new Set
of the entry set because quoting from the javadoc of HashMap.entrySet()
:
If the map is modified while an iteration over the set is in progress (except through the iterator's own remove operation, or through the setValue operation on a map entry returned by the iterator) the results of the iteration are undefined.
Solution #2: Collect first then replace the different keys
Another option is to collect the keys where the trimmed key is different, and change only those after the first iteration. This solution has the advantage of not having to "duplicate" the entry set to iterate over it. If there are relatively few keys whose trimmed variant is different, probably this is the fastest solution:
Map<String, Object> map = new HashMap<>();
// Set to store the modified keys,
// Also store the trimmed String for performance reasons
Set<String[]> modifiedSet = new HashSet<>();
for (Entry<String, Object> entry : map.entrySet()) {
String trimmed = entry.getKey().trim();
if (!trimmed.equals(entry.getKey()))
modifiedSet.add(new String[]{entry.getKey(), trimmed});
}
// Changing a key can be done in one step:
// Removing the old entry (which returns the old value) and put the new
for (String[] modified : modifiedSet)
map.put(modified[1], map.remove(modified[0]));
Upvotes: 1
Reputation: 35577
If there is no way to trim()
keys before adding to HashMap
then you have to do something like following:
HashMap<String,Object> map=new HashMap<>();
HashMap<String,Object> newMap=new HashMap<>();
for(Map.Entry<String,Object> entry:map.entrySet()){
newMap.put(entry.getKey().trim(),entry.getValue());
}
Upvotes: 1
Reputation: 11620
You have two options:
In your example you have no choice, and you need to iterate over those keys.
Althought in java 8 you could use pararell streams to boost up such operation. But I would not recommend it in multithread enviroment.
Upvotes: 2