美文网首页
java Objects.equals; BigDecimal

java Objects.equals; BigDecimal

作者: 黑暗中冬眠的华仔 | 来源:发表于2020-09-03 20:24 被阅读0次
    • 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

          本文链接:https://www.haomeiwen.com/subject/fusnsktx.html