我注意到有几种方法可以比较Java中的字符串。
我很久以前习惯使用equalsIgnoreCase
来避免区分大小写的字符串出现问题。
另一方面,其他人更喜欢以大写或小写的方式传递所有内容。
从我的立场(即使技术上我坐着),我看不出真正的区别。
有人知道一种做法是否优于另一种做法?如果是这样,为什么呢?
答案 0 :(得分:49)
使用equalsIgnoreCase
因为它比在比较之前将两个字符串转换为大写更具可读性。 可读性胜过微优化。
什么更具可读性?
if (myString.toUpperCase().equals(myOtherString.toUpperCase())) {
或
if (myString.equalsIgnoreCase(myOtherString)) {
我认为我们都同意equalsIgnoreCase
更具可读性。
答案 1 :(得分:10)
equalsIgnoreCase避免了有关特定于语言环境的差异的问题(例如,在土耳其语语言环境中,有两个不同的大写“i”字母)。另一方面,Maps只使用equals()方法。
答案 2 :(得分:3)
但是在后者的问题中,你通过大写或小写的假设,你不能盲目地信任来电者。因此,您必须在方法的开头包含ASSERT
语句,以确保输入始终处于您期望的情况。
答案 3 :(得分:2)
两者都不是更好,它们都可以在不同场景中使用。
很多时候,当你必须进行字符串比较时,有机会按摩至少一个字符串以便于比较,在这些情况下,你会看到字符串转换为特定的情况,修剪等等比较。
另一方面,如果你只是想对两个字符串进行即时不区分大小写的比较,那么可以随意使用equalsIgnoreCase
,这就是它的用途。但是,我要提醒一下,如果你看到很多equalsIgnoreCase
,那可能是代码味道。
答案 4 :(得分:1)
根据这篇文章,性能方面都是相同的:
http://www.params.me/2011/03/stringtolowercasestringtouppercase-vs.html
所以我会基于代码读取性来决定,在某些情况下,如果我总是将值传递给单个方法来创建对象,那么toLowerCase()会更好,否则equalsIgnoreCase()更有意义。
答案 5 :(得分:1)
这取决于用例。
如果您正在进行一对一的字符串比较,则equalsIgnoreCase可能更快,因为在内部它只是在每个字符重叠时在字符串中迭代(代码来自java.lang.String),这稍微在执行相同的比较之前,比大写或小写它们更快:
if (ignoreCase)
{
// If characters don't match but case may be ignored,
// try converting both characters to uppercase.
// If the results match, then the comparison scan should
// continue.
char u1 = Character.toUpperCase(c1);
char u2 = Character.toUpperCase(c2);
if (u1 == u2) {
continue;
}
// Unfortunately, conversion to uppercase does not work properly
// for the Georgian alphabet, which has strange rules about case
// conversion. So we need to make one last check before
// exiting.
if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
continue;
}
}
但是当你想要以不区分大小写的方式对充满字符串的数据结构(特别是美国拉丁文/ ASCII空间中的字符串)进行查找时,修剪/小写会更快要检查的字符串,并将它们放在HashSet或HashMap之类的内容中。
这比在List的每个元素上调用equalsIgnoreCase更好,因为equalsIgnoreCase()的轻微性能提升被你基本上对一个数组做了一个修改版本的contains()这个事实所取消了是O(n)。使用预规范化的字符串,您可以使用在O(1)中运行的单个contains()调用来检查整个字符串列表。
答案 6 :(得分:1)
jdk 8中的equalsIgnoreCase文档
将此String与另一个String进行比较,忽略大小写 注意事项。如果两个字符串被认为是相等的,则忽略大小写 具有相同的长度和两个字符串中的相应字符 等同于无视案例。
两个字符c1和c2被认为是相同的 如果至少满足下列条件之一,则忽略大小写:
我的想法:
因此,使用equalsIgnoreCase,我们遍历Strings(只有当它们的大小值相同时)才比较每个char。在最坏的情况下,我们将表现为O(3cn),其中n =字符串的大小。我们不会使用额外的空间。
使用toUpper()然后比较字符串是否相等,你总是循环遍历每个字符串一次,将所有字符串转换为upper,然后通过引用检查(equals())进行等价。这是theta(2n + c)。但是请记住,当你执行toUpperCase()时,你实际上必须创建两个新的字符串,因为Java中的字符串是不可变的。
所以我会说equalsIgnoreCase更高效,更容易阅读。
我再次考虑用例,因为这对我来说就是最重要的。 toUpper方法在某些用例中可能有效,但98%的时间我使用equalsIgnoreCase()。
答案 7 :(得分:0)
当我使用仅限英语的字符时,如果我正在调用toUpperCase()
,我会在开始进行比较之前运行toLowerCase()
或.equalsIgnoreCase()
不止一次或者如果我使用switch
语句。这样,它只进行一次大小写更改操作,因此效率更高。
例如,在工厂模式中:
public static SuperObject objectFactory(String objectName) {
switch(objectName.toUpperCase()) {
case "OBJECT1":
return new SubObject1();
break;
case "OBJECT2":
return new SubObject2();
break;
case "OBJECT3":
return new SubObject3();
break;
}
return null;
}
(对于字符串比较,使用switch
语句比if..else if..else
语句稍快一些