4

このメソッドを適切にジェネリックにして、警告をなくす方法はありますか?

/**
 * <p>Sort a collection by a certain "value" in its entries. This value is retrieved using
 * the given <code>valueFunction</code> which takes an entry as argument and returns
 * its value.</p>
 * 
 * <p>Example:</p>
 * <pre>// sort tiles by number
 *Collects.sortByValue(tileList, true, new Function<Integer,NormalTile>() {
 *  public Integer call(NormalTile t) {
 *      return t.getNumber();
 *  }
 *});</pre>
 *
 * @param list The collection.
 * @param ascending Whether to sort ascending (<code>true</code>) or descending (<code>false</code>).
 * @param valueFunction The function that retrieves the value of an entry.
 */
public static <T> void sortByValue(List<T> list, final boolean ascending, @SuppressWarnings("rawtypes") final Function<? extends Comparable, T> valueFunction) {
    Collections.sort(list, new Comparator<T>() {
        @SuppressWarnings({ "unchecked", "rawtypes" })
        @Override public int compare(T o1, T o2) {
            final Comparable v1 = valueFunction.call(o1);
            final Comparable v2 = valueFunction.call(o2);
            return v1.compareTo(v2) * (ascending ? 1 : -1);
        }
    });
}

試しFunction<? extends Comparable<?>, T>てみFunction<? extends Comparable<? extends Comparable>, T>ましたが、どちらもコンパイルせず、への呼び出しでエラーが発生しましたcompareTo。前者の場合:

タイプ Comparable のメソッド compareTo(capture#9-of ?) は引数に適用できません (capture#10-of ? extends Comparable)

4

3 に答える 3

5

これを試して:

public static <T, C extends Comparable<? super C>> void sortByValue(List<T> list, final boolean ascending, final Function<C, T> valueFunction) {
    Collections.sort(list, new Comparator<T>() {
        @Override public int compare(T o1, T o2) {
            final C v1 = valueFunction.apply(o1);
            final C v2 = valueFunction.apply(o2);
            return v1.compareTo(v2) * (ascending ? 1 : -1);
        }
    });
}

superサブタイプに定義されたコンパレータを許可する必要もあります。詳細はこちら: http://docs.oracle.com/javase/tutorial/extra/generics/morefun.html

アップデート

また、あなたのコードを見ると、さらに別の自転車が見えます。Google Collections という優れたライブラリがあり、それを処理するための非常に便利な順序付けの概念を提供します。

したがって、コードは次のようになります。

Ordering<NormalTile> myOrdering = Ordering.natural()
  .onResultOf(new Function<Integer,NormalTile>() {
  public Integer call(NormalTile t) {
      return t.getNumber();
  }))
  .nullsLast();
...
Collections.sort(list, myOrdering);
//or
newList = myOrdering.sortedCopy(readonlyList);
于 2011-12-07T13:03:54.433 に答える
2

これは私にとってはうまくいきます(Eclipseコンパイラ)

public static <T, U extends Comparable<U>> void sortByValue(
  List<T> list, final boolean ascending, final Function<U, T> valueFunction) {

  Collections.sort(list, new Comparator<T>() {
    @Override
    public int compare(T o1, T o2) {
      final U v1 = valueFunction.call(o1);
      final U v2 = valueFunction.call(o2);
      return v1.compareTo(v2) * (ascending ? 1 : -1);
    }
  });
}

他の人が投稿したように、さらに進んで次のように宣言することもできUます

U extends Comparable<? super U>

より多くのメソッド引数/戻り値がある場合、これは便利ですU

于 2011-12-07T13:02:44.483 に答える
1

関数の2つのパラメーターを宣言するとどうなりますか?

public static <T,C extends Comparable<C>> void sortByValue(List<T> list,
    final boolean ascending, final Function<C, T> valueFunction) {
...
final C v1 = ...
final C v2  ...

コンパイラで健全性をチェックしたことはありませんが(インターフェイスがなく、空腹すぎてモックできません:))、試してみてください。

私はまた、それがそうであるべきかどうかについて推論するにはあまりにも不機嫌C extends Comparable<C>ですC extends Comparable<? super C>。前者は機能し、少し一般的だと思いますが、実際には、ほとんどのクラスは、それ自体を除いてComparableを実装していません。

于 2011-12-07T12:59:45.900 に答える