2017-11-01 4 views
7

は、私は次のシグネチャを持つメソッドがあると仮定:この方法は、(文字列キーを用いて)機能のマップを受け付けるタイプ安全Comparator.comparing()に渡される関数のインスタンスを作成

<T, U extends Comparable<? super U>> Comparator<T> method(Map<String, Function<? super T, ? extends U>> comparatorFunctionMap) 

および作成します結果としてComparator<T>(それはどのように重要ではない)。マップ値はFunction<? super T, ? extends U>のインスタンスなので、直接Comparator.comparing()に渡すことができます。

タイプセーフな方法でこのマップにデータを設定するにはどうすればよいですか?私は、属性nameageを持つクラスPersonを持っているとしましょう。

は、私は次の操作を行うときは:私が代わりにこれをしようとした場合

Map<String, Function<? super Person, ? extends Comparable>> map1 = new HashMap<>(); 
map1.put("name", Person::getName); 
method(map1); 

私は例えば、ライン1と3の警告を受ける:

Map<String, Function<? super Person, ? extends Comparable<?>>> map2 = new HashMap<>(); 
map2.put("name", Person::getName); 
method(map2); 

三行目は、コンパイルエラーです。

これを安全に行う方法はありますか?

+0

私はあなたの最初のスニペット(生の比較可能性)を使って警告を受け取りません。 – Eran

+1

複数の型を返すにはマップ内の関数が必要ですか?例えば、同じマップが 'Function 'と 'Function 'を保持できる必要がありますか? –

+0

@MikeStrobel:そうですね、考えられるのは異なる比較可能なタイプ(少なくとも文字列と数字ですが、おそらく他のものも可能です)をマップにまとめておくことでした。私は今これが主要な問題だと思う。 – Ondra

答えて

2

Person::getNamePerson::getAgeの両方をマップに追加できるようにするには、String、Integer、Comparableの両方のスーパータイプであるUがないため、提案するメソッドのシグネチャを使用できません。

比較対象がタイプごとに関連していないため、基本的にマップはMap<String, Function<T, Comparable<?>>です。

生の種類を使用せずに回避することはできません。以下のようになります。タイプセーフティがあることに注意してください(マップにComparableを渡す必要があります)。

static void m() { 
    Map<String, Function<Person, Comparable<?>>> map = new HashMap<>(); 
    map.put("name", Person::getName); 
    map.put("age", Person::getAge); 
    Comparator<Person> c = method(map); 
} 


@SuppressWarnings(value = {"unchecked", "rawtypes"}) 
static <T> Comparator<T> method(String name, Map<String, Function<T, Comparable<?>>> comparatorFunctionMap) { 
    Function f = (Function) comparatorFunctionMap.get("age"); 
    Comparator<T> c = Comparator.comparing(f); 
    return c; 
} 

本の唯一の(と思う)の制限は、技術的には、1奇妙なクラスを渡すことができることであるおそらくランタイムエラーを引き起こすWeird implements Comparable<String>を言います。

+0

'getName()'は 'String'を返します。これは' Comparable <?スーパー人物>。 –

+0

@MikeStrobelあなたが正しいです、私は編集しました。 – assylias

+0

@assylias:ありがとう、私は問題が共通のコレクションに異なる比較可能な型を返す関数に適合しようとしていたが、それを正しく表現できないと感じていました。 – Ondra

関連する問題