2016-10-20 2 views
3

パラメータとしてCollection<T>を取得し、要素(マッピング)で何かを行い、Collection<R>を返す汎用メソッドを作成したいとします。 これは、問題ではありません、次の宣言で:今すぐJava generics、nesting型パラメータ

public <R,T> Collection<R> foo(Collection<T> c); 

、私はパラメータの同じ型のコレクションを返すために私の方法を強制したいので、リターンをキャストする必要がなくなります値を特定のコレクションに追加します。このようなもの:

public <R, T, S extends Collection> S<R> foo(S<T> c); 

悲しいことに、これはコンパイルされません。

これは何とかできますか?これを行う正しい方法は何ですか?

+0

あなたは型パラメータトークンをパラメータ化することはできません。(あなたがpolutedヒープを作成している、Cを再利用することはできません)それを行うの

一つの方法は、型を強制収集のためのサプライヤーを提供します。 '...、S extends Collection 'と '(S c)'のようなものがあります。 –

+0

RとTの関係は? – Powerlord

+0

@Powerlord、私はT-> RタイプのMapperを適用したいと思います。 TとRの間には関係がありません。 –

答えて

1

一つの方法は、次の操作を実行することです:

public <R, S, CR extends Collection<R>, CS extends Collection<S>> CR foo(CS c); 

問題があなたの引数と型へのあなたのリターンを結合されます。

+0

コレクションが同じタイプであることを強制したいので、戻り値と私はメソッドを呼び出すたびにキャストする必要はありません –

+0

@orimarcovitch実際にコードを試しましたか?キャスティングは必要ありません。 –

+0

あなたは実際に正しいです!これはうまくいきます! –

-1

Javaでメソッドのオーバーロードを使用することができます。マッピング方法でデータ操作のオーバーロードを試みます。あなたがジェネリックを使用したい場合は、これを行うには

+0

私はあなたのソリューションを本当に理解していませんでしたが、とにかく、オーバーロードでは私の戻り値が私の望むようになるわけではありません... –

0

このように2つのジェネリックを結びつけることはできません。とにかくfooで新しいコレクションを作成する必要がある場合でも、可能です。

public static void callFoo(){ 
    List<String> strings = new ArrayList<>(); 
    ArrayList<Integer> foo = foo(strings, ArrayList::new); 
    } 

    public static <R,T, S extends Collection<R>> S foo(Collection<T> ts, Supplier<S> supplier){ 
    S s = supplier.get(); 
    for(T t:ts){ 
     s.add(null); 
    } 
    return s; 
    } 
関連する問題