java Objects.equals; BigDecimal ;重写equals是不是你想要的

  • Objects.equals
    网上许多例子在说 if(a.equals("str")) 应该改写成 if ("str".equals(a)); 之后说可以使用 Objects.equals方法来比较 ;
    在使用Objects.equals时 底层是
    image.png

在使用的时候,如果a和b都是null 那么Objects.equals(a,b)返回的是什么呢?是否会到达预期(当然是业务预期)结果; 这个结果返回 是true ;可能有的业务预期是false 感觉大多数的业务预期都是false吧 ,这里使用的时候注意一下;

  • BigDecimal BigInteger
    浮点型数据在进行笔记比较的时候 是否会有一些“意料之外的惊喜”呢,
float a = 1.0f - 0.9f;
float b = 0.9f - 0.8f;
System.out.println(a);// 0.100000024
System.out.println(b);// 0.099999964
System.out.println(a == b);// false

然后大家想到了BigDecimal ,但是在使用时候需要注意

BigDecimal bigDecimalStr = new BigDecimal("0.1");
BigDecimal bigDecimalFloat = new BigDecimal(0.1);//强烈不建议 但是为什么这个构造还存在 这个有待讨论
log.info("bigDecimalStr {} bigDecimalFloat {}", bigDecimalStr, bigDecimalFloat);
//bigDecimalStr 0.1 bigDecimalFloat 0.1000000000000000055511151231257827021181583404541015625

总结:

BigDecimal 主要用来操作(大 到底有多大?)浮点数,BigInteger 主要用来操作大整数(超过 long 类型)。
BigDecimal 的实现利用到了 BigInteger, 所不同的是 BigDecimal 加入了小数位的概念
到底有多大 有这么大 这个是BigInteger限制 (感觉你计算什么都够用了 嘿嘿)

/**
     * This constant limits {@code mag.length} of BigIntegers to the supported
     * range.
     */
    private static final int MAX_MAG_LENGTH = Integer.MAX_VALUE / Integer.SIZE + 1; // (1 << 26)

/**
     * Throws an {@code ArithmeticException} if the {@code BigInteger} would be
     * out of the supported range.
     *
     * @throws ArithmeticException if {@code this} exceeds the supported range.
     */
    private void checkRange() {
        if (mag.length > MAX_MAG_LENGTH || mag.length == MAX_MAG_LENGTH && mag[0] < 0) {
            reportOverflow();
        }
    }

    private static void reportOverflow() {
        throw new ArithmeticException("BigInteger would overflow supported range");
    }
  • hashCode equals
    为什么重写 equals 时必须重写 hashCode 方法?

先说一下java规范
规范1:若重写equals(Object obj)方法,有必要重写hashcode()方法,确保通过equals(Object obj)方法判断结果为true的两个对象具备相等的hashcode()返回值。说得简单点就是:“如果两个对象相同,那么他们的hashcode应该 相等”。不过请注意:这个只是规范,如果你非要写一个类让equals(Object obj)返回true而hashcode()返回两个不相等的值,编译和运行都是不会报错的。不过这样违反了Java规范,程序也就埋下了BUG。

规范2:如果equals(Object obj)返回false,即两个对象“不相同”,并不要求对这两个对象调用hashcode()方法得到两个不相同的数。说的简单点就是:“如果两个对象不相同,他们的hashcode可能相同”。

根据这两个规范,可以得到如下推论:

1、如果两个对象equals,Java运行时环境会认为他们的hashcode一定相等。

2、如果两个对象不equals,他们的hashcode有可能相等。

3、如果两个对象hashcode相等,他们不一定equals。

4、如果两个对象hashcode不相等,他们一定不equals。

如果两个对象相等,则 hashcode 一定也是相同的。两个对象相等,对两个对象分别调用 equals 方法都返回 true。但是,两个对象有相同的 hashcode 值,它们也不一定是相等的 。因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖。

hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)

在使用HashSet进行add操作的时候 如果只是重写了equals方法 没有重写hashcode方法 那么两个相同(属性值都一样的)对象 会同时存在 ,但是却不会影响你使用该对象的equals方法;
杂凑算法-哈希
哈希冲突解决办法

基本类型 位数 字节 默认值
int 32 4 0
short 16 2 0
long 64 8 0L
byte 8 1 0
char 16 2 'u0000'
float 32 4 0f
double 64 8 0d
boolean 1 false
        Long al=1L;
        Integer ai = 1;
        al.equals(ai);//false
        boolean equals1 = Objects.equals(al, 1);
        log.info("equals1 {}", equals1);//false

原因 :底层判断了类型


image.png

你可能感兴趣的:(java Objects.equals; BigDecimal ;重写equals是不是你想要的)