递归泛型 [英] Recursive generics

查看:125
本文介绍了递归泛型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法让这个方法适当的泛化,并取消警告?

  / ** 
*< p>通过条目中的某个值对集合进行排序。使用
*给定的< code> valueFunction< / code>它将一个条目作为参数并返回
*其值。< / p>
*
*< p>示例:< / p>
*< pre> //按数字排序图块
* Collects.sortByValue(tileList,true,new函数< Integer,NormalTile>(){
* public Integer call(NormalTile t) {
* return t.getNumber();
*}
*});< / pre>
*
* @param list集合。
* @param ascending是否按升序(< code> true< / code>)或降序(< code> false< / code>)进行排序。
* @param valueFunction检索条目值的函数。
* /
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比较v1 = valueFunction.call(o1);
final比较v2 = valueFunction.call(o2);
返回v1.compareTo(v2)*(升序?1:-1);
}
});
}

我试过函数< ;?扩展Comparable<?>,T> 函数< ;?扩展Comparable< ;?扩展Comparable> ;, T> ,但都不编译,并且调用 compareTo 时出错。对于前者,即:


类型Comparable中的方法compareTo(capture#9-of?)不适用于参数capture#10-of?extends Comparable)



解决方案

试试这个:

  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)* (升序?1:-1);
}
});
}

您还需要 super 允许为子类型定义比较器。这里有更多解释: http://docs.oracle.com/javase/tutorial /extra/generics/morefun.html



更新

另外,看看你的代码,我又看到了另一辆自行车,有一个很好的图书馆Google Collections,它提供了非常方便的 Ordering 概念来处理它。

所以,你的代码看起来像这样: / p>

 排序< NormalTile> myOrdering = Ordering.natural()
.onResultOf(new Function< Integer,NormalTile>(){
public Integer call(NormalTile t){
return t.getNumber();
}))
.nullsLast();
...
Collections.sort(list,myOrdering);
//或
newList = myOrdering.sortedCopy(readonlyList);


Is there a way to make this method properly generic and do away with the warnings?

/**
 * <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);
        }
    });
}

I tried Function<? extends Comparable<?>, T> and Function<? extends Comparable<? extends Comparable>, T> but neither compiled, with an error on the call to compareTo. For the former that is:

The method compareTo(capture#9-of ?) in the type Comparable is not applicable for the arguments (capture#10-of ? extends Comparable)

解决方案

Try this:

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

you also need the super to allow comparators defined for sub types. More explanations here: http://docs.oracle.com/javase/tutorial/extra/generics/morefun.html

UPDATE

Also, looking at your code I see yet another bicycle, there is a good library the Google Collections, which provides very convenient Ordering notion to handle it.

So, your code would look like:

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

这篇关于递归泛型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆