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


111

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

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

if (s1.equals(s2)) {
    System.out.println("hai");
} else {
    System.out.println("welcome");
}

它显示“欢迎”。我了解它区分大小写。但是我的问题是我想比较两个不区分大小写的字符串。即我希望输出是hai


3
如果您知道它区分大小写,则可以在比较之前将其都转换为小写或大写。
fastcodejava 2010年

如果您使用s1.equalsIgnoreCase(s2)它,可能会在需要完成的所有地方都做不到。我建议您找到字符串的来源(可能是文件,数据库或用户输入),然后将其转换为大写(或小写)并继续使用.equals进行比较。
H2ONaCl

1
不要转换为小写/大写(如上面的注释所建议),请使用公认的equalsIgnoreCase方法。阅读土耳其文I问题和类似的Unicode问题以了解基本原理。
Ohad Schneider

1
@OhadSchneider equalsIgnoreCase无论如何都会为土耳其语返回错误的值,因为即使比较“ i”和“ I”,它也会返回true,尽管它应该返回false。因此,我怀疑如果要考虑区域设置,Collator则实际上是一种方法。
Trejkaz

1
@OhadSchneider我想知道。它说按字符执行此操作会产生相同的结果,但是对整个字符串执行toLowerCase/ toUpperCase并按字符执行操作也会产生两个不同的结果。
Trejkaz

Answers:


171
  • 最好的方法是使用s1.equalsIgnoreCase(s2):(请参阅javadoc
  • 您也可以将它们都转换为大写/小写并使用 s1.equals(s2)

39
请注意,两种解决方案不一定在所有语言环境中都相同。String#equalsIgnoreCase不使用特定于语言环境的大小写规则,而String#toLowerCase和#toUpperCase则使用。
jarnbjo 2010年

1
@jarnbjo您能举个例子说明那里的区别吗?
towi

16
特定于语言环境的案例规则至少适用于土耳其语和德语。土耳其语将带或不带点的I视为两个不同的字母,从而创建i / i和ıI的大小写对,而其他语言则将iI视为一对,并且不使用ı和İ。在德语中,小写字母ß大写为“ SS”。
jarnbjo


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));
}
    String brook = "flu\u0308ßchen";
    String BROOK = "FLÜSSCHEN";

    assert equalsIgnoreCase(brook, BROOK);

即使对这种简单测试String.equalsIgnoreCase,与或String.equals在大写或小写字符串上进行天真比较也会失败。

(请注意,尽管预定义的案例折叠样式getNFKCCasefoldInstance是与语言环境无关的;对于土耳其语语言环境,UCharacter.foldCase可能需要进行更多工作。)


22

您必须使用对象的compareToIgnoreCase方法String

int compareValue = str1.compareToIgnoreCase(str2);

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


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");
}

现在它将输出: hai


5

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

String.CASE_INSENSITIVE_ORDER

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

String s = "some text here";
s.equalsIgnoreCase("Some text here");

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

只是为了进一步了解与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;
}

因此,如果您想使用带有字符串作为键的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;
    }
}

然后这样使用它:

HashMap<HashWrap, Object> map = new HashMap<HashWrap, Object>();

2

请注意,在执行.equals或.equalsIgnoreCase之前,您可能还希望对它们进行空检查。

空的String对象不能调用equals方法。

即:

public boolean areStringsSame(String str1, String str2)
{
    if (str1 == null && str2 == null)
        return true;
    if (str1 == null || str2 == null)
        return false;

    return str1.equalsIgnoreCase(str2);
}

1
注意:后两个语句可以组合以产生相同的结果,如下所示:if (str1 == null || str2 == null) return false;
LuckyMe 2013年

修改后的代码以使上述注释更
简洁

1
您还可以更改第一行if (str1 == str2) return true;,当两个字符串引用引用相同的字符串对象时,这两个行既可以满足null要求,也可以满足快捷方式。
巴尼2014年




1

为了安全起见,您可以使用

org.apache.commons.lang.StringUtils.equalsIgnoreCase(String, String)

要么

org.apache.commons.lang3.StringUtils.equalsIgnoreCase(CharSequence, CharSequence)

-6
public boolean newEquals(String str1, String str2)
{
    int len = str1.length();
int len1 = str2.length();
if(len==len1)
{
    for(int i=0,j=0;i<str1.length();i++,j++)
    {
        if(str1.charAt(i)!=str2.charAt(j))
        return false;
    }`enter code here`
}
return true;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.