253

我想比较两个字符串是否相等,或者两者都可以null

所以,我不能简单地调用.equals(),因为它可以包含null值。

到目前为止我尝试过的代码:

boolean compare(String str1, String str2) {
  return ((str1 == str2) || (str1 != null && str1.equals(str2)));
}

检查所有可能值的最佳方法是什么,包括null

4

12 回答 12

431

从 Java 7 开始,您可以使用静态方法java.util.Objects.equals(Object, Object)对两个对象执行相等检查,而无需关心它们是否为null.

如果两个对象都是null它会返回true,如果一个是null而另一个不是它会返回false。否则,它将返回equals以第二个作为参数调用第一个对象的结果。

于 2012-06-30T07:40:28.817 回答
211

这是 Java 内部代码使用的(在其他compare方法上):

public static boolean compare(String str1, String str2) {
    return (str1 == null ? str2 == null : str1.equals(str2));
}
于 2012-06-30T05:11:22.397 回答
50

对于这些情况,最好使用Apache Commons StringUtils#equals,它已经处理空字符串。代码示例:

public boolean compare(String s1, String s2) {
    return StringUtils.equals(s1, s2);
}

如果您不想添加库,只需复制方法的源代码StringUtils#equals并在需要时应用即可。

于 2012-06-30T05:24:00.057 回答
29

对于那些不能使用 API 19 的 Objects.equals(str1, str2) 的 android 用户,有这样的:

android.text.TextUtils.equals(str1, str2);

它是空安全的。它很少需要使用更昂贵的 string.equals() 方法,因为由于Android 的字符串池化,Android 上的相同字符串几乎总是与 "==" 操作数比较为真,并且长度检查是过滤掉大多数不匹配的快速方法。

源代码:

/**
 * Returns true if a and b are equal, including if they are both null.
 * <p><i>Note: In platform versions 1.1 and earlier, this method only worked  well if
 * both the arguments were instances of String.</i></p>
 * @param a first CharSequence to check
 * @param b second CharSequence to check
 * @return true if a and b are equal
 */
public static boolean equals(CharSequence a, CharSequence b) {
    if (a == b) return true;
    int length;
    if (a != null && b != null && (length = a.length()) == b.length()) {
        if (a instanceof String && b instanceof String) {
            return a.equals(b);
        } else {
            for (int i = 0; i < length; i++) {
                if (a.charAt(i) != b.charAt(i)) return false;
            }
            return true;
        }
    }
    return false;
}
于 2015-06-21T11:13:19.983 回答
7

自 3.5 版以来,Apache Commons StringUtils 具有以下方法:

static int  compare(String str1, String str2)
static int  compare(String str1, String str2, boolean nullIsLess)
static int  compareIgnoreCase(String str1, String str2)
static int  compareIgnoreCase(String str1, String str2, boolean nullIsLess)

这些提供空安全字符串比较。

于 2016-11-22T15:15:03.157 回答
7

使用Java 8:

private static Comparator<String> nullSafeStringComparator = Comparator
        .nullsFirst(String::compareToIgnoreCase); 

private static Comparator<Metadata> metadataComparator = Comparator
        .comparing(Metadata::getName, nullSafeStringComparator)
        .thenComparing(Metadata::getValue, nullSafeStringComparator);

public int compareTo(Metadata that) {
    return metadataComparator.compare(this, that);
}
于 2019-02-14T11:28:13.140 回答
5

使用 Apache Commons StringUtils 类的 equals(-,-) 和 equalsIgnoreCase(-,-) 方法比较两个字符串。

StringUtils.equals(-, -)

StringUtils.equals(null, null)   = true
StringUtils.equals(null, "abc")  = false
StringUtils.equals("abc", null)  = false
StringUtils.equals("abc", "abc") = true
StringUtils.equals("abc", "ABC") = false

StringUtils.equalsIgnoreCase(-, -)

StringUtils.equalsIgnoreCase(null, null)   = true
StringUtils.equalsIgnoreCase(null, "abc")  = false
StringUtils.equalsIgnoreCase("xyz", null)  = false
StringUtils.equalsIgnoreCase("xyz", "xyz") = true
StringUtils.equalsIgnoreCase("xyz", "XYZ") = true
于 2018-06-10T11:34:27.283 回答
4

您可以使用 java.util.Objects如下。

public static boolean compare(String str1, String str2) {
    return Objects.equals(str1, str2);
}
于 2016-02-08T08:10:07.023 回答
1
boolean compare(String str1, String str2) {
    if(str1==null || str2==null) {
        //return false; if you assume null not equal to null
        return str1==str2;
    }
    return str1.equals(str2);
}

这是你想要的吗?

于 2012-06-30T05:02:51.307 回答
0
boolean compare(String str1, String str2) {
    if (str1 == null || str2 == null)
        return str1 == str2;

    return str1.equals(str2);
}
于 2012-06-30T05:06:01.967 回答
0
boolean compare(String str1, String str2) {
  return (str1==null || str2==null) ? str1 == str2 : str1.equals(str2);
}
于 2012-06-30T05:10:29.730 回答
0

好的,那么“最佳解决方案”是什么意思?

如果您的意思是最易读,那么对于有经验的 Java 程序员来说,所有可能的解决方案都差不多。但 IMO 最易读的是这个

 public boolean compareStringsOrNulls(String str1, String str2) {
     // Implement it how you like
 }

换句话说,将实现隐藏在一个(理想情况下)可以内联的简单方法中。

(您也可以“外包”到第 3 方实用程序库……如果您已经在代码库中使用它。)


如果您的意思是性能最高,那么:

  1. 最高效的解决方案取决于平台和上下文,
  2. null“上下文”问题之一是参数出现的相对(动态)频率,
  3. 哪个版本更快可能并不重要......因为差异可能太小而无法影响整体应用程序性能,并且
  4. 如果它确实重要,找出在您的平台上最快的唯一方法是尝试两个版本并测量差异。
于 2012-06-30T05:25:54.333 回答