76

重複の可能性:
Javaコレクションにプリミティブ値を格納しますか?

私が次を使用するときのJavaで:-

public HashMap<char, int> buildMap(String letters)
{
    HashMap<char, int> checkSum = new HashMap<char, int>();

    for ( int i = 0; i < letters.length(); ++i )
    {
        checkSum.put(letters.charAt(i), primes[i]);
    }

    return checkSum;
}

不適切なタイプに関連するエラーが発生します。charとintの代わりに、それぞれCharacterとIntegerを使用して、問題を解決しました。ただし、HashMapがプリミティブデータ型を処理できない理由を理解するのに苦労しています。

4

7 に答える 7

139

ジェネリックパラメーターは、プリミティブ型ではなく参照型にのみバインドできるため、対応するラッパー型を使用する必要があります。HashMap<Character, Integer>代わりに試してください。

ただし、HashMapがプリミティブデータ型を処理できない理由を理解するのに苦労しています。

これは型消去によるものです。Javaには最初からジェネリックがなかったので、aHashMap<Character, Integer>は実際にはHashMap<Object, Object>です。コンパイラは、間違ったタイプの値を入力したり、間違ったタイプを取得したりしないように、一連の追加のチェックと暗黙的なキャストを実行しますが、実行時にはHashMapクラスが1つだけで、オブジェクトを格納します。

他の言語はタイプを「特殊化」するため、C ++では、aは内部とvector<bool>は大きく異なり、共通のスーパータイプvector<my_class>を共有しません。vector<?>ただし、Javaは、プレジェネリックコードとの下位互換性のためにaList<T> List何であるかに関係なく、物事を定義します。Tジェネリック型のすべてのパラメーター化に対して単一の実装クラスが必要であるというこの下位互換性の要件により、ジェネリックパラメーターをプリミティブにバインドできるようなテンプレートの特殊化が妨げられます。

于 2012-11-04T05:32:16.907 に答える
14

ジェネリックスは、キーワードの形式でプリミティブ型を使用できません。

使用する

public HashMap<Character, Integer> buildMap(String letters)
{
    HashMap<Character, Integer> checkSum = new HashMap<Character, Integer>();

    for ( int i = 0; i < letters.length(); ++i )
    {
        checkSum.put(letters.charAt(i), primes[i]);
    }

    return checkSum;
}

更新: Java 7以降では、diamond演算子を使用できます。

HashMap<Character, Integer> checkSum = new HashMap<>();
于 2012-11-04T05:33:43.440 に答える
3

ジェネリックスはオブジェクトタイプのみをサポートし、プリミティブはサポートしません。C ++テンプレートとは異なり、ジェネリックはコード生成を必要とせず、使用するジェネリックタイプの数に関係なく、HashMapコードは1つだけです。

Trove4Jは、プリミティブを使用するために選択されたコレクションを事前に生成することでこれを回避し、必要に応じてサポートするためにラップできるTCharIntHashMapMap<Character, Integer>をサポートします。

TCharIntHashMap:charキーとint値のオープンアドレスマップ実装。

于 2012-11-04T08:18:59.117 に答える
2

ハッシュマップは、を使用することはできますがclasses、を使用することはできませんprimitives。Programmerinterview.comのこのページは、答えを見つけるためのガイドとして役立つ場合があります。正直なところ、私はこの問題の答えを自分で詳しく理解していません。

于 2012-11-04T05:32:52.333 に答える
2

プリミティブ型をコレクションに入れることはできません。ただし、ボックスで許可されている限り、対応するオブジェクトラッパーを使用してそれらを宣言し、プリミティブ値を追加することができます。

于 2012-11-04T05:33:54.227 に答える
2

ジェネリックコレクションクラスは、プリミティブでは使用できません。代わりに、CharacterおよびIntegerラッパークラスを使用してください。

Map<Character , Integer > checkSum = new HashMap<Character, Integer>();

于 2012-11-04T05:34:33.127 に答える
2

GenericsWrapperクラスのみを使用して定義できます。ラッパータイプを使用して定義したくない場合は、以下のようにRaw定義を使用できます。

@SuppressWarnings("rawtypes")
public HashMap buildMap(String letters)
{
    HashMap checkSum = new HashMap();

    for ( int i = 0; i < letters.length(); ++i )
    {
       checkSum.put(letters.charAt(i), primes[i]);
    }
    return checkSum;
}

または、ラッパー型を使用してHashMapを定義し、プリミティブ型を格納します。プリミティブ値はラッパータイプにプロモートされます。

public HashMap<Character, Integer> buildMap(String letters)
{
  HashMap<Character, Integer> checkSum = new HashMap<Character, Integer>();

  for ( int i = 0; i < letters.length(); ++i )
  {
    checkSum.put(letters.charAt(i), primes[i]);
  }
  return checkSum;
}
于 2012-11-04T05:35:32.300 に答える