6

次の実装をタイプセーフな方法で作成する方法はありますか?

public void myMethod( Map<String, ? extends List<String>> map )
{
   map.put("foo", Collections.singletonList("bar");
}

上記の実装は機能しません。メソッドを正しくMap<String, ? super List<String>>コンパイルするには、が必要です。map.put()ただし、myMethodは、この方法でListのサブタイプを受け入れません。だから、Map<String, ? extends List<String>>代わりに使用する必要があります。どうすればこの問題をタイプセーフな方法で解決できますか?

4

4 に答える 4

20
public void myMethod( Map<String, List<String>> map ) {
    map.put("foo", Collections.singletonList("bar") );
}

実際の型は の任意の実装である可能性があるため、 List( の戻り値の型を ofにCollections.singletonList()配置することはできません。たとえば、ジェネリックを aに配置するのは安全ではありません。をのに。Map? extends ListListListMap<String,LinkedList>ListLinkedListLinkedListMap<String,List>

あなたはジェネリックを考えすぎていたと思います。? extends非ジェネリック クラスに使用する必要はありません。たとえば、はList<Object>any を保持しますが、オブジェクトを追加するのに は必要ありません。Aはオブジェクトのみを受け取り、オブジェクトは受け取りません[ジェネリック クラスはパラメーターに基づいて継承しません]。ここで出番です。と の両方をに追加するには、タイプが である必要があります。Object? extendsList<List<Foo>>List<Foo>List<FooSubclass>? extendsList<Foo>List<FooSubclass>ListList<List<? extends Foo>>

于 2009-05-16T02:52:23.727 に答える
6

うまくいきませんMap<String, List<String>か?そこにワイルドカードを持たなければならない特別な理由はありますか?

于 2009-05-16T02:53:08.763 に答える
4

コレクションとジェネリックを一緒に使用する場合、非常に単純な原則があります。これは「Get and The Put Principle」と呼ばれます。

コレクションから値を取得するだけの場合は「extends」ワイルドカードを使用し、コレクションに値を PUT するだけの場合は「super」ワイルドカードを使用し、get と put の両方が必要な場合はワイルドカードを使用しません。

したがって、ご覧のとおり、この原則によれば、最初の例は無効です。

于 2009-10-06T09:44:49.290 に答える
0

誰かがあなたに合格したと想像してくださいMap<String, ArrayList<String>>。入力している値は Collections.singletonList ではない.singletonListの結果ですArrayList

Map で List のサブタイプを受け入れることはできず、互換性のない独自のサブタイプを追加できると期待することはできません。

于 2009-05-16T03:43:10.360 に答える