如何在我自己的类中处理null以避免NullPointerException

时间:2019-06-25 18:21:12

标签: java null

作为一种实践,我正在尝试为我的LinkedList构建一个类,因为我以前在python中进行过工作,所以我知道我可以轻松地以递归方式设置一种方法来检查两个链表是否相等:

class ListNode {
    int val;
    ListNode next;

    ListNode(int x) {
        val = x;
    }

    public boolean equals(ListNode other) {
        if (this == null && other == null) {
            return true;
        } else if (this == null || other == null) {
            return false;
        } else {
            return this.val == other.val && this.next.equals(other.next);
        }
    }

但是,由于这在python中可以正常工作,因此在java(我得到NullPointerException)中不起作用,这不足为奇,因为我需要处理node.nextnull,则null.equals(other)无法执行,因为null没有方法equals

所以我想出了一种可以使用的静态方法,但是我不太喜欢它。

public static boolean equals(ListNode self, ListNode other) {
    if (self == null && other == null) {
        return true;
    } else if (self == null || other == null) {
        return false;
    } else {
        return self.val == other.val && equals(self.next, other.next);
    }
}

我想知道是否有更好的方法来处理这种常见情况?

好的,我想了一下,可以通过首先检查下一个值来保持非静态状态:

public boolean equals(ListNode other) {
    if (this.next == null && other.next == null) {
        return this.val == other.val;
    } else if (this.next == null || other.next == null) {
        return false;
    } else {
        return this.val == other.val && this.next.equals(other.next);
    }
}

这是个好方法吗?

2 个答案:

答案 0 :(得分:1)

起初,您的代码看起来不错,并且即使考虑为equals函数编写漂亮的代码也很酷。

1)提醒一下,Object#equals方法以Object作为参数,而不是声明此#equals的同一类的实例({{ 1}})。

2)我可以建议的另一点是,不要在ListNode语句后放置多余的else

3)您可以使用标准的return方法进行可靠的空安全检查。

4)结束时,我们来看一下IDEA如何为我们的java.util.Objects.equals类生成默认的#equals覆盖。 我已将代码对齐以使其易于阅读,并添加了澄清的注释:

ListNode

5)我认为,这种package com.dpopov.rxjava.stackoverflow; import java.util.Objects; public class ListNode { private int val; private ListNode next; @Override public boolean equals(final Object o) { // if this is the same object as o, no further check required if (this == o) return true; // case handles other object == null and different class of other Object if (o == null || getClass() != o.getClass()) return false; // now we now that o can be cast to ListNode final ListNode listNode = (ListNode) o; return (val == listNode.val) // primitive type cast comparison require no null-checks && Objects.equals(next, listNode.next); // utility method takes care of nulls } @Override public int hashCode() { return Objects.hash(val, next); } } 实现非常接近完美。 我唯一可能做的选择是将最终逻辑表达式和第二个#equals拆分为单独的if语句,以使所有内容成为一个简单的逻辑表达式,并始终“失败优先”,即返回对于我们的if方法,在所有可能的情况下都是false

equals

但是这已经基本上是一个品味问题了。可以合理地认为,简单的逻辑表达更为清晰。

答案 1 :(得分:0)

  

我想知道是否有更好的方法来处理这种常见问题   情况?

您可以将代码放入try-catch块中,

public boolean equals(ListNode other) {
    try {
        if (this == null && other == null) {
            return true;
        } else if (this == null || other == null) {
            return false;
        } else {
            return this.val == other.val && this.next.equals(other.next);
        }
    } catch (Exception ex) {
        /* Handle Exception */
        return false;
    }
}

或者,您可以简单地处理node.next可以为null的情况,

public boolean equals(ListNode other) {
    if (this == null && other == null) {
        return true;
    } else if (this == null || other == null) {
        return false;
    } else if (this.next != null) {
        return this.val == other.val && this.next.equals(other.next);
    }
    return false;
}