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

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

我一直在分析 Java SE 8 中的 Comparator 接口。现在,我很想知道如何使用实现 class 的 reverseOrder() 方法=14=]界面。我写了一个示例程序来检查它。

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() 方法。为什么 ? class NaturalOrderString 实现 Comparator<T>

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

此外,我了解到列表中的排序是使用自然排序发生的。因此,使用 Collection class 我可以访问 reverseOrder() 方法。所以,在我的例子之前,我可以愉快地写

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

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

或者,如果关于我的代码确实可以通过 mycom 对象访问 reverseOrder(),请给我一个例子。

基本上这里可以施展很多魔法。

为了反向排序,您只需要"reverse"比较的结果。

你可以研究这些foils。它们是用德语写的,但是那里的文字不多——而且代码都是 java。该演示文稿提供了一些 lambda 基础知识;然后解释如何使用 lambda 和方法引用来开发一个完整的系统,您可以在其中 sort/reverse 对流进行排序;使用 "accessor" 对象从您打算排序的事物中检索任何属性。

例如导致:

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

现在可以实现那个接口了,反向排序是免费的。

因为Comparator.reverseOrder是静态方法

来自JLS

[8.4.8] A class does not inherit static methods from its superinterfaces.

如果要使用此方法,直接调用Comparator.reverseOrder()即可。但是,听起来这不是您真正想要的 - 请改用非静态 reversed()

Comparator.reverseOrder() 方法简单地委托给 Collections.reverseOrder()Collections.reverseOrder() 简单地 returns 一个实现反向自然排序的比较器。

您要做的事情很简单:

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

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

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

首先,根据您的问题,由于 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.

     }
  }

希望您现在已经清楚了这个概念。

Can I use Comparator.reverseOrder()

是的,当然可以。由于编译器会推断出很多信息,所以您可能会如何使用它并不是很明显。

签名是:

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

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

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

reverseOrder 不带任何参数,但 returns 我们传入一个 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]

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