Reputation: 4569
I broke my brain on it for a few hours, but need to carry on and found an ugly workaround, but I'd be happy to cleanup my code, here's the problem:
public static void function1(Map<String, Float> map)
{
for(String key : map.keySet()) {
Float val = map.get(key);
// val is null here, throws NPE as soon as we try to use it
}
}
public static void function2(Map<String, Float> map)
{
Iterator<Entry<String, Float>> it = map.entrySet().iterator();
while(it.hasNext()) {
Entry<String, Float> entry = it.next();
String key = entry.getKey();
Float val = entry.getValue();
// do something with key & val, works fine
}
}
the argument Map<String, Float> map
of course is correctly initialized and doesn't contain any null value.
on a side note, function1 works fine if I change the argument to Map map and use string pairs only. My goal is to to have only 1 function with generics Map<? extends Object, ? extends Object> map
which I could use for both type of maps.
any suggestion appreciated, thanks! thomas
EDIT: I added some really basic introspection to make the function work with generics. I can confirm that I'm still getting null values when using the keyset, while I followed the suggestion below to use the entryset. here's my code below (the 1st function works fine, while the second returns null elements.
// yeah, it's aweful, but it works.
public static JsonNode map2JSON(Map<? extends Object, ? extends Object> map)
{
ObjectNode dummyObject = Json.newObject();
ArrayNode result = dummyObject.putArray("dummyKey");
for(Entry<?, ?> entry : map.entrySet()) {
ObjectNode mapElementNode = result.addObject();
if("java.lang.String".equalsIgnoreCase(entry.getKey().getClass().getName())) {
String key = (String)entry.getKey();
if("java.lang.Float".equalsIgnoreCase(entry.getValue().getClass().getName())) {
Float val = (Float)entry.getValue();
mapElementNode.put(key, val);
} else if("java.lang.String".equalsIgnoreCase(entry.getValue().getClass().getName())) {
String val = (String)entry.getValue();
mapElementNode.put(key, val);
}
}
}
return result;
}
// result here contains valid keys (the string part) and null values (the float part)
@Deprecated
public static JsonNode mapSF2JSON(Map<String, Float> map)
{
ObjectNode dummyObject = Json.newObject();
ArrayNode result = dummyObject.putArray("dummyKey");
for(String key : map.keySet()) {
ObjectNode mapElementNode = result.addObject();
mapElementNode.put(key, map.get(key));
}
return result;
}
Upvotes: 2
Views: 3270
Reputation: 28757
function1 uses a foreach loop, which will throw a NullPointerException when the map is null. You should check the map to be not null before you iterate with foreach
Further You should rewrite the ugly
if("java.lang.String".equalsIgnoreCase(entry.getKey().getClass().getName())) {
to
if (entry.getKey().getClass() == String.class) {
Upvotes: 0
Reputation: 28757
You probably inserted NULL key Strings into the map. This is possible when using a HashMap. Try to avoid adding NULL keys. Further you could use a TreeMap.
Bye the way it is not bad to iterate over the entry set, you could clean up your code by using foreach in function2 like you have done in function1:
This will look something like:
for(Entry<String, Float> entry : map.entrySet()) {
Float val = entry.getValue();
}
Although it is not necessary to clean up function2. But you should find the location where you inserted the NULL key into the map.
Upvotes: 1