如何使字符串比较不区分大小写?

use*_*018 108 java string comparison case-insensitive

我创建了一个Java程序来比较两个字符串:

String s1 = "Hello";
String s2 = "hello";

if (s1.equals(s2)) {
    System.out.println("hai");
} else {
    System.out.println("welcome");
}
Run Code Online (Sandbox Code Playgroud)

它显示"欢迎".我理解它区分大小写.但我的问题是我想要比较两个没有区分大小写的字符串.即我期望输出hai.

Mic*_*vin 169

  • 最好的将是s1.equalsIgnoreCase(s2):(见javadoc)
  • 您也可以将它们转换为大写/小写并使用 s1.equals(s2)

  • 请注意,对于所有语言环境,这两种解决方案不一定相同.String#equalsIgnoreCase不使用特定于语言环境的大小写规则,而String#toLowerCase和#toUpperCase不使用. (38认同)
  • 至少针对土耳其语和德语实施区域设置特定案例规则.土耳其对待我有和没有点作为两个不同的字母,创建低/大对对iİ和ıI而其他语言对iI作为一对,不要使用字母ı和İ.在德语中,小写ß大写为"SS". (15认同)

glt*_*lts 24

String.equalsIgnoreCase 是天真的不区分大小写的字符串比较最实用的选择.

但是,最好注意这个方法既不进行完整的大小写折叠也不进行分解,因此不能执行Unicode标准中规定的无大小写匹配.事实上,JDK API不提供对案例折叠字符数据的信息的访问,因此这项工作最好委托给经过试验和测试的第三方库.

该库是ICU,以下是如何实现用于不区分大小写的字符串比较的实用程序:

import com.ibm.icu.text.Normalizer2;

// ...

public static boolean equalsIgnoreCase(CharSequence s, CharSequence t) {
    Normalizer2 normalizer = Normalizer2.getNFKCCasefoldInstance();
    return normalizer.normalize(s).equals(normalizer.normalize(t));
}
Run Code Online (Sandbox Code Playgroud)
    String brook = "?u\u0308ßchen";
    String BROOK = "FLÜSSCHEN";

    assert equalsIgnoreCase(brook, BROOK);
Run Code Online (Sandbox Code Playgroud)

即使是这个简单的测试String.equalsIgnoreCase,String.equals与上层或下层字符串进行天真的比较也会失败.

(请注意,预定义的案例折叠风格getNFKCCasefoldInstance与语言环境无关;对于土耳其语语言环境,UCharacter.foldCase可能需要更多的工作.)


小智 22

您必须使用compareToIgnoreCaseString对象的方法.

int compareValue = str1.compareToIgnoreCase(str2);
Run Code Online (Sandbox Code Playgroud)

if (compareValue == 0)它意味着str1平等str2.

  • 不知道这个方法也可用.谢谢! (3认同)

KNU*_*KNU 10

import java.lang.String; //contains equalsIgnoreCase()
/*
*
*/
String s1 = "Hello";
String s2 = "hello";

if (s1.equalsIgnoreCase(s2)) {
System.out.println("hai");
} else {
System.out.println("welcome");
}
Run Code Online (Sandbox Code Playgroud)

现在它将输出: hai


le-*_*ude 5

在默认的Java API中,您可以:

String.CASE_INSENSITIVE_ORDER
Run Code Online (Sandbox Code Playgroud)

因此,如果要使用带排序数据结构的字符串,则无需重写比较器。

String s = "some text here";
s.equalsIgnoreCase("Some text here");
Run Code Online (Sandbox Code Playgroud)

您想要在自己的代码中进行纯相等检查。

只是为了进一步了解与Java中的字符串相等有关的任何信息。java.lang.String类的hashCode()函数“区分大小写”:

public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
        char val[] = value;

        for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i];
        }
        hash = h;
    }
    return h;
}
Run Code Online (Sandbox Code Playgroud)

因此,如果您要使用带有字符串作为键的Hashtable / HashMap,并且将诸如“ SomeKey”,“ SOMEKEY”和“ somekey”之类的键视为相等,则必须将字符串包装在另一个类中(不能扩展)字符串,因为它是最后一堂课)。例如 :

private static class HashWrap {
    private final String value;
    private final int hash;

    public String get() {
        return value;
    }

    private HashWrap(String value) {
        this.value = value;
        String lc = value.toLowerCase();
        this.hash = lc.hashCode();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o instanceof HashWrap) {
            HashWrap that = (HashWrap) o;
            return value.equalsIgnoreCase(that.value);
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return this.hash;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后这样使用它:

HashMap<HashWrap, Object> map = new HashMap<HashWrap, Object>();
Run Code Online (Sandbox Code Playgroud)