java中==和equals和hashCode的区别

java中的数据类型分为两种:
基本数据类型:
  byte,short,char,int,float,double, long,boolean
以上为基本数据类型的之间的比较应该用双等号(==),基本数据类型数值中的地址值也是相同的
引用数据类型:
  类,接口,数组和其他被new出来的对象,需要用equals去比较, 双等号“ == ” 比较的是对象的地址值,也就是在栈中的值,对象是放在堆中的,所以需要重写“equals”去比较

public static void main(String[] args) {
        int aInt = 127;
        int bInt = 127;
        Integer aInteger = new Integer(127);
        Integer bInteger = new Integer(127);

        int cInt = 128;
        int dInt = 128;
        Integer eInteger = 128;
        Integer dInteger = 128;

        System.out.println("aInt == bInt   :" +(aInt == bInt));
        System.out.println("aInteger == bInteger   :" +(aInteger == bInteger));

        System.out.println("cInt == dInt   :" +(cInt == dInt));
        //重点来了啊
        System.out.println("aInt == aInteger   :" +(aInt == aInteger));
		System.out.println("eInteger == dInteger   :" +(eInteger == dInteger));
      --------------------------------------------
        String s1 = "str";
        String s2 = "str";
        String str1 = new String("str");
        String str2 = new String("str");

        System.out.println("s1==s2:" + (s1 == s2));
        System.out.println("s1==str1:" + (s1 == str1));
        System.out.println("str1==str2:" + (str1 == str2));
    }

输出结果:
	aInt == bInt   :true
	aInteger == bInteger   :false
	cInt == dInt   :true
	eInteger == dInteger   :false
	aInt == aInteger   :true
	---------------------------------------
	s1==s2:true
	s1==str1:false
	str1==str2:false

Integer value = 123;
实际的编译过程是:Integer value = Integer.valueOf(123);
由上面代码块中可以看出,在 int = 127, 和128时,是有差别的
看一下源码:

public static Integer valueOf(int i) {  
         assert IntegerCache.high >= 127;  
         if (i >= IntegerCache.low && i <= IntegerCache.high)  
             return IntegerCache.cache[i + (-IntegerCache.low)];  
         return new Integer(i);  
     } 

对于-128到127之间的数,会进行缓存,Integer b1 = 127时,会将127进行缓存,下次再写Integer i6 = 127时,就会直接从缓存中取,就不会new了。
所以:eInteger == dInteger :false aInt == aInteger :true

关于equals
  从上面也可以看出,“ ==”比较的栈中的地址值,“equals”比较的才是实际赋予的对象的堆中的数据值,
如果对象中覆盖了“equals”方法,那就要视实际的代码确定执行作用了
在《Effective Java》中介绍到关于“equals”有五点比较重要的定义:

  1. 自反性:对任意引用值X,x.equals(x)的返回值一定为true.
  2. 对称性:对于任何引用值x,y,当且仅当y.equals(x)返回值为true时,x.equals(y)的返回值一定为true;
  3. 传递性:如果x.equals(y)=true, y.equals(z)=true,则x.equals(z)=true
  4. 一致性:如果参与比较的对象没任何改变,则对象比较的结果也不应该有任何改变
  5. 非空性:任何非空的引用值X,x.equals(null)的返回值一定为false

关于hashCode:
  当集合要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。 如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如果这个位置上已经有元素了,就调用它的equals方法与新元素进行比较,相同的话就不存,不相同就散列其它的地址。所以这里存在一个冲突解决的问题。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次,极高的提高了效率。

hashCode和equals之间的关系

  1. 如果两个对象equals,Java运行时环境会认为他们的hashcode一定相等。
  2. 如果两个对象不equals,他们的hashcode有可能相等。
  3. 如果两个对象hashcode相等,他们不一定equals。
  4. 如果两个对象hashcode不相等,他们一定不equals。

总结:
1. 基本数据类型用“ == ”比较其中的值
2. 比较对象内容是否相等用“equals”
3. hashCode只有在集合中用到
4. 当 “ equals() ”方法被覆盖掉的时候,比较对象是否相等,就用覆盖的逻辑方法
5. hashCode最大的作用,在集合中,将对象放入到集合中时,首先判断要放入对象的hashcode值与集合中的任意一个元素的hashcode值是否相等,如果不相等直接将该对象放入集合中。如果hashcode值相等,然后再通过equals方法判断要放入对象与集合中的任意一个对象是否相等,如果equals判断不相等,直接将该元素放入到集合中,否则不放入。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值