是否可以使用Comparator <t>实现reverseOrder()方法?

时间:2017-06-09 09:05:11

标签: java comparator

我一直在使用Java SE 8中的Comparator接口进行分析。现在,我有兴趣知道如何使用实现reverseOrder()接口的类来使用Comparator<T>方法。我写了一个示例程序来检查它。

class NaturalOrderString implements Comparator<String>{
    @Override
    public int compare(String o1, String o2) {
        // TODO Auto-generated method stub
        return o1.compareTo(o2);
    }               
} 

public class App {
  public static void main(String[] args) { 
      Comparator<String> mycom= new NaturalOrderString();

      mycom.reverseOrder(); // can't use this
   }
}

所以,现在我应该能够使用与Comparator接口相关的所有方法。但令人惊讶的是,我键入mycom.然后没有建议使用reverseOrder()方法。为什么? 班级NaturalOrderString实施Comparator<T>

因此,我应该接受mycom个对象来访问reverseOrder()方法。不是吗?

此外,我发现列表中的排序是使用自然排序进行的。因此,使用集合类,我可以访问reverseOrder()方法。所以,在我的例子之前我很乐意写

Collections.reverseOrder(mycom); // that's fine.

但我的问题是为什么我不能使用reverseOrder()使用实现Comparator<T>的类的对象?而且,既然我们无法访问它,为什么Java在reverseOrder()接口中包含Comparator<T>方法呢?

或者,如果我的代码真的可以通过 mycom 对象访问reverseOrder(),请举个例子。

5 个答案:

答案 0 :(得分:3)

基本上这里有很多魔法。

为了反向排序,您只需要“反转”比较结果。

您可以研究这些foils。它们是用德语编写的,但那里没有太多文本 - 代码都是java。演示文稿给出了一些lambda基础知识;然后解释如何使用lambdas和方法引用来开发一个整个系统,在这个系统中对流进行排序/反向排序;使用“访问器”对象从您想要排序的东西中检索任何属性。

例如导致:

interface Comparator<T> {
  public int compare(T a, T b);
  public default Comparator<T> reversed() {
    return (a, b) –> compare(b, a) ;
}

现在可以实现该接口,并且免费提供反向排序。

答案 1 :(得分:1)

Comparator.reverseOrder()方法只需委托给Collections.reverseOrder(),而Collections.reverseOrder()只返回一个实现反向自然排序的比较器。

你要做的就是这么简单:

@Override
public int compare(String o1, String o2) 
{
    int d = o1.compareTo(o2);
    return -d;

也可以使用myComparator.reversed()实现。

答案 2 :(得分:1)

基本上,reverseOrder()方法将返回一个比较器,它强加了自然顺序的反转。

首先,关注您的问题,因为reverseOrder()是 static method ,您不能像mycom.reverseOrder()那样使用它。你必须像Comparot.reverseOrder()一样使用。 关注你的代码。我创建了一个ArrayList来演示和使用Comparator.reverseOrder()

public class App {

public static void main(String[] args) {
    // TODO Auto-generated method stub

    List<String> people= new ArrayList<String>();
    people.add("Sam");
    people.add("Bob");
    people.add("Andrew");
    people.add("Michel");
    people.add("Abe");
    people.add("John");

    Comparator<String> mycom= new NaturalOrderString();

    Collections.sort(people); // this will sort the people array list in natural order

    Collections.sort(people,Comparator.reverseOrder()); // Here's your desired method it will reverse the natural order as documentation.

     }
  }

希望你现在对这个概念很清楚。

答案 3 :(得分:0)

因为Comparator.reverseOrder是静态方法。

来自JLS

  

[8.4.8] 类不会从其超接口继承静态方法。

如果您想使用此方法,可以将其称为Comparator.reverseOrder()。然而,听起来这并不是你真正想要的 - 而是使用非静态reversed()

答案 4 :(得分:0)

  

我可以使用Comparator.reverseOrder()

是的,当然可以。由于编译器会推断出大量信息,因此您不会立即明白如何使用它。

签名是:

static <T extends Comparable<? super T>> Comparator<T> reverseOrder()

正如您所看到的,它需要一个通用类型,它必须实现Comparable。它比这更严格一些:它要求类型可以与其自身或其超类型相媲美。我们无法使用这些定义为Apple获得反向比较器:

public class Orange { }
public class Apple implements Comparable<Orange> { /* methods */ }

reverseOrder不接受任何参数,但返回我们传入的Comparator类型。您可以像这样使用它:

Comparator<Foo> reverseCompatator = Comparator.<Foo>reverseOrder();

这是一个完整的,可编辑的例子:

// Simply wraps an integer value
class Foo implements Comparable<Foo>
{
    private final Integer value;

    Foo(final Integer value) {
        this.value = value;
    }

    public int compareTo(Foo that) {
        // use standard integer comparison (i.e. 1,2,3,4,5,...)
        return this.value.compareTo(that.value);
    }

    @Override
    public String toString() {
        return "Foo " + value;
    }
}

public class Main
{
    public static void main (String[] args)
    {
        // create a list
        List<Foo> foos = Arrays.asList(new Foo(1), new Foo(3), new Foo(5));

        // sort the list in reverse
        foos.sort(
            Comparator.<Foo>reverseOrder()
        );

        System.out.println(foos);
    }
}

示例输出:

  

[Foo 5,Foo 3,Foo 1]

实际上,您可以从<Foo>中删除Comparator.<Foo>,因为编译器能够找到您需要的内容。