为了账号安全,请及时绑定邮箱和手机立即绑定

等于并与 BigDecimal 进行比较

等于并与 BigDecimal 进行比较

12345678_0001 2023-08-04 14:50:32
我有一个类重写hashCode() 和equals()- 方法。当我处理时BigDecimal,我必须compareTo()使用Objects.equals():public class MyProduct extends Product{private BigDecimal price;@Overridepublic int hashCode() {    return Objects.hash(price);}@Overridepublic 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);    }}我有以下问题:if (this == obj) return true;我应该从-method 中删除该行吗equals()?因为使用这一行,compareTo 不会被触发,并且可能会计算出错误的 equals(),对吗?equals()方法可以改进吗?
查看完整描述

3 回答

?
有只小跳蛙

TA贡献1824条经验 获得超8个赞

第一行只是一种优化,旨在如果两个引用都指向同一对象,则提前返回结果。


可以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他们来说可能很棘手,因为你不关心规模而只关心价值)。


查看完整回答
反对 回复 2023-08-04
?
忽然笑

TA贡献1806条经验 获得超5个赞

我编写了一个 utitly 方法,可用于比较两个 BigDecimals 而不会抛出 NPE:


// returns true, if val1 is the same as val2

// can this be improved ?

public static boolean isEqual(BigDecimal val1, BigDecimal val2) {

        return !((val1 != null ^ val2 != null) || (val2 != null && val1.compareTo(val2) != 0));

    }

这可以在 equals 方法中使用:


@Override

    public boolean equals(Object obj) {

        if (this == obj) return true;

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

        final MyProduct other = (MyProduct) obj;


        if(!isEqual(price, other.price)) return false;


        return super.equals(obj);

    }


查看完整回答
反对 回复 2023-08-04
?
慕村225694

TA贡献1880条经验 获得超4个赞

我找到了最简单的方法:


public static boolean isEqual(BigDecimal val1, BigDecimal val2) {

    return val1 != null ^ val2 != null && val2 != null && val1.compareTo(val2) != 0;

}

然后在 equals() 中使用它:


public boolean equals(Object obj) {

        if (this == obj) return true;

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

        final MyProduct other = (MyProduct) obj;


        if(!isEqual(price, other.price)) return false;


        return super.equals(obj);

    }


查看完整回答
反对 回复 2023-08-04
  • 3 回答
  • 0 关注
  • 140 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信