我一直在使用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()
,请举个例子。
答案 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>
,因为编译器能够找到您需要的内容。