JAVA中equals,== 和 hashcode 的区别

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Dan_2017/article/details/79535722

(一) ==

 java中数据类型分为两类:

(1)基本数据类型:byte,char,short,int,float,double,long,boolean。当比较基本数据类型的时候用 == 比较的是他们的值。

(2)引用类型(类,数组,接口):当用等号比较这三种类型的时候比较的是内存中存放的地址。

        对象是存放在堆中的,栈中存放的是对象的引用地址,所以用 == 比较时比较的时栈中存放的值。

实例1:

	public static void main(String[] args) {
		int int1 = 12;
		int int2 = 12;
		Integer Integer1 = new Integer(12);
		Integer Integer2 = new Integer(12);
		Integer Integer3 = new Integer(127);

		Integer a1 = 127;
		Integer b1 = 127;

		Integer a = 128;
		Integer b = 128;

		String s1 = "str";
		String s2 = "str";
		String str1 = new String("str");
		String str2 = new String("str");
		
		 //int1==int2:true 
		System.out.println("int1==int2:" + (int1 == int2));
		
		//int1==Integer1:true  这里Integer1自动拆箱成int,所以为true
		System.out.println("int1==Integer1:" + (int1 == Integer1)); 
		
		//Integer1==Integer2:false 这是两个不同的对象,在内存中存放的地址不同
		System.out.println("Integer1==Integer2:" + (Integer1 == Integer2));
		
		//Integer3==b1:false  Integer3指向new的对象地址,b1只想缓存中的127地址,地址不同
		System.out.println("Integer3==b1:" + (Integer3 == b1));
		
		
		//a1==b1:true Integer查看源码就知道对于-128  -- 127之间的数会进行直接缓存,
		//当Integer a1时会将127进行缓存,在写Integer b1时会去缓存中直接读取,不会new,所以相等
		System.out.println("a1==b1:" + (a1 == b1));
		
		//a==b:false  同a1,b1不同他每次都会new
		System.out.println("a==b:" + (a == b));

		//s1==s2:true  这两个都是String字符串常量,存在静态区
		System.out.println("s1==s2:" + (s1 == s2));
		
		//s1==str1:false
		System.out.println("s1==str1:" + (s1 == str1));
		
		//str1==str2:false
		System.out.println("str1==str2:" + (str1 == str2));
	}

补充:

JVM内存分四种:1、栈区(stacksegment)—由编译器自动分配释放,存放函数的参数值,局部变量的值等,具体方法执行结束之后,系统自动释放JVM内存资源2、堆区(heapsegment)—一般由程序员分配释放,存放由new创建的对象和数组,jvm不定时查看这个对象,如果没有引用指向这个对象就回收3、静态区(datasegment)—存放全局变量静态变量字符串常量,不释放

4、代码区(codesegment)—存放程序中方法的二进制代码,而且是多个对象共享一个代码空间区域


(二):equals()

扫描二维码关注公众号,回复: 3552305 查看本文章

JAVA当中所有的类都是继承于Object这个超类的,在Object类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地址,但在一些类库当中这个方法被复写了,如String、Integer、Date。在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。 
所以说,对于复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是内存中的存放位置的地址值,跟双等号(==)的结果相同;如果被复写,按照复写的要求来。
 
【特别注意】Object类中的equals方法和“==”是一样的,没有区别,而String类,Integer类等等一些类,是重写了equals方法,才使得equals和“==不同”,所以,当自己创建类时,自动继承了Object的equals方法,要想实现不同的等于比较,必须重写equals方法。

"=="比"equal"运行速度快,因为"=="只是比较引用.

注意规范:"".equals(str);而不是str.equals("");

因为str可能为空,这容易出错,所以一般将需要被比较的常量写在前面。


补充: equals 方法实现的规则

自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。 
对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。 
传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。 

一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。 

对于任何非空引用值 x,x.equals(null) 都应返回 false。 

(三):hashcode()

关于Object 类中hashCode() 方法的实现。。对象的Object类的哈希码的值 是一个和该对象内存地址有关的一个int值。
不同对象的内存地址是不同的。

返回该对象的哈希码值。支持此方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。 
hashCode 的常规协定是: 

在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。 
如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。 
如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。 


实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)

哈希码,又叫做散列码。
得到对象的哈希码:要求对象的哈希码均匀的散列在正数 的取值范围内。可以让对象均匀的散列在哈希表的线性表中。

hashCode 方法 用来确定对象在线性表中的位置。和高速访问元素。
equals 用来保证set中的元素的唯一性

对于两个对象来说,如果对象对应的类型中没有重写hashCode方法。如果两个对象的哈希码值相同,说明了什么?说明两个对象是同一个对象,指向了同一个内存区域。


猜你喜欢

转载自blog.csdn.net/Dan_2017/article/details/79535722
今日推荐