45

ジェネリックを使用してマップの配列を宣言し、マップ タイプを指定できます。

private Map<String, Integer>[] myMaps;

ただし、適切にインスタンス化する方法がわかりません。

myMaps = new HashMap<String, Integer>[count]; // gives "generic array creation" error
myMaps = new HashMap[count]; // gives an "unchecked or unsafe operation" warning
myMaps = (Map<String, Integer>[])new HashMap[count]; // also gives warning

コンパイラ エラーや警告を表示せずに、このマップの配列をインスタンス化するにはどうすればよいですか?

アップデート:

返信ありがとうございます。私は最終的にリストの提案に行きました。

4

8 に答える 8

47

あなたの質問に対する厳密な回答ではありませんが、List代わりに a を使用することを検討しましたか?

List<Map<String,Integer>> maps = new ArrayList<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());

うまくいくようです。

配列とジェネリックを混在させることが推奨されない理由の詳細な説明については、Java の理論と実践: ジェネリックの落とし穴を参照してください。

アップデート:

コメントで Drew が述べたように、 Collection の代わりにCollectionインターフェイスを使用する方が良い場合がありますList。これは、Set、または の他のサブインターフェイスの 1 つに変更する必要がある場合に便利ですCollection。コード例:

Collection<Map<String,Integer>> maps = new HashSet<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());

この開始点から、 、、または を実装する他のクラスに変更HashSetするだけで済みます。ArrayListPriorityQueueCollection

于 2009-09-29T15:17:56.033 に答える
26

ジェネリック配列を安全に作成することはできません。効果的なJava2ndEditionは、ジェネリックスの章で詳細に説明されています。119ページの最後の段落から始めます。

ジェネリック配列を作成することが違法なのはなぜですか?タイプセーフではないからです。それが合法である場合、そうでなければ正しいプログラムでコンパイラーによって生成されたキャストは、実行時に。で失敗する可能性があります ClassCastException。これは、ジェネリック型システムによって提供される基本的な保証に違反します。

これをより具体的にするために、次のコードフラグメントを検討してください。

// Why generic array creation is illegal - won't compile!
List<String>[] stringLists = new List<String>[1]; // (1)
List<Integer> intList = Arrays.asList(42); // (2)
Object[] objects = stringLists; // (3)
objects[0] = intList; // (4)
String s = stringLists[0].get(0); // (5)

ジェネリック配列を作成する1行目が正当であると仮定しましょう。List<Integer>2行目では、単一の要素を含むを作成して初期化します 。3行目では、 List<String>配列をObject 配列変数に格納しています。これは、配列が共変であるため有効です。4行目は、を配列List<Integer>の唯一の要素に格納しObjectます。これは、ジェネリックが消去によって実装されるため成功します。インスタンスのランタイムタイプList<Integer>は単純であり、インスタンスのListランタイムタイプ はであるため、この割り当てでは。は生成されません 。今、私たちは困っています。 のみを保持するように宣言された配列にインスタンスを格納しましたList<String>[]List[]ArrayStoreExceptionList<Integer>List<String> インスタンス。5行目では、この配列の唯一のリストから唯一の要素を取得します。コンパイラは取得した要素を自動的ににキャストしますStringが、これはであるため、実行時Integerに取得 します。ClassCastExceptionこれを防ぐために、1行目(ジェネリック配列を作成)はコンパイル時エラーを生成します。

配列とジェネリックスは(他の理由と同様に)うまく組み合わされないため、一般的には配列よりもCollectionオブジェクト(特にオブジェクト)を使用する方が適切です。List

于 2009-09-29T15:22:19.723 に答える
6

一般に、Java でジェネリックと配列を混在させることはお勧めできません。ArrayList を使用することをお勧めします。

配列を使用する必要がある場合、これを処理する最善の方法は、配列の作成 (例 2 または 3) を別のメソッドに入れ、@SuppressWarnings("unchecked") で注釈を付けることです。

于 2009-09-29T15:11:23.080 に答える
2

簡単な答えは、あなたが本当にできないということのようです。

それについてのブログについては、以下を参照してください。 http://www.bloggingaboutjava.org/2006/01/java-generics-quirks/

ブログへのコメントの1つは、次のように述べています。

実際、エンジニアはそのようなアレイの作成を違法にしました。したがって、ジェネリッククラスからの配列の作成は失敗します。Collection.toArrayメソッドとそれに続くCasttothe Arrayは、コンパイル時に機能します。

これは、実行時にArrayStoreCheckを実行できないという問題を解決しませんが、この方法でジェネリックの配列を作成できます。

トカゲのビルが提案したように、おそらくあなたは

List<Map<String,Integer>>
于 2009-09-29T15:19:07.577 に答える
-2

私は同様の質問をしました、私がこれを参照した最高の応答

于 2009-09-29T15:23:19.350 に答える
-5
myMaps = new HashMap<String, Integer>[10]();

だからそれは間違っている

配列を作成しようとする代わりに、マップのリストを作成してみませんか?

List<Map<String, Integer>> mymaps = new ArrayList<Map<String, Integer>>(count);
于 2009-09-29T15:08:26.350 に答える