1

ここにある非常に優れたソートソリューションを実装しました:

static <K,V extends Comparable<? super V>> SortedSet<Map.Entry<K,V>>
entriesSortedByValues(Map<K,V> map) {

    SortedSet<Map.Entry<K,V>> sortedEntries = new TreeSet<Map.Entry<K,V>>(

        new Comparator<Map.Entry<K,V>>() {
            @Override
            public int compare(Map.Entry<K,V> e1, Map.Entry<K,V> e2) {
                int res = e1.getValue().compareTo(e2.getValue());
                return res != 0 ? res : 1;
            }
        }
    );

    sortedEntries.addAll(map.entrySet());
    return sortedEntries;
}

コードはうまくいくようです。ただし、FindBugs は次の行について不平を言っています。

sortedEntries.addAll(map.entrySet());

苦情は次のとおりです。

バグ: com.local.sem.util.MapUtil.entriesSortedByValues(Map) で Map.Entry オブジェクトが再利用されるため、エントリ セットの要素の追加が失敗する場合があります。

entrySet() メソッドは、基礎となる Map のビューを返すことができます。このビューでは、反復中に単一の Entry オブジェクトが再利用されて返されます。Java 1.6 では、IdentityHashMap と EnumMap の両方がそうしました。このような Map を反復する場合、Entry 値は次の反復に進むまでのみ有効です。たとえば、そのような entrySet を addAll メソッドに渡そうとすると、事態は大きく悪化します。

Confidence : Normal, Rank : Trouble (14)
Pattern : DMI_ENTRY_SETS_MAY_REUSE_ENTRY_OBJECTS
Type : DMI, Category : BAD_PRACTICE (Bad practice)

それが何を意味するのか、または実際にこの特定のコードに関連しているかどうかを誰か教えてもらえますか?

4

2 に答える 2

3

問題の簡単な例を次に示します。

Map<String,String> map = new IdentityHashMap<String,String>();
map.put("a", "1");
map.put("b", "2");
Iterator<Entry<String,String>> i = map.entrySet().iterator();
Entry<String,String> e1 = i.next();
System.out.println("first key is: " + e1.getKey());
Entry<String,String> e2 = i.next();
System.out.println("first key is now: " + e1.getKey());

Java 6 を使用すると、次のように出力されます。

first key is: a
first key is now: b

これは、i.next() への 2 回目の呼び出しが最初の呼び出しと同じエントリを返しますが、そのエントリに格納されている値が変更されているためです。

IdentityHashMap を HashMap に変更すると、返される各エントリが異なるため、e1.getKey() は変更されません。

于 2012-08-08T17:59:23.643 に答える
-3

entrySet() メソッドは、基礎となる Map のビューを返すことができます。このビューでは、反復中に単一の Entry オブジェクトが再利用されて返されます。Java 1.6 では、IdentityHashMap と EnumMap の両方がそうしました。このような Map を反復する場合、Entry 値は次の反復に進むまでのみ有効です。たとえば、そのような entrySet を addAll メソッドに渡そうとすると、事態は大きく悪化します。

詳しくはリンク先をお読みください。http://findbugs.sourceforge.net/bugDescriptions.html#DMI_ENTRY_SETS_MAY_REUSE_ENTRY_OBJECTS

于 2012-08-08T01:56:31.650 に答える