在对Comparable
s和Comparator
s进行了一些研究之后,我遇到了一些看起来有用的有趣语法(我不明白)。
例:
public static Comparator<Type> TypeComparer = new Comparator<Type>() {
public int compare(Type a, Type b) {
return a.compareTo(b);
}
}
我真的很想知道这里发生了什么。我永远不会想到在定义方法时使用=
运算符。这是一种方法吧?或者一个包含方法的变量?
我将如何使用此对象?如果我可以打电话,我应该期望退货什么?
如果您想查看原始示例,请参阅博客文章
TypeComparer
不是一个静态方法,它是一个静态字段。
让我们逐部分演练语法:
public static Comparator<Type> TypeComparer = ...
声明一个字段。它的名字是TypeComparer
,类型是Comparator<Type>
。由于Comparator<T>
是一个接口,因此该字段接受实现该接口的任何类的实例。new Comparator<Type>() { ... }
此语法定义一个新类并同时创建其实例。新定义的类没有名称(称为匿名内部类),其唯一的实例分配给TypeComparer
public int compare(Type a, Type b) { ... }
这是匿名比较器类的方法。它实现了完成类所需的Comparator<T>
的方法。
类的用户可以在不知道其确切类型的情况下使用Comparator<Type>
的实例,因为他们可以对其接口进行编程(即调用其compare(...)
方法)。
注意:从 Java 8 开始,您可以将上述示例缩短为一行:
public static Comparator<Type> TypeComparer = (a, b) -> {return a.compareTo(b);};
我将如何使用这个对象?如果我 可以叫吗?
使用匿名类是因为不需要创建命名类。它们使您能够同时声明和实例化类。
仅当您想要定义仅在声明它的类的框架中使用的实现时,它才有意义。
否则,创建命名类更相关,因为它允许使该类更容易/自然地被客户端类使用。
使用命名类(public
或任何访问修饰符)可以编写:
public class MyComparator implements Comparator<Type> {
public int compare(Type a, Type b) {
return a.compareTo(b);
}
}
然后你可以使用它:
Collections.sort(myList, new MyComparator();
使用匿名类,您编写:
Comparator<Type> typeComparer = new Comparator<Type>() {
public int compare(Type a, Type b) {
return a.compareTo(b);
}
};
并将变量用作任何变量:
Collections.sort(myList, typeComparer);
您甚至可以通过消除variable
来缩短它:
Collections.sort(myList, new Comparator<Type>() {
public int compare(Type a, Type b) {
return a.compareTo(b);
}
});
如您所见,它生成的代码较少,但可读性不强。
Java 8解决了这个问题。
您可以使用 lambda 表达式:
Collections.sort(myList, (a, b) -> a.compareTo(b));
或方法引用(lambda 表达式较短版本):
Collections.sort(myList, Comparable::compareTo);
或Comparator.comparing() static
方法:
Collections.sort(myList, Comparator.comparing(Comparator.naturalOrder());