Recursive generics

隐身守侯 提交于 2019-12-05 12:22:27

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

This works for me (Eclipse compiler)

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

As others posted, you may even go further and declare U as

U extends Comparable<? super U>

That will come in handy if you have more method arguments / return values depending on U

What if you declare two parameters for the function?

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  ...

Haven't sanity checked myself with a compiler (don't have your interfaces and am too hungry to mock them :) ), but give it a shot.

I'm also too groggy to reason over whether it should be C extends Comparable<C> or C extends Comparable<? super C>. I think the former would work and be a tad more general, although in practice, most classes don't implement Comparable except against themselves.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!