24

我知道不可能像这样在 null 对象上调用 equals 方法:

//NOT WORKING
            String s1 = null;
            String s2 = null;
            if(s1.equals(s2))
            {
                System.out.println("NOT WORKING :'(");
            }

但在我的情况下,我想比较两个数据库中的两个对象,这两个对象的属性可以为空......

那么比较两个属性的方法是什么,知道我们不确定值是null还是填充。

这个方法好不好?

//WORKING
            String s1 = "test";
            String s2 = "test";
            if(s1 == s2 || s1.equals(s2))
            {
                System.out.println("WORKING :)");
            }

            //WORKING
            String s1 = null;
            String s2 = null;
            if(s1 == s2 || s1.equals(s2))
            {
                System.out.println("WORKING :)");
            }

我不确定,因为在这种情况下它不起作用......:

//NOT WORKING
            String s1 = null;
            String s2 = null;
            if(s1.equals(s2)|| s1 == s2  )
            {
                System.out.println("NOT WORKING :'''(");
            }
4

9 回答 9

32

我通常使用我编写的静态实用程序函数equalsWithNulls来解决这个问题:

class MyUtils {
  public static final boolean equalsWithNulls(Object a, Object b) {
    if (a==b) return true;
    if ((a==null)||(b==null)) return false;
    return a.equals(b);
  }
}

用法:

if (MyUtils.equalsWithNulls(s1,s2)) {
  // do stuff
}

这种方法的优点:

  • 在单个函数调用中总结了完全相等测试的复杂性。我认为这比每次执行此操作时都在代码中嵌入一堆复杂的布尔测试要好得多。结果导致错误的可能性要小得多。
  • 使您的代码更具描述性,因此更易于阅读。
  • 通过在方法名称中明确提及空值,您可以向读者传达他们应该记住其中一个或两个参数可能为空值。
  • 是否首先进行 (a==b) 测试(在 a 和 b 非空但引用完全相同的对象的相当常见的情况下避免调用 a.equals(b) 的优化)
于 2012-06-13T09:22:49.677 回答
25

在执行 equals 方法之前,您需要检查至少一个不为空 -

if(s1 == s2 || (s1!=null && s1.equals(s2)))  {
   System.out.println("WORKING :)");
} 

在这里s1==s2可以工作null==null。但是,如果甚至一个不为空,那么您需要在执行 equals 之前检查至少 s1。

更新:正如@'bernard paulus' 所编辑,如果您使用的是 Java 7,则可以使用java.util.Objects.equals(Object, Object)

于 2012-06-13T09:21:33.067 回答
18

另一个使用选项:

Objects.equals(identification, criteria.getIdentification())

java.util.Objects

此类包含用于对对象进行操作的静态实用程序方法。这些实用程序包括用于计算对象的哈希码、返回对象的字符串以及比较两个对象的空值安全或空值容忍方法。

自:1.7

公共静态布尔等于(对象a,对象b)

如果参数彼此相等,则返回 true,否则返回 false。因此,如果两个参数都为 null,则返回 true,如果恰好一个参数为 null,则返回 false。否则,相等性是通过使用第一个参数的 equals 方法来确定的。

于 2016-04-19T10:48:59.383 回答
5

尝试使用 org.apache.commons.lang 中的 ObjectUtils 类

public static boolean equals(java.lang.Object object1,
                         java.lang.Object object2)

从 api 文档...

比较两个对象是否相等,其中一个或两个对象可能为空。

ObjectUtils.equals(null, null) = true

ObjectUtils.equals(null, "") = false

ObjectUtils.equals("", null) = false

ObjectUtils.equals("", "") = true

ObjectUtils.equals(Boolean.TRUE, null) = false

ObjectUtils.equals(Boolean.TRUE, "true") = false

ObjectUtils.equals(Boolean.TRUE, Boolean.TRUE) = true

ObjectUtils.equals(Boolean.TRUE, Boolean.FALSE) = false

于 2012-11-19T23:32:08.593 回答
3

您在为 null时收到 NullPointerException 的原因s1.equals(s2)不是因为s2 为 null,而是因为您试图在 s1 上调用 equals 方法,该方法为 null。s1

尝试像这样修改它:

if(s1 != null && s1.equals(s2){ /*...*/ }

另请注意,如果 s1 不为 null 而 s2 为 null,您将得到falseequals 的返回值,但没有 NullPointerException。

于 2012-06-13T09:21:20.630 回答
2
        String s1 = null;
        String s2 = null;

        if(s1 != null && s2 != null && s1.equals(s2)) {
            System.out.println("equals");
        } else {
            System.out.println("not equals");
        }
于 2012-06-13T09:21:46.500 回答
2

我认为您正在比较两个对象。

所以应该是这样的

if(s1==null & s2 == null)  // both null but equal
   return true;
else if(s1 != null && s2 != null && s1.equals(s2)) // both not null and equal
   return true;
else
   return false;

True - 等于 False - 不等于

于 2012-06-13T09:23:51.940 回答
1

如果您想知道某些内容是否为“空”,您可以使用以下方法进行比较:

if(s1==null)

如果它是空的,它会告诉你真实的。问题,如果你有一个空字符串,你不能使用equals()方法。由于这个原因,你的第三部分不起作用,因为如果它等于你就不能使用空指针。

您应该首先检查对象是否为空,然后如果它不为空,请使用 equals 方法。

另一方面要小心,因为也许你想比较空字符串,在这种情况下你必须使用 equal("")。如果要比较空字符串,最好将空字符串放在首位:

"".equals(YourStringNotNull);

对不起我的英语,希望对你有帮助。

于 2012-06-13T09:43:17.707 回答
0

在空对象上调用点运算符(调用方法或对象属性)将始终抛出 RuntimeException (异常是静态成员,因为它们不属于对象而是属于类)。

代码块之所以有效,只是因为 || 是一个快捷操作符:

 String s1 = null;
 String s2 = null;
 if(s1 == s2 || s1.equals(s2))

如果左侧为真,它不会评估右侧。

&& 相同:如果左侧为假,它不会评估右侧。

于 2013-12-27T09:26:02.117 回答