递归泛型

时间:2011-12-07 12:53:54

标签: java generics unchecked

有没有办法让这个方法适当通用并取消警告?

/**
 * <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(捕获#9-of?)方法不适用于参数(捕获#10-of?extends Comparable)

3 个答案:

答案 0 :(得分: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概念来处理它。

所以,你的代码看起来像是:

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);

答案 1 :(得分: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

,这将派上用场

答案 2 :(得分:1)

如果为函数声明两个参数怎么办?

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。