I have similar problem to one discussed here, but with stronger practical usage.
For example, I have a Map<String, Integer>
, and I have some function, which is given a key and in case the mapped integer value is negative, puts NULL
to the map:
Map<String, Integer> map = new HashMap<String, Integer>();
public void nullifyIfNegative(String key) {
Integer value = map.get(key);
if (value != null && value.intValue() < 0) {
map.put(key, null);
}
}
I this case, the lookup (and hence, hashCode
calculation for the key) is done twice: one for lookup and one for replacement. It would be nice to have another method (which is already in HashMap
) and allows to make this more effective:
public void nullifyIfNegative(String key) {
Map.Entry<String, Integer> entry = map.getEntry(key);
if (entry != null && entry.getValue().intValue() < 0) {
entry.setValue(null);
}
}
The same concerns cases, when you want to manipulate immutable objects, which can be map values:
Map<String, String>
: I want to append something to the string value.Map<String, int[]>
: I want to insert a number into the array.
So the case is quite common. Solutions, which might work, but not for me:
- Reflection. Is good, but I cannot sacrifice performance just for this nice feature.
- Use
org.apache.commons.collections.map.AbstractHashedMap
(it has at leastprotected getEntry()
method), but unfortunately, commons-collections do not support generics. - Use generic commons-collections, but this library (AFAIK) is out-of-date (not in sync with latest library version from Apache), and (what is critical) is not available in central maven repository.
- Use value wrappers, which means "making values mutable" (e.g. use mutable integers [e.g.
org.apache.commons.lang.mutable.MutableInt
], or collections instead of arrays). This solutions leads to memory loss, which I would like to avoid. - Try to extend
java.util.HashMap
with custom class implementation (which should be injava.util
package) and put it to endorsed folder (asjava.lang.ClassLoader
will refuse to load it inClass<?> defineClass(String name, byte[] b, int off, int len)
, see sources), but I don't want to patch JDK and it seems like the list of packages that can be endorsed, does not includejava.util
.
The similar question is already raised on sun.com bugtracker, but I would like to know, what is the opinion of the community and what can be the way out taking in mind the maximum memory & performance effectiveness.
If you agree, this is nice and beneficiary functionality, please, vote this bug!