You need to enable JavaScript to run this app. Java二叉树TreeNode自定义equals方法空指针异常原因及解决
优惠活动
大模型
产品
解决方案
定价
更多

Java二叉树TreeNode自定义equals方法空指针异常原因及解决

为什么自定义TreeNode的equals方法会触发空指针异常

最初的实现存在两个导致运行失败的核心问题:

  • 方法内的this == null判断逻辑完全无效:Java语法中,只要实例方法能执行到方法体内部,就说明调用该方法的对象本身是非空的,this在方法执行周期内永远不可能为null,这个判断分支根本不可能被触发。
  • 递归调用没有前置空值校验:当递归遍历到某一层时,如果当前节点的left或right子节点本身为null,代码直接执行this.left.equals(other.left)本质就是对null对象调用实例方法,必然抛出NullPointerException。原代码里的空值判断覆盖不到这个场景——触发空指针的是要被调用方法的子节点,不是当前正在执行equals方法的节点。

可行的修复实现

方案1:抽取独立静态比较方法

将两个节点的相等判断逻辑封装为静态方法,不依赖实例调用,从根源上避免“对null对象调用实例方法”的问题:

public static boolean isEqual(TreeNode self, TreeNode other) {
    if (self == null && other == null) {
        return true;
    } else if (self == null || other == null) {
        return false;
    } else {
        return self.val == other.val
                && isEqual(self.left, other.left)
                && isEqual(self.right, other.right);
    }
}

静态方法可以直接接收null参数完成空值判断,不会因为调用对象为null就直接触发异常,实际运行效果验证:

TreeNode a = new TreeNode(5);
TreeNode b = new TreeNode(5);
System.out.println(TreeNode.isEqual(a, b)); // 输出 true

方案2:实例方法内先做空值校验再触发递归

如果需要保留实例形式的equals方法,就不能直接在可能为null的子节点上调用equals,必须先逐一对左右子节点做空值判断,确认非空时再触发递归:

public boolean equals(TreeNode other) {
    // 双方左右子节点全为空时,仅比较当前节点值
    if (this.left == null && other.left == null && this.right == null && other.right == null) {
        return this.val == other.val;
    } 
    // 双方左右子节点全非空时,全量递归比较
    else if (this.left != null && other.left != null && this.right != null && other.right != null) {
        return this.val == other.val && this.left.equals(other.left) && this.right.equals(other.right);
    } 
    // 仅左子节点双非空、右子节点双空时,只递归比较左子树
    else if (this.left != null && other.left != null && this.right == null && other.right == null) {
        return this.val == other.val && this.left.equals(other.left);
    } 
    // 仅右子节点双非空、左子节点双空时,只递归比较右子树
    else if (this.left == null && other.left == null && this.right != null && other.right != null) {
        return this.val == other.val && this.right.equals(other.right);
    } 
    // 其余单边子节点非空的场景,直接判定不相等
    else {
        return false;
    }
}

额外提醒:上述实例equals的方法签名是equals(TreeNode other),并不是重写java.lang.Object的equals(Object obj)方法。如果将TreeNode存入依赖相等判断的集合(如HashMap、HashSet),该方法不会被自动触发,无法满足Java对象相等的通用契约。

内容的提问来源于stack exchange,提问作者jxie0755

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.05 08:24:08