首页 > 解决方案 > 等于并与 BigDecimal 比较

问题描述

我有一个覆盖hashCode() 和equals()-method 的类。当我处理时BigDecimal,我必须使用compareTo()而不是Objects.equals()

public class MyProduct extends Product{

private BigDecimal price;


@Override
public int hashCode() {
    return Objects.hash(price);
}


@Override
public boolean equals(Object obj) {

        if (this == obj) return true; // is this right or should this be deleted

        if (obj == null || getClass() != obj.getClass()) return false;

        final Product other = (Product) obj;

        // is this right?
        if (price == null ? (other.price != null) : price.compareTo(other.price) != 0) {
            return false;
        }
        return super.equals(obj);
    }

}

我有以下问题:

  1. 我应该if (this == obj) return true;equals()-method 中删除该行吗?因为有了这一行,compareTo 不会被触发,并且可能会计算出错误的 equals(),对吗?
  2. 可以改进 equals() 方法吗?

标签: java

解决方案


第一行只是为了在两个引用都指向同一个对象时提前返回结果的优化。

可以为price空吗?我认为是的,因为您正在equals()执行中检查它。在这种情况下,您的代码将无法正常工作,other.price以防null. 特别是这里的代码:

price.compareTo(other.price) != 0

会抛出一个NullPointerException.

你可以像这样修复它:

    @Override
    public boolean equals(Object obj) {

        if (this == obj) return true; // is this right or should this be deleted

        if (obj == null || getClass() != obj.getClass()) return false;

        final MyProduct other = (MyProduct) obj;

        // If you prefer, the below two can be replaced with a single condition
        // price != null ^ other.price != null
        // Credits to @Andreas
        if (price == null && other.price != null) {
            return false;
        }
        if (price != null && other.price == null) {
            return false;
        }
        if (other.price != null && price.compareTo(other.price) != 0) {
            return false;
        }

        return super.equals(obj);
    }

现在,您可能可以将其缩短,但我个人认为这种方式最具可读性。

无论如何,除非您真的非常关心自定义您的equals()实现,否则我建议您使用您的 IDE 生成一个并坚持使用它。他们大部分时间都做得不错,您不必担心它会被破坏(尽管比较BigDecimals对他们来说可能很棘手,因为您不关心规模而只关心价值)。


推荐阅读