基本数据类型 | 包装类 | 基本数据类型 | 包装类 |
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一个对应的对象。
包装类都重写了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哈希码则可能相同也可能不同。
原文:https://www.cnblogs.com/rj182jysstudy/p/12069666.html