在Java中测试 String
的相等性时,我总是使用 equals()
,因为对我而言,这似乎是最自然的方法 . 毕竟,它的名字已经说明了它的目的 . 然而,我最近告诉我的一位同事被教导使用 compareTo() == 0
而不是 equals()
. 这感觉不自然(因为 compareTo()
是为了提供一个排序而不是相等的平等),甚至有点危险(因为 compareTo() == 0
并不一定意味着在所有情况下都是平等的,即使我知道它对_1146085的确是如此) .
他不知道为什么他被教导使用 compareTo()
而不是 equals()
,我也找不到任何理由 . 这真的是个人品味的问题,还是有任何方法的真正原因?
19 回答
equals()检查两个字符串是否相等 . 它给出了布尔值 . compareTo()检查字符串对象是否等于,大于或小于另一个字符串对象 . 它给出结果如果:1如果字符串对象大于0则如果两者都等于-1如果字符串小于其他字符串
EQ:
在使用
compareTo()
而不是equals()
时,有一件事很重要compareTo
适用于实现'Comparable'接口的类,否则会抛出NullPointerException
.String
类实现Comparable接口,而StringBuffer
不实现,因此您可以在String
对象中使用"foo".compareTo("doo")
但不能在StringBuffer
对象中使用"foo".compareTo("doo")
.区别在于
"foo".equals((String)null)
返回false而"foo".compareTo((String)null) == 0
抛出NullPointerException . 所以即使对于Strings来说,它们也不总是可以互换的 .比较相等时,您应该使用
equals()
,因为它以清晰的方式表达您的意图 .compareTo()
还有一个缺点,即它只适用于实现Comparable
接口的对象 .这通常适用于字符串 .
两个主要区别是:
equals
会将任何Object作为参数,但compareTo
将只接受字符串 .equals
仅告诉您它们是否相等,但compareTo
提供了字符串按字典顺序进行比较的信息 .我看了the String class code,compareTo和equals中的算法看起来基本相同 . 我相信他的观点只是一个品味问题,我同意你的看法 - 如果您需要知道的是字符串的相等性而不是首先按字典顺序排列,那么我会使用
equals
.如果字符串长度不同,
compareTo
会做更多的工作 .equals
只能返回false,而compareTo
必须始终检查足够的字符以查找排序顺序 .在String上下文中:
compareTo:按字典顺序比较两个字符串 .
equals:将此字符串与指定对象进行比较 .
compareTo按字符比较两个字符串(在相同的索引处)并相应地返回一个整数(正数或负数) .
compareTo()
不仅适用于字符串,还适用于任何其他对象,因为compareTo<T>
采用通用参数T
. String是通过实现Comparable
接口实现compareTo()
方法的类之一 . (compareTo()是类似接口的方法) . 因此任何类都可以自由地实现Comparable接口 .But compareTo() gives the ordering of objects ,通常用于按升序或降序排序对象,而 equals() will only talk about the equality 并说明它们是否相等 .
compareTo和equals之间非常重要的区别:
equals() 检查两个对象是否相同并返回一个布尔值 .
compareTo() (来自Comparable接口)返回一个整数 . 它检查两个对象中的哪一个是"less than","equal to"或"greater than"另一个 . 并非所有对象都可以按逻辑顺序排列,因此compareTo()方法并不总是有意义 .
请注意,equals()不定义对象之间的顺序,compareTo()也是如此 .
现在我建议你检查两种方法的源代码,得出结论,equals比compareTo更可取,这涉及一些数学计算 .
看起来这两种方法几乎都做同样的事情,但compareTo()方法接受String而不是Object,并在普通的equals()方法之上添加一些额外的功能 . 如果你关心的只是相等,那么equals()方法是最好的选择,因为它对下一个看看你的代码的程序员更有意义 . 两个不同函数之间的时差应该无关紧要,除非你循环了一些大量的项目 . 当您需要知道集合中字符串的顺序或者您需要知道以相同字符序列开头的字符串之间的长度差异时,compareTo()非常有用 .
来源:http://java.sun.com/javase/6/docs/api/java/lang/String.html
equals()
应该是OP的选择方法 .查看java.lang.String on grepcode中
equals()
和compareTo()
的实现,如果我们只是担心,我们可以很容易地看到等于更好两个字符串相等:equals()
:和
compareTo()
:当其中一个字符串是另一个字符串的前缀时,
compareTo()
的性能更差,因为它仍然需要确定字典顺序,而equals()
将不再担心并立即返回false .在我看来,我们应该按照预期使用这两个:
equals()
检查是否相等,并且compareTo()
找到词法排序 .在Java中覆盖compareTo时,您需要记住某些事项,例如Compareto必须与equals和subtraction一致,不应该用于比较整数字段,因为它们可以溢出 . 检查Things to remember while overriding Comparator in Java了解详情 .
Equals可以比compareTo更有效 .
如果String中字符序列的长度不匹配,则字符串无法相等,因此拒绝可以更快 .
而且,如果它是同一个对象(身份相等而不是逻辑相等),它也会更有效率 .
如果他们也实现了hashCode缓存,那么在hashCode不匹配的情况下拒绝非equals可能会更快 .
String.equals()
需要调用 instanceof 运算符,而compareTo()
则不需要 . 我的同事已注意到equals()
方法中过多的 instanceof 调用导致性能大幅下降,但我的测试证明compareTo()
只是稍快一点 .然而,我使用的是Java 1.6 . 在其他版本(或其他JDK供应商)上,差异可能更大 .
该测试比较了1000个元素阵列中的每个字符串,重复10次 .
equals
可以将任何Object作为参数,但compareTo
只能接受String .当到达null时,
compareTo
将抛出异常当你想知道差异发生的地方时,你可以使用
compareTo
.这是一个死灵法术的实验:-)
大多数答案比较性能和API差异 . 他们错过了两个操作只具有不同语义的基本点 .
你的直觉是正确的 . x.equals(y)不能与x.compareTo(y)== 0互换 . 第一个比较身份,而另一个比较'size'的概念 . 确实,在许多情况下,尤其是原始类型,这两个共同对齐 .
一般情况是这样的:
如果x和y相同,则它们共享相同的“大小”:如果x.equals(y)为真=> x.compareTo(y)为0 .
但是,如果x和y共享相同的大小,则并不意味着它们是相同的 .
如果x.compareTo(y)为0,则不一定意味着x.equals(y)为真 .
身份与大小不同的一个引人注目的例子是复数 . 假设比较是通过它们的绝对值来完成的 . 所以给出两个复数: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
:元素排序所必需的 . 再次对于稳定排序,您需要相等,因此返回0 .Equals -
1-重写GetHashCode方法以允许类型在哈希表中正常工作 .
2-不要在实现Equals方法时抛出异常 . 相反,为null参数返回false .
3-
只要x和y引用的对象未被修改,x.Equals(y)的连续调用就会返回相同的值 .
4-对于某些类型的对象,最好使用Equals测试值相等而不是引用相等 . 如果两个对象具有相同的值,即使它们不是同一个实例,这样的Equals实现也会返回true .
例如 -
输出: -
而 compareTo -
将当前实例与另一个相同类型的对象进行比较,并返回一个整数,该整数指示当前实例是否在排序顺序中与其他对象相同的位置之前,之后或出现 .
它返回 -
小于零 - 此实例在排序顺序中位于obj之前 . 零 - 此实例出现在排序中的相同位置订购为obj . 大于零 - 此实例遵循排序顺序中的obj .
如果object与实例的类型不同,它可以抛出ArgumentException .
例如,您可以访问此处 .
所以我建议用Equals代替compareTo .
“equals”比较对象并返回true或false,“compare to”返回0 if为true或数字[> 0]或[<0]如果为false则为例如:
结果:
文档对比: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)