Java 为什么要使用嵌套类来实现Comparator?
浏览docjar forJava 为什么要使用嵌套类来实现Comparator?,java,comparator,comparable,Java,Comparator,Comparable,浏览docjar forString,我碰巧看到了以下代码: public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator(); private static class CaseInsensitiveComparator impl
String
,我碰巧看到了以下代码:
public static final Comparator<String> CASE_INSENSITIVE_ORDER
= new CaseInsensitiveComparator();
private static class CaseInsensitiveComparator
implements Comparator<String>, java.io.Serializable {
// use serialVersionUID from JDK 1.2.2 for interoperability
private static final long serialVersionUID = 8575799808933029326L;
public int compare(String s1, String s2) {
// ...
}
}
公共静态最终比较器大小写不敏感\u顺序
=新的不区分大小写比较器();
私有静态类不区分大小写比较程序
实现Comparator,java.io.Serializable{
//使用JDK 1.2.2中的serialVersionUID实现互操作性
私有静态最终长serialVersionUID=85757998089333029326L;
公共整数比较(字符串s1、字符串s2){
// ...
}
}
我的问题是,为什么我们不能实现Comparator
,比如Comparable
,并使用私有方法而不是嵌套类
另一方面,为什么
Comparator
没有一个类似于compareTo
中的compareTo
的单一参数的方法?您只能实现一个相同类型的接口。字符串已实现可比较的词典比较:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
{
因此,这可能是它有额外的比较器的原因之一
比较器的概念是在两个项目之间提供比较服务的对象,而不是一个项目与另一个项目具有可比性的合同(可比接口)
在字符串上实现比较器将编译,但这在语义上是错误的
公共最终类字符串
实现java.io.Serializable、Comparable、Comparator、CharSequence
{
因为字符串不是比较器。当然,它们确实是可比的,但它们本身不是“比较函数”:让字符串实现比较器是没有意义的
另一方面,CaseInsensitiveComparator
是一个特定的比较函数,只与字符串有关。因此,它被声明为一个静态
嵌套类
我看
我的问题是为什么我们不能实现comparator,就像comparable一样,使用私有函数而不是内部类
Comparator
接口的全部要点是,接口的实现是与被比较对象的类分开的类
从理论上讲,你可以按照你的建议去做,但最终的结果是违反直觉的
public class MyKey implements Comparator<MyKey> {
private String field;
public boolean compare(MyKey m1, MyKey m2) {
// We must ignore this.field! We are comparing m1 and m2 ...
return m1.field.compareTo(m2.field);
}
}
MyKey[] keys = ...
Arrays.sort(keys, new MyKey()); // Note we have to pass an instance
// to provide the Comparator.
…表示区分大小写,但
String[] strings = new String[]{"a", "c", "B"};
Arrays.sort(strings, "weasel");
…意味着排序不区分大小写。你真的觉得这是个好主意吗?真的吗?将其作为一个类而不是一个函数允许我们对集合(或可能执行比较的其他类)应用不同的多态比较策略。这样,使用比较器的方法不需要知道它是区分大小写的比较器还是不区分大小写的比较器或其他什么;它只执行比较。但是,如果这是一个函数,则这种多态性将不适用。执行比较的方法将必须使用“the”比较方法,或者必须知道正在执行的比较类型,以便选择正确的方法
拥有两个参数,而不是将第一个参数绑定到一个特定字符串,允许我们在任意数量的字符串上使用相同的比较器。否则,在处理大型集合时,我们必须跟踪许多比较器。它还允许将此比较器与左侧或右侧的子类一起使用e(或两者兼有)只有一个参数就没有那么大的灵活性。主要原因是公开比较器
对象,例如字符串
s可以用作键,或者使用排序或其他类型的等式的其他对象。它不能是静态
方法,因为比较器
接口不能指定静态
方法,比较器
必须是一个实现接口的对象,以便在类TreeMap
中使用。我们需要一个单独的不区分大小写的方法,因为默认比较(由Comparable
的方法实现)已被区分大小写的比较所采用
为什么我们不能实现比较器,就像comparable和use一样
一个私有函数而不是内部类
实现Comparable
接口,用于按字典顺序比较两个字符串,这是比较两个字符串的一种非常常见的方法
但是,有时您需要以不同的方式比较两个字符串,例如,在忽略区分大小写的情况下比较两个字符串。接口提供了一种以不同方式比较两个对象的方法。在这种情况下,实现了CaseInsensitiveComparator
以提供此功能,并在String.compareTognoreCase()中使用
method.你可以。这不是一个真正的问题。但是一个类实现自己的比较器方法通常是没有意义的。比较器是在你有两个“外来”对象时使用的。@EJP-换句话说,你可以……但这是一个愚蠢的想法。我想我之前误解了,现在我明白了你想说的要点。然而,从一个从编译的角度来看,String
没有理由不能同时实现Comparator
和Comparable
。同意,但在字符串上实现Comparator在语义上是错误的(意义/目的)
public class MyKey implements Comparator<MyKey> {
private String field;
public boolean compare(MyKey m1, MyKey m2) {
// We must ignore this.field! We are comparing m1 and m2 ...
return m1.field.compareTo(m2.field);
}
}
MyKey[] keys = ...
Arrays.sort(keys, new MyKey()); // Note we have to pass an instance
// to provide the Comparator.
String[] strings = new String[]{"a", "c", "B"};
Arrays.sort(strings);
String[] strings = new String[]{"a", "c", "B"};
Arrays.sort(strings, "weasel");