将Java中的两个对象与可能的null值进行比较


Answers:


173

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

public static boolean compare(String str1, String str2) {
    return (str1 == null ? str2 == null : str1.equals(str2));
}

3
为什么不只将String类型更改为Objects-使它更通用?然后它是一样的,如果你移动到Java 7中你会得到什么
汤姆

3
哪个Java类包含您提供的方法?
Volodymyr Levytskyi 2014年

30
嘿! 您不应有返回true / false的compare方法。等于与比较不同。比较对排序很有用。您应该返回<0==0>0指示哪一个是低/研磨器比其他
coya

10
我建议使用Objects.equals(Object, Object)Mark Rotteveel在他的回答中指出的(请赞成)
Neuron

1
@Eric的确不是一个好的答案。我敢肯定,您不会认为最好的答案就是总是只包含与所有存在的Java版本兼容的代码
Neuron

315

从Java 7开始,您可以使用static方法java.util.Objects.equals(Object, Object)对两个对象执行相等检查,而不必关心它们是否存在null

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


这种方法将类型检查推迟到程序运行时为止。有两个后果:运行时速度会变慢,并且如果您偶然尝试比较不同的类型,IDE不会通知您。
averasko '16

10
@averasko使用时Object.equals(Object),没有编译时类型检查。其Objects.equals(Object, Object)工作原理与normal非常相似equals,并且由IDE进行Objects.equals(Object, Object)引用/检查,这些规则也是受启发式支持的(例如IntelliJ IDEA 2016.2具有相同的检查均等和来自对象的检查)。
Mark Rotteveel '16

2
我喜欢这种方法。如今,无需包括一些ApacheCommons库。
Torsten Ojaperv '16

1
@SimonBaars这不是在null对象上运行函数,这是一个静态方法,您传递了两个参数(可以为null)或对对象的引用。
Mark Rotteveel

8
恕我直言,这应该是公认的答案。我不想重新发明轮子在每一个应用程序,我写
神经元


28

对于那些无法使用API​​ 19的Objects.equals(str1,str2)的android系统来说,它是这样的:

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

这是无效的。它很少需要使用更昂贵的string.equals()方法,因为由于Android的String PoolingAndroid上相同的字符串几乎总是与“ ==”操作数进行比较,而长度检查是一种过滤掉大多数不匹配项的快速方法。

源代码:

/**
 * 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;
}

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)

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


6

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

4

使用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

3

您可以java.util.Objects按以下方式使用 。

public static boolean compare(String str1, String str2) {
    return Objects.equals(str1, str2);
}

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

这是您想要的吗?


5
false如果两个String都不相同null,则返回这种情况。
JScoobyCed 2012年

1
boolean compare(String str1, String str2) {
    if (str1 == null || str2 == null)
        return str1 == str2;

    return str1.equals(str2);
}

1
boolean compare(String str1, String str2) {
  return (str1==null || str2==null) ? str1 == str2 : str1.equals(str2);
}

0

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

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

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

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

(如果您已经在代码库中使用它,您也可以“外包”到第三方工具库中。)


如果您是表现最佳的人,则:

  1. 最有效的解决方案取决于平台和上下文,
  2. “背景”问题之一是相对(动态)发生的频率 null参数,
  3. 可能并不重要版本更快......因为差异可能太小,使整体应用性能的差异,
  4. 如果确实如此,找出哪种最快在您的平台上的唯一方法是尝试两种版本并衡量差异。
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.