调用map.get里面的for / in循环抛出nullpointerexception而迭代器没有

时间:2012-11-18 12:44:43

标签: java generics iterator

我打破了我的大脑几个小时,但需要继续进行并找到一个丑陋的解决方法,但我很乐意清理我的代码,这就是问题所在:

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
    }
}

参数Map<String, Float> map当然是正确初始化的,并且不包含任何空值。

在旁注中,如果我将参数更改为Map map并仅使用字符串对,则function1可以正常工作。我的目标是只有一个带有泛型Map<? extends Object, ? extends Object> map的函数,我可以将它用于这两种类型的映射。

任何建议表示赞赏,谢谢! 托马斯


编辑:我添加了一些非常基本的内省来使该函数与泛型一起工作。我可以确认在使用密钥集时我仍然得到空值,而我按照下面的建议使用了入口集。这是我下面的代码(第一个函数工作正常,而第二个函数返回null元素。

// 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;
}

2 个答案:

答案 0 :(得分:1)

您可能已将NULL键字符串插入到地图中。使用HashMap时可以这样做。 尽量避免添加NULL键。此外,您可以使用TreeMap。

再见迭代条目集的方式,你可以清理你的代码 通过在function2中使用foreach,就像在function1中一样:

这看起来像是:

for(Entry<String, Float> entry : map.entrySet()) {
    Float val = entry.getValue();
}

虽然没有必要清理function2。 但是你应该找到将NULL键插入地图的位置。

答案 1 :(得分:0)

function1使用foreach循环,当map为null时将抛出NullPointerException。 在使用foreach

进行迭代之前,应该检查映射是否为null

此外你应该重写丑陋的

if("java.lang.String".equalsIgnoreCase(entry.getKey().getClass().getName())) {

 if (entry.getKey().getClass() == String.class) {