Java:String:equalsIgnoreCase vs将所有内容切换为大写/小写

我注意到有几种方法可以比较Java中的字符串。

我刚刚习惯使用equalsIgnoreCase以避免出现区分大小写的字符串问题。

另一方面,其他人喜欢以大写或小写的方式传递所有内容。

从我的立场(即使技术上我坐着),我看不出真正的区别。

有人知道一种做法是否优于另一种做法? 如果是这样,为什么?

使用equalsIgnoreCase因为它比在比较之前将两个字符串转换为大写更具可读性。 可读性胜过微优化

什么更具可读性?

 if (myString.toUpperCase().equals(myOtherString.toUpperCase())) { 

要么

 if (myString.equalsIgnoreCase(myOtherString)) { 

我想我们都同意equalsIgnoreCase更具可读性。

equalsIgnoreCase避免了有关Locale特定差异的问题(例如,在Turkish Locale中有两个不同的大写“i”字母)。 另一方面,Maps仅使用equals()方法。

但是在后者的问题中,你假设无论是大写还是小写,你都不能盲目地信任来电者。 因此,您必须在方法的开头包含ASSERT语句,以确保输入始终处于您期望的情况。

两者都不是更好,它们都可以在不同场景中使用。

很多时候,当你必须进行字符串比较时,有机会按摩至少一个字符串以便于比较,在这些情况下,你会看到字符串转换为特定的情况,修剪等,然后进行比较。

另一方面,如果你只是想对两个字符串进行即时不区分大小写的比较,那么可以随意使用equalsIgnoreCase ,这就是它的用途。 但是,我要提醒一下,如果你看到很多equalsIgnoreCase它可能是代码味道。

根据这篇文章,性能方面都是相同的:

http://www.params.me/2011/03/stringtolowercasestringtouppercase-vs.html

所以我决定基于代码读取性,在某些情况下,如果我总是将值传递给单个方法来创建对象,toLowerCase()会更好,否则equalsIgnoreCase()更有意义。

这取决于用例。

如果您正在进行一对一的字符串比较,则equalsIgnoreCase可能更快,因为在内部它只是在每个字符的上半部分,因为它遍历字符串(下面的代码来自java.lang.String),这比bigcasing或lowercasing稍快一些在执行相同的比较之前,他们都是:

 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()调用来检查整个字符串列表。

jdk 8中的equalsIgnoreCase文档

  • 将此String与另一个String进行比较,忽略大小写。 如果两个字符串具有相同的长度并且两个字符串中的相应字符等于忽略大小写,则认为它们是相等的忽略大小写。

    如果至少满足下列条件之一,则两个字符c1和c2被视为相同的忽略大小写:

    • 这两个字符是相同的(通过==运算符进行比较)
    • 将方法java.lang.CharactertoUpperCase(char)应用于每个字符会产生相同的结果
    • 将方法java.lang.CharactertoLowerCase(char)应用于每个字符会产生相同的结果

我的想法:

因此,使用equalsIgnoreCase,我们遍历Strings(只有当它们的大小值相同时)才比较每个char。 在最坏的情况下,我们将表现为O(3cn),其中n =字符串的大小。 我们不会使用额外的空间。

使用toUpper()然后比较字符串是否相等,你总是循环遍历每个字符串一次,将所有字符串转换为upper,然后通过引用检查(equals())进行等价。 这是theta(2n + c)。 但是请记住,当你执行toUpperCase()时,你实际上必须创建两个新的字符串,因为Java中的字符串是不可变的。

所以我想说equalsIgnoreCase更高效,更容易阅读。

我再次考虑用例,因为这对我来说就是最重要的。 toUpper方法在某些用例中可能有效,但98%的时候我使用equalsIgnoreCase()。

当我使用仅限英语的字符时,如果我.equalsIgnoreCase()调用.equalsIgnoreCase()或者我正在使用switch语句,那么在开始进行比较之前,我总是运行toUpperCase()toLowerCase() 。 这样它只进行一次大小写更改操作,因此效率更高。

例如,在工厂模式中:

 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阻止字符串比较稍快)