简体   繁体   English

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

[英]Is it possible to implement reverseOrder() method using Comparator<T>?

I have been analyzing with Comparator interface in Java SE 8. Now, I am interested to know that how could I use reverseOrder() method using a class which implements the Comparator<T> interface. 我一直在使用Java SE 8中的Comparator接口进行分析。现在,我有兴趣知道如何使用实现Comparator<T>接口的类来使用reverseOrder()方法。 I wrote to a example program to check that out. 我写了一个示例程序来检查出来。

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

So, now I should be able to use all the methods associated with Comparator Interface. 所以,现在我应该能够使用与Comparator Interface相关的所有方法。 But surprisingly whey I type mycom. 但令人惊讶的是,我输入了mycom. then there comes no suggestion for reverseOrder() method. 然后没有建议使用reverseOrder()方法。 Why ? 为什么? The class NaturalOrderString implements Comparator<T> . NaturalOrderString类实现了Comparator<T>

So, I should accept mycom object to access reverseOrder() method. 所以,我应该接受mycom对象来访问reverseOrder()方法。 Isn't it ? 不是吗?

Moreover, I came to know that sorting in lists are occurred using natural ordering . 而且,我开始知道列表中的排序是使用自然排序发生的。 So, using the Collection class I could access reverseOrder() method. 因此,使用Collection类我可以访问reverseOrder()方法。 So, preceding my example I could happily write 所以,在我的例子之前,我可以高兴地写

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

But my question is why I can't use reverseOrder() using a object of a class which implements Comparator<T> ? 但我的问题是为什么我不能使用reverseOrder()使用实现Comparator<T>的类的对象? And, since we can't access it why Java include reverseOrder() method in Comparator<T> interface ? 而且,既然我们无法访问它,为什么Java在Comparator<T>接口中包含reverseOrder()方法?

Or, if it's really possible to access reverseOrder() through mycom object regarding my code, please give me an example of it. 或者,如果真的可以通过关于我的代码的mycom对象访问reverseOrder() ,请给我一个例子。

Basically a lot of magic is possible here. 基本上这里可能有很多魔法。

In order to reverse sorting, you simply need to "reverse" the result of the comparation. 为了反向排序,您只需要“反转”比较结果。

You can study these foils . 你可以研究这些 They are written in German, but there isn't much text there - and the code is all java. 它们是用德语编写的,但那里没有太多文本 - 代码都是java。 The presentation gives some lambda basics; 演示文稿给出了一些lambda基础知识; to then explain how you can use lambdas and method references to develop a whole system where you sort/reverse sort streams; 然后解释如何使用lambdas和方法引用来开发一个整个系统,在这个系统中对流进行排序/反向排序; using "accessor" objects to retrieve whatever properties from the things you intend to sort. 使用“访问器”对象从您要排序的事物中检索任何属性。

For example leading to: 例如导致:

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

Now one can implement that interface, and reverse sorting comes for free. 现在可以实现该接口,并且免费提供反向排序。

The Comparator.reverseOrder() method simply delegates to Collections.reverseOrder() and Collections.reverseOrder() simply returns a comparator which implements reverse natural ordering. Comparator.reverseOrder()方法只是委托给Collections.reverseOrder()Collections.reverseOrder()只返回一个实现反向自然排序的比较器。

What you are trying to do is as simple as this: 你要做的就是这么简单:

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

which can also be achieved with myComparator.reversed() . 也可以使用myComparator.reversed()实现。

Basically reverseOrder() method will return a comparator that imposes the reverse of the natural ordering. 基本上,reverseOrder()方法将返回一个比较器,它强加了自然顺序的反转。

Firstly, following your question, since reverseOrder() is a static method you can't use it like mycom.reverseOrder(). 首先,按照你的问题,因为reverseOrder()是一个static method你不能像mycom.reverseOrder()那样使用它。 You have to use like Comparot.reverseOrder(). 你必须像Comparot.reverseOrder()一样使用。 Following your code. 关注你的代码。 I created a ArrayList to demonstrate and use Comparator.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.

     }
  }

Hope you are now clear with this concept. 希望你现在对这个概念很清楚。

Because Comparator.reverseOrder is a static method. 因为Comparator.reverseOrder是一个静态方法。

From the JLS : 来自JLS

[8.4.8] A class does not inherit static methods from its superinterfaces. [8.4.8]类不从其超接口继承静态方法。

If you want to use this method, you can just call it as Comparator.reverseOrder() . 如果要使用此方法,可以将其称为Comparator.reverseOrder() However, it sounds like that's not what you actually want - use the non-static reversed() instead. 然而,听起来这并不是你真正想要的 - 而是使用非静态reversed()

Can I use Comparator.reverseOrder() 我可以使用Comparator.reverseOrder()吗?

Yes, of course you can. 是的,当然可以。 It's just not immediately obvious how you might use it because the compiler infers a lot of information. 由于编译器会推断出大量信息,因此您可能无法立即使用它。

The signature is: 签名是:

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

So as you can see, it takes a generic type, which must implement Comparable . 正如您所看到的,它需要一个泛型类型,它必须实现Comparable It's somewhat more strict than that: it requires the type to be comparable to either itself or one of its super types. 它比那更严格:它要求类型可以与其自身或其超类型相媲美。 We couldn't get a reverse comparator for Apple, using these definitions: 我们无法使用这些定义获得Apple的反向比较器:

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

reverseOrder takes no arguments but returns us a Comparator of the type we pass in. You can use it like so: reverseOrder不带参数,但返回我们传入的类型的Comparator 。你可以像这样使用它:

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

Here's a full, compilable example: 这是一个完整的,可编译的例子:

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

Sample output: 样本输出:

[Foo 5, Foo 3, Foo 1] [Foo 5,Foo 3,Foo 1]

In practice you can remove <Foo> from Comparator.<Foo> because the compiler is able to work out what you need. 在实践中,您可以从Comparator.<Foo>删除<Foo> ,因为编译器能够找出您需要的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM