我想比较两个字符串是否相等,当其中一个或两个都可以为空时。

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

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

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

检查包括空值在内的所有可能值的最佳方法是什么?


当前回答

使用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);
}

或者您也可以使用Java使用下面的方法

public static boolean比较(字符串第一个,字符串第二个){ 返回(Objects.isNull(第一次)?Objects.isNull(秒): first.equals(秒)); }

其他回答

好的,那么best possible solution是什么意思呢?

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

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

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

(你也可以“外包”给第三方工具库……如果你已经在你的代码库中使用了它。)


如果你指的是最具性能,那么:

最高效的解决方案取决于平台和环境, “上下文”问题之一是空参数出现的相对(动态)频率, 哪个版本更快可能并不重要……因为这种差异可能太小,不会对整体应用程序性能产生影响 如果这真的很重要,那么找出在你的平台上哪个版本最快的唯一方法就是尝试两个版本并衡量差异。

从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)

它们提供了空安全的字符串比较。

对于那些不能使用API 19的对象的android用户。等于(str1, str2)

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

这是你想要的吗?

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

stringutil的。等于(-,-):

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

stringutil的。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