Javastring:compareTo()与equals()
当在Java中testingString
的平等时,我总是使用equals()
因为对我来说这似乎是最自然的方法。 毕竟,它的名字已经说明了它打算做什么。 不过,我最近告诉我的一位同事被教导使用compareTo() == 0
而不是equals()
。 这感觉不自然(因为compareTo()
是为了提供一个sorting而不是比较的相等),甚至有点危险(因为compareTo() == 0
并不一定意味着在所有情况下都是平等的,即使我知道它对于String
' s)给我。
他不知道为什么他被教会使用compareTo()
而不是equals()
来处理String
,而且我也找不到任何理由。 这真的是个人品味的问题,还是有任何方法的真正原因?
不同的是, "foo".equals((String)null)
返回false,而"foo".compareTo((String)null) == 0
引发NullPointerException。 所以即使对于string,它们也不总是可以互换的。
当比较平等时,你应该使用equals()
,因为它以一种清晰的方式expression你的意图。
compareTo()
还有一个缺点:它只能在实现Comparable
接口的对象上工作。
一般来说,这不仅适用于string。
两个主要的区别是:
-
equals
将把任何Object作为参数,但是compareTo
只会使用Strings。 -
equals
只会告诉你它们是否相等,但compareTo
给出了string如何按照字典顺序进行比较的信息。
我看了一下String类的代码 ,compareTo和equals里面的algorithm看起来基本一样。 我相信他的意见只是一个口味问题,我同意你的观点 – 如果你需要知道的只是string的平等,而不是按字母顺序排列的话,那么我会用equals
。
如果string长度不同, compareTo
会做更多的工作。 equals
可以返回false,而compareTo
必须检查足够的字符才能findsorting顺序。
compareTo()
不仅适用于string,也适用于其他任何对象,因为compareTo<T>
接受generics参数T
string是通过实现Comparable
接口实现了compareTo()
方法的类之一。 (compareTo()是可比较的接口的一种方法)。 所以任何类都可以自由地实现Comparable接口。
但是compareTo()
给出了对象的sorting ,通常用于按升序或降序对对象进行sorting,而equals()
将只讨论相等性并说明它们是否相等。
在string上下文:
compareTo:按字母顺序比较两个string。
等于:将此string与指定对象进行比较。
compareTo比较两个string的字符(在相同的索引处)并相应地返回一个整数(正数或负数)。
String s1 = "ab"; String s2 = "ab"; String s3 = "qb"; s1.compareTo(s2); // is 0 s1.compareTo(s3); // is -16 s3.compareTo(s1); // is 16
在OP的情况下, equals()
应该是select的方法。
在grepcode的java.lang.String中查看 equals()
和compareTo()
实现 ,我们可以很容易地看到,如果我们只关心两个string的相等性,那么equals就更好:
equals()
:
1012 public boolean equals( Object anObject){
1013 if ( this == anObject){
1014 返回 true ;
1015 }
1016 if (anObject instanceof String ){
1017 String anotherString =( String )anObject;
1018 int n = count;
1019 if (n == anotherString.count){
1020 char v1 [] = value;
1021 char v2 [] = anotherString.value;
1022 int i = offset;
1023 int j = anotherString.offset;
1024 (n--!= 0){
1025 if (v1 [i ++]!= v2 [j ++])
1026 返回 false ;
1027 }
1028 返回 true ;
1029 }
1030 }
1031 返回 false ;
1032 }
和compareTo()
:
1174 public int compareTo( String anotherString){
1175 int len1 = count;
1176 int len2 = anotherString.count;
1177 int n =math。 min (len1,len2);
1178 char v1 [] = value;
1179 char v2 [] = anotherString.value;
1180 int i = offset;
1181 int j = anotherString.offset;
1183 if (i == j){
1184 int k = i;
1185 int lim = n + i;
1186 而 (k <lim){
1187 char c1 = v1 [k];
1188 char c2 = v2 [k];
1189 if (c1!= c2){
1190 返回 c1 - c2;
1191 }
1192 k ++;
1193 }
其他 {
1195 (n--!= 0){
1196 char c1 = v1 [i ++];
1197 char c2 = v2 [j ++];
1198 if (c1!= c2){
1199 返回 c1 - c2;
1200 }
1201 }
1202 }
1203 return len1 - len2;
1204 }
当其中一个string是另一个string的前缀时, compareTo()
的性能会更糟,因为它仍然需要确定字典顺序,而equals()
不会再担心并立即返回false。
在我看来,我们应该按照他们的意图使用这两个:
-
equals()
检查是否相等 -
compareTo()
来查找词法sorting。
看来,这两种方法几乎都做同样的事情,但compareTo()方法需要一个string,而不是一个对象,并在正常的equals()方法的顶部添加一些额外的function。 如果你所关心的只是平等,那么equals()方法是最好的select,因为下一个程序员看看你的代码会更有意义。 两个不同的函数之间的时间差异应该不重要,除非你正在循环大量的项目。 当需要知道集合中string的顺序时,或者需要知道以相同字符序列开始的string之间的长度差异时,compareTo()非常有用。
来源: http : //java.sun.com/javase/6/docs/api/java/lang/String.html
equals()可以比compareTo()更有效。
compareTo和equals之间的一个非常重要的区别:
"myString".compareTo(null); //Throws java.lang.NullPointerException "myString".equals(null); //Returns false
equals()检查两个对象是否相同,并返回一个布尔值。
compareTo() (来自接口Comparable)返回一个整数。 它检查两个对象中的哪一个是“小于”,“等于”或“大于”另一个。 并不是所有的对象都可以进行逻辑sorting,所以compareTo()方法并不总是合理的。
请注意,equals()没有定义compareTo()所对象之间的顺序。
现在我build议你查看这两种方法的源代码,得出结论:equals比compareTo更好,这涉及到一些math计算。
在Java中重写compareTo时需要注意的一些事情,比如compareto必须和equals相等,减法不能用于比较整数字段,因为它们可能会溢出。 检查事情要记住,而在Java重写比较器的细节。
等于compareTo可以更高效。
如果string中字符序列的长度不匹配,则string不可能相等,因此拒绝可能会更快。
而且,如果它是同一个对象(身份平等而不是逻辑平等),它也会更有效率。
如果他们也实现了hashCodecaching,那么在hashCode不匹配的情况下拒绝非等号会更快。
-
equals
可以将任何Object作为参数,但compareTo
只能使用String。 -
当空值为null时,
compareTo
将抛出一个exception -
当你想知道差异发生的位置时,可以使用
compareTo
。
这是一个巫术实验:-)
大多数答案比较性能和API差异。 他们错过了两个操作的语义不同的基本点。
你的直觉是正确的。 x.equals(y)不能与x.compareTo(y)== 0互换。第一个比较标识,而另一个比较“大小”的概念。 诚然,在许多情况下,尤其是与原始types,这两个共同alignment。
一般情况是这样的:
如果x和y相同,则它们共享相同的“大小”:如果x.equals(y)为true => x.compareTo(y)为0。
但是,如果x和y的大小相同,并不意味着它们是相同的。
如果x.compareTo(y)为0,则不一定表示x.equals(y)为true。
身份不同于大小的令人信服的例子将是复杂的数字。 假定比较是通过它们的绝对值完成的。 所以给出两个复数:Z1 = a1 + b1 * i和Z2 = a2 + b2 * i:
当且仅当a1 = a2和b1 = b2时,Z1.equals(z2)返回true。
但是,只要满足条件a1 ^ 2 + b1 ^ 2 == a2 ^ 2 + b2 ^ 2,Z1.compareTo(Z2)就返回0,并且无限个(a1,b1)和(a2,b2)对返回。
-
equals
:检查平等和限制重复所需的。 Java库的许多类使用这种情况下,他们想要查找重复。 例如HashSet.add(ob1)
只会添加如果不存在。 所以,如果你正在扩展一些这样的类,然后覆盖equals()
。 -
compareTo
:用于sorting元素。 再次为稳定的sorting你需要平等,所以有一个返回0。
String.equals()
需要调用instanceof
运算符,而compareTo()
不需要。 我的同事已经注意到在equals()
方法中由于instanceof
调用的数量过多而引起的大量性能下降,但是我的testingcertificatecompareTo()
只稍快一点。
不过,我正在使用Java 1.6。 在其他版本(或其他JDK供应商)上,差异可能更大。
该testing比较了1000个元素数组中的每个string,重复了10次。
等于 –
1-覆盖GetHashCode方法以允许types在哈希表中正确工作。
2-不要在Equals方法的实现中抛出exception。 相反,为null参数返回false。
3-
x.Equals(x) returns true. x.Equals(y) returns the same value as y.Equals(x). (x.Equals(y) && y.Equals(z)) returns true if and only if x.Equals(z) returns true.
只要x和y引用的对象没有被修改,x.Equals(y)的连续调用就返回相同的值。
x.Equals(null) returns false.
4-对于某些types的对象,最好进行等式testing以获得价值平等,而不是参照平等。 如果两个对象具有相同的值,即使它们不是相同的实例,Equals的这种实现也会返回true。
例如 –
Object obj1 = new Object(); Object obj2 = new Object(); Console.WriteLine(obj1.Equals(obj2)); obj1 = obj2; Console.WriteLine(obj1.Equals(obj2));
输出: –
False True
而compareTo –
将当前实例与另一个相同types的对象进行比较,并返回一个整数,该整数指示当前实例是否在sorting顺序中与其他对象相同的位置之前,之后或之后。
它返回 –
小于零 – 这个实例按照sorting顺序在obj之前。 零 – 这个实例发生在与objsorting顺序相同的位置。 大于零 – 此实例按sorting顺序跟随obj。
如果对象与实例的types不同,它可以抛出ArgumentException。
例如,你可以访问这里。
所以我build议最好使用Equals代替compareTo。
“equals”比较对象并返回true或false,“compare to”返回0如果为true或者数字[> 0]或[<0] if为false这里是一个例子:
<!-- language: lang-java --> //Objects Integer Integer num1 = 1; Integer num2 = 1; //equal System.out.println(num1.equals(num2)); System.out.println(num1.compareTo(num2)); //New Value num2 = 3;//set value //diferent System.out.println(num1.equals(num2)); System.out.println(num1.compareTo(num2));
结果:
num1.equals(num2) =true num1.compareTo(num2) =0 num1.equals(num2) =false num1.compareTo(num2) =-1
文档比较: https : //docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html
文档等于: https ://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals( java.lang.Object)
equals()检查两个string是否相等。它给出布尔值。 compareTo()检查string对象是否等于,大于或小于另一个string对象。它给出如下结果:1如果string对象大于0如果两者都等于-1如果string小于其他string
EQ:
String a = "Amit"; String b = "Sumit"; String c = new String("Amit"); System.out.println(a.equals(c));//true System.out.println(a.compareTo(c)); //1