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

时间:2010-12-15 04:17:53

标签: java string string-comparison

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

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

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

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

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

8 个答案:

答案 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被认为是相同的   如果至少满足下列条件之一,则忽略大小写:   

          
    • 这两个字符是相同的(通过==运算符进行比较)     
    • 将方法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()。

答案 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语句稍快一些