Java字符串:compareTo()与equals()

Tho*_*zer 113 java string equals compareto

String我在Java中测试同等性时,我总是使用它,equals()因为对我来说这似乎是最自然的方法.毕竟,它的名字已经说明了它的目的.然而,我最近告诉我的一位同事被教导用compareTo() == 0而不是equals().这感觉不自然(因为compareTo()它意味着提供一种排序,而不是相等的平等),甚至有点危险(因为compareTo() == 0并不一定意味着在所有情况下都是平等的,即使我知道这对我来说也是如此String).

他不知道为什么他被教导用compareTo()而不是equals()用于String,我也找不到任何理由.这真的是个人品味的问题,还是有任何方法的真正原因?

wax*_*ing 100

不同之处在于抛出NullPointerException时"foo".equals((String)null)返回false "foo".compareTo((String)null) == 0.所以即使对于Strings来说,它们也不总是可以互换的.

  • 为什么你认为equals计算哈希码?您可以看到情况并非如此:http://www.docjar.com/html/api/java/lang/String.java.html(第1013行). (27认同)
  • 我想你也应该提一下.equals计算哈希码.两个不同字符串的哈希码虽然很少,但可以是相同的.但是当使用compareTo()时,它会逐个字符地检查字符串.所以在这种情况下,当且仅当它们的实际内容相等时,两个字符串才会返回true. (6认同)
  • @Ashwin这是必要的,因为如果.equals返回true,则哈希码也应该相等.但是,如果哈希码相等,则并不意味着.equals应该返回true (4认同)
  • 当我们重写equals时必须覆盖hashcode,因为如果类使用基于哈希的集合,包括HashMap,HashSet和Hashtable,则该类将无法正常运行 (3认同)
  • 你是对的.我认为equals和hashcode齐头并进(equals检查两者是否具有相同的哈希码).那么,如果您决定覆盖其中任何一个方法,为什么必须覆盖这两个方法. (2认同)

Kal*_*see 28

两个主要区别是:

  1. equals将任何Object作为参数,但compareTo只接受字符串.
  2. equals只告诉你它们是否相等,但是compareTo提供有关字符串如何按字典顺序进行比较的信息.

我看了一下String类代码,compareTo和equals中的算法看起来基本相同.我相信他的观点只是一个品味的问题,我同意你的看法 - 如果您需要知道的是字符串的相等性而不是首先按字典顺序排列,那么我会使用equals.


sta*_*lue 26

在比较你应该使用的平等时equals(),因为它以清晰的方式表达你的意图.

compareTo()还有一个缺点,它只适用于实现Comparable接口的对象.

这通常适用于字符串.


rob*_*inr 17

compareTo如果字符串有不同的长度,我会做更多的工作.equals可以只返回false,同时compareTo必须始终检查足够的字符以查找排序顺序.


小智 10

compareTo()不仅适用于字符串,还适用于任何其他对象,因为compareTo<T>它采用泛型参数T.String是compareTo()通过实现Comparable接口实现该方法的类之一.(compareTo()是可比较的接口的方法).因此任何类都可以自由地实现Comparable接口.

但是compareTo()给出了对象的排序,通常用于按升序或降序排序对象,而equals()只讨论相等性并说明它们是否相等.


Vir*_*gic 10

在String上下文中:
compareTo:按字典顺序比较两个字符串.
equals:将此字符串与指定对象进行比较.

compareTo按字符比较两个字符串(在相同的索引处)并相应地返回一个整数(正数或负数).

String s1 = "ab";
String s2 = "ab";
String s3 = "qb";
s1.compareTo(s2); // is 0
s1.compareTo(s3); // is -16
s3.compareTo(s1); // is 16
Run Code Online (Sandbox Code Playgroud)


Jai*_*tel 7

equals()可以比compareTo()更高效.

compareTo和equals之间非常重要的区别:

"myString".compareTo(null);  //Throws java.lang.NullPointerException
"myString".equals(null);     //Returns false
Run Code Online (Sandbox Code Playgroud)

equals()检查两个对象是否相同,并返回一个布尔值.

compareTo()(来自Comparable接口)返回一个整数.它检查两个对象中的哪一个"小于","等于"或"大于"另一个.并非所有对象都可以按逻辑顺序排列,因此compareTo()方法并不总是有意义.

请注意,equals()不定义对象之间的顺序,compareTo()也是如此.

现在我建议你检查两种方法的源代码,得出结论,equals比compareTo更可取,这涉及一些数学计算.


Sco*_* M. 5

看起来这两种方法几乎都做同样的事情,但compareTo()方法接受String而不是Object,并在普通的equals()方法之上添加一些额外的功能.如果你关心的只是相等,那么equals()方法是最好的选择,因为它对下一个看看你的代码的程序员更有意义.两个不同函数之间的时差应该无关紧要,除非你循环了一些大量的项目.当您需要知道集合中字符串的顺序或者您需要知道以相同字符序列开头的字符串之间的长度差异时,compareTo()非常有用.

来源:http://java.sun.com/javase/6/docs/api/java/lang/String.html


prk*_*prk 5

equals() 应该是OP的选择方法.

纵观实施equals(),并compareTo()java.lang.String中的grepcode,我们不难看出,等于是更好,如果我们只是关心两个字符串的平等:

equals():

1012  public boolean equals(Object anObject) {
1013 if (this == anObject) {
1014 return 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 while (n-- != 0) {
1025 if (v1[i++] != v2[j++])
1026 return false;
1027 }
1028 return true;
1029 }
1030 }
1031 return 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 while (k < lim) {
1187 char c1 = v1[k];
1188 char c2 = v2[k];
1189 if (c1 != c2) {
1190 return c1 - c2;
1191 }
1192 k++;
1193 }
1194 } else {
1195 while (n-- != 0) {
1196 char c1 = v1[i++];
1197 char c2 = v2[j++];
1198 if (c1 != c2) {
1199 return c1 - c2;
1200 }
1201 }
1202 }
1203 return len1 - len2;
1204 }

当其中一个字符串是另一个字符串的前缀时,性能compareTo()会更差,因为它仍然需要确定字典顺序,而equals()不再担心并立即返回false.

在我看来,我们应该按照预期使用这两个:

  • equals() 检查平等,和
  • compareTo() 找到词汇排序.