有没有办法让这个方法适当通用并取消警告?
/**
* <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)
答案 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。