2

私は数時間頭を悩ませましたが、続行する必要があり、醜い回避策を見つけましたが、コードをクリーンアップできれば幸いです。問題は次のとおりです。

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は正しく初期化されており、null値は含まれていません。

ちなみに、引数をMap mapに変更し、文字列のペアのみを使用すると、function1は正常に機能します。私の目標はMap<? extends Object, ? extends Object> map、両方のタイプのマップに使用できるジェネリックスを備えた関数を1つだけにすることです。

どんな提案もありがたいです、ありがとう!トーマス


編集:関数をジェネリックスで機能させるために、いくつかの非常に基本的なイントロスペクションを追加しました。エントリセットを使用するために以下の提案に従いましたが、キーセットを使用してもまだnull値を取得していることを確認できます。以下に私のコードを示します(最初の関数は正常に機能し、2番目の関数は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;
}
4

2 に答える 2

1

マップに NULL キー文字列を挿入した可能性があります。これは、HashMap を使用する場合に可能です。NULL キーを追加しないようにしてください。さらに、TreeMap を使用できます。

ところで、エントリ セットを繰り返し処理することは悪くありません。関数 1 で行ったように、関数 2 で foreach を使用してコードをクリーンアップできます。

これは次のようになります。

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

function2 をクリーンアップする必要はありませんが。ただし、マップに NULL キーを挿入した場所を見つける必要があります。

于 2012-11-18T13:33:09.757 に答える
0

function1 は foreach ループを使用し、マップが null の場合に NullPointerException をスローします。foreach で反復する前に、マップが null でないことを確認する必要があります

さらにあなたは醜いものを書き直す必要があります

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

 if (entry.getKey().getClass() == String.class) {
于 2012-11-18T17:50:05.330 に答える