首页 > 其他 > 详细

包装类的创建及equals()和hashCode()方法

时间:2019-12-19 22:07:11      阅读:110      评论:0      收藏:0      [点我收藏+]

 一.包装类介绍

  

基本数据类型对应包装类
基本数据类型 包装类 基本数据类型 包装类
int Integer double Double
float Float boolean Boolean
short Short char Character
byte Byte long Long

二、创建包装类

  拿Integer为例,我们有三种方式为Integer类添加属性:

1         Integer i0 = new Integer(100);//不推荐
2         Integer i1 = 0;//默认调用valueOf()方法
3         Integer i2 = Integer.valueOf(10); 

   在这三种方式中,第三种方式不推荐使用,除了Float和Double,都会缓存包装类对象,具体参照:

      https://blog.csdn.net/qq_37206105/article/details/97281104

   在第一种创建方式中,由于Java5引入了自动装箱,其会直接调用Integer的valueOf()方法自动转化为Integer对象,而Float和Double会直接new一个对应的对象。

三、包装类中的hashCode()和equals()方法

  包装类都重写了Object类中的hashCode()和equals()方法,不同的实现类有不同的实现方式包装类实现equals方法时都先判断了类型是否相同,然后再判断值是否相同,各个包装类判断有不同的判断方式,先看看Integer的实现方式:

1 public boolean equals(Object obj) {
2          if (obj instanceof Integer) {//判断类型
3                  return value == ((Integer)obj).intValue();//返回int类型值然后判断是否相等
4              }
5          return false;
6 }

  Integer类的实现方式很简单,先判断参数类型是否为Integer类型然后调用方法返回其int类型值进行判断,在除了Float类外其他包装类的重写equals()方式都与Integer的实现方式相似,都会先判断类型然后再转化为对应类型值进行比较将结果返回,Byte、Short、Character及Integer的哈希码都为都为内部值,例如Character实例c0值为的哈希码为a:

public static void testCharacter(){
        Character c0 = ‘a‘;
        System.out.println(c0);
    }

  接下来介绍Boolean类,其hashCode()方法却有很大不同,接下来看一下hashCode()方法的源码:

1 public static int hashCode(boolean value) {
2         return value ? 1231 : 1237;
3     }

  在这个方法中根据传入布尔值进行判断,若为true则其哈希码为1231,false为1237,1231及1237为质数,不易冲突。介绍完了Boolean类,接下来说一下Long类,Long类的hashCode()方法源码如下:

1 public static int hashCode(long value) {
2         return (int)(value ^ (value >>> 32));
3     }

  在Long类内部对long类型数据进行了右移32位和异或操作,类似于这样操作的还有Double类:

1 public static int hashCode(double value) {
2         long bits = doubleToLongBits(value);
3         return (int)(bits ^ (bits >>> 32));
4     }

  不难看出,在Double类内部先将double转化成long类型然后进行了和Long类相同的操作,最后,我们介绍一下Float类:在Float类中,其equals()方法和hashCode()方法都与其他类不同,首先先看下equals()方法:

1 public boolean equals(Object obj) {
2         return (obj instanceof Float)
3                && (floatToIntBits(((Float)obj).value) == floatToIntBits(value));
4     }

  Float类和其他包装类一样,都是先进行了类型判断,只是在值判断阶段有些许不同,Float类在其内部将其二进制转化为整型然后对其比较,需要说明的是由于计算机对浮点型数据计算不精确的关系,其转化的哈希码也有所不同,看如下示例:

1      Float f1 = 0.01f;
2         Float f2 = 0.1f * 0.1f;
3         //两个Float对象哈希码不同,相差1
4         System.out.println(f1.hashCode());
5         System.out.println(f2.hashCode());
6         System.out.println(f1.equals(f2));//false 浮点数不精确,故此结果为false.

  从数学的角度来说,0.1*0.1为0.01,但是从输出结果来看,二者哈希码却相差1,因为计算机内部将其转化为二进制进行计算,而0.01的哈希码与0.1*0.1的哈希码并不相同,同样的,0.01和0.1*0.1的二进制也并不相同,因此此处第6行代码为false,需要说明的是:equals为true,则哈希码必定相同,equals为false哈希码则可能相同也可能不同。

包装类的创建及equals()和hashCode()方法

原文:https://www.cnblogs.com/rj182jysstudy/p/12069666.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!