java中==比较的是内存地址是否相等。比较内存中存放的对象地址,真正意义上的指针操作。
equals比较的是继承于object中的equals方法的值比较,此方法的默认实现是比较两对象的==。
String 类改写了equals方法,比较的是其字符数组依次字符的char值。
==可以直接比较基础类型的值,int short long char 用在引用数据类型上比较的是引用数据类型的对象的对内存地址。
e'quals 是方法,对象比较的方法。
String 类型对象==比较
String str1 = "abc";
String str2="abc";
String str3 = new String("abc");
str1==str2 !=str3
方式一:String str1 = "abc"; =创建的字符串,会在字符串常量池中查找值为“abc”的字符串对象,如果没有用new的方式创建,
str1指向这个新的字符串的内存地址,如果有,不会创建新的字符串,共用一个字符串对象。
方式二:String str3=new String("abc");//使用new 的方式一定是在堆内存上创建新的对象,str3指向的新的对象的内存地址。
str1==str2 true;
str1==str3 false;
s5.intern()方法能使一个位于堆中的字符串在运行期间动态地加入到字符串常量池中(字符串常量池的内容是程序启动的时候就已经加载好了),如果字符串常量池中有该对象对应的字面量,则返回该字面量在字符串常量池中的引用
String str1 = "abc";//jdk6前字符串常量存放在方法区的常量池中,jdk7后字符串常量池放在堆中
String str2 = "abc";
String str3 = new String("abc");//new 出来的字符串,存放于堆内存中
String str4 = new String("abc");
String str5 = "abc";
String str6 = "ab";
String str7 = "c";
String str8 = str6 + str7;
String str9 = "a" + "bc";
String str10 = str3.intern();//intern()方法能使一个位于堆中的字符串在运行期间动态的加入到字符串常量池中,(字符串常量池的内容实在程序启动时加载好的)
System.out.println("str1==str2: " + Boolean.toString(str1 == str2));//str1==str2: true
System.out.println("str1==str3: " + Boolean.toString(str1 == str3));//str1==str3: false
System.out.println("str3==str4: " + Boolean.toString(str3 == str4));//str3==str4: false
// System.out.println("str1==str5: " + Boolean.toString(str1 == str5));
// System.out.println("str1==str8: " + Boolean.toString(str1 == str8));
/**字面量的拼接,在jvm编译期间进行了优化,用的也是常量池*/
System.out.println("str1==str9: " + Boolean.toString(str1 == str9));//str1==str9: true
System.out.println("str1==str10: " + Boolean.toString(str1 == str10));//str1==str10: true
String s1 = "hello";
String s2 = new String("hello");
String s3 = s2.intern();
String s4 = new String("hello").intern();
System.out.println("s1==s2: " + Boolean.toString(s1 == s2));//s1==s2: false
System.out.println("s1==s3: " + Boolean.toString(s1 == s3));//s1==s3: true
System.out.println("s1==s4: " + Boolean.toString(s1 == s4));//s1==s4: true
1.hashCode()
用来获取用户的哈希码,返回的是一个int整数。这个hash码的作用是确定对象在哈希表中的索引位置。
hashCode()只在类的散列表中才有意义
只在hashmap<>,hashSet<>,hashSet<>.哈希码才有用武之地
2.hashCode()和equals()的关系
如果不在类的散列表中,hashcode()与equals()毫无关系
如果在类的散列表中 例如hashSet<>去重,需要同时判断equals()方法和hashCode()方法
在散列表中
重写equals()方法一定要重写hashCode()方法。equals()比较的是两个对象的内容是否一样。hashCode()计算的两个对象的内存地址。equals()相等下,hashCode()不相等下,hashSet还是会存入两个内容相等的对象,因为hashSet会首先根据hashCode去查,不一样,会存入新的。所以在散列表,中,判定对象是否重复,必须同时改写hashCode()和equals(),否则必定会有相同内容的对象重复。
hashSet是通过hashMap实现的,hashMap的key不能重复。不能重复的判定逻辑是,先依照对象的hashCode()值换算成数组小标去hash表中寻找,如果没有就不重复,如果有在在此下标下的链表中通过equals()比较其中是否有重复对象,如果没有,则不重复,有则重复。