web-dev-qa-db-ja.com

JavaコンパイラがHashMapの値の型としてプリミティブintを好まないのはなぜですか?

コンパイラはこのコードについて文句を言います:

    HashMap<String,int> userName2ind = new HashMap<String,int>();
    for (int i=0; i<=players.length; i++) {
        userName2ind.put(orderedUserNames[i],i+1);
    }

「予期しないタイプ」と書き込み、intを指します。 intStringに置き換え、i+1i+"1"に置き換えると、コンパイルは正常に行われます。ここの何が問題になっていますか?

27
Roman

Integerでは問題ありませんが、int -- Javaジェネリックは参照型でのみ機能します 、基本的には:(

これを試してください-すべてをボックス化することに注意してください:

HashMap<String,Integer> userName2ind = new HashMap<String,Integer>();
for (int i=0; i<=players.length; i++) {
    userName2ind.put(orderedUserNames[i],i+1);
}
41
Jon Skeet

コレクションが小さい場合は、参照型を使用することはおそらく問題ありませんが、代替手段があり、適切なものは trove4j です。 Troveは、純粋なプリミティブを使用してコレクションAPIを再作成するという非常に優れた仕事をしています。見返りは、はるかにメモリ使用量が少なく、多くの場合、挿入/検索時のパフォーマンスが向上することです。あなたの例は次のようになります:

TObjectIntHashMap<String> userName2ind = new TObjectIntHashMap<String>();
for (int i=0; i<=players.length; i++) {
    userName2ind.put(orderedUserNames[i],i+1);
}

私の経験では、唯一の欠点はこれらの同時実装がないことです。そのため、スレッドセーフを管理する別の方法を考え出す必要があります。

2
Nicholas