A.==
1、基本类型,比较内容。
1. hashcode()方法,在object类中定义如下:
public native int hashCode();
说明是一个本地方法,它的实现是根据本地机器相关的。
2.String类中重写了hashcode()方法如下:
1.equals()相等的两个对象,hashcode()一定相等;
2.equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。换句话说,equals()方法不相等的两个对象,hashcode()有可能相等。(我的理解是由于哈希码在生成的时候产生冲突造成的)。
E.谈到hashcode()和equals()就不能不说到 hashset,hashmap,hashtable中的使用,具体是怎样呢,请看如下分析:
1.Hashset是继承Set接口,Set接口又实现Collection接口,这是层次关系。那么hashset是根据什么原理来存取对象的呢?
在hashset中不允许出现重复对象,元素的位置也是不确定的。在hashset中又是怎样判定元素是否重复的呢?
判断两个对象是否相等的规则是:
1),判断两个对象的hashCode是否相等: 如果不相等,认为两个对象也不相等,完毕 ,如果相等,转入2)
(这一点只是为了提高存储效率而要求的,其实理论上没有也可以,但如果没有,实际使用时效率会大大降低,所以我们这里将其做为必需的。后面会重点讲到这 个问题。)
2),判断两个对象用equals运算是否相等:如果不相等,认为两个对象也不相等, 如果相等,认为两个对象相等(equals()是判断两个对象是否相等的关键)
2.看看Hashset
4 .HashSet添加我们自己写的对象,实现 HashSet去重复功能
F.
1、基本类型,比较内容。
2、引用类型,比较地址。
B.equals
1.首先equals()和hashcode()这两个方法都是从object类中继承过来的。 equals()方法在object类中定义如下(默认比较地址):
<span style="white-space:pre"> </span>public boolean equals(Object obj) {
<span style="white-space:pre"> </span>return (this == obj);
<span style="white-space:pre"> </span>}
2.String中,jdk重写了equals方法,此时可以看出,比较的是内容
<span style="white-space:pre"> </span>public boolean equals(Object anObject) {
<span style="white-space:pre"> </span>if (anObject instanceof String) {
<span style="white-space:pre"> </span>String anotherString = (String) anObject;
<span style="white-space:pre"> </span>int n = count;
<span style="white-space:pre"> </span>if (n == anotherString.count) {
<span style="white-space:pre"> </span>char v1[] = value;
<span style="white-space:pre"> </span>char v2[] = anotherString.value;
<span style="white-space:pre"> </span>int i = offset;
<span style="white-space:pre"> </span>int j = anotherString.offset;
<span style="white-space:pre"> </span>while (n-- != 0) {
<span style="white-space:pre"> </span>if (v1[i++] != v2[j++])
<span style="white-space:pre"> </span>return false;
<span style="white-space:pre"> </span>}
return true;
}
}
<span style="white-space:pre"> </span>return false;
<span style="white-space:pre"> </span>}
1. hashcode()方法,在object类中定义如下:
public native int hashCode();
说明是一个本地方法,它的实现是根据本地机器相关的。
2.String类中重写了hashcode()方法如下:
<span style="white-space:pre"> </span>public int hashCode() {
<span style="white-space:pre"> </span>int h = hash;
<span style="white-space:pre"> </span>if (h == 0) {
<span style="white-space:pre"> </span>int off = offset;
char val[] = value;
int len = count;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
<span style="white-space:pre"> </span>}
1.equals()相等的两个对象,hashcode()一定相等;
2.equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。换句话说,equals()方法不相等的两个对象,hashcode()有可能相等。(我的理解是由于哈希码在生成的时候产生冲突造成的)。
E.谈到hashcode()和equals()就不能不说到 hashset,hashmap,hashtable中的使用,具体是怎样呢,请看如下分析:
1.Hashset是继承Set接口,Set接口又实现Collection接口,这是层次关系。那么hashset是根据什么原理来存取对象的呢?
在hashset中不允许出现重复对象,元素的位置也是不确定的。在hashset中又是怎样判定元素是否重复的呢?
判断两个对象是否相等的规则是:
1),判断两个对象的hashCode是否相等: 如果不相等,认为两个对象也不相等,完毕 ,如果相等,转入2)
(这一点只是为了提高存储效率而要求的,其实理论上没有也可以,但如果没有,实际使用时效率会大大降低,所以我们这里将其做为必需的。后面会重点讲到这 个问题。)
2),判断两个对象用equals运算是否相等:如果不相等,认为两个对象也不相等, 如果相等,认为两个对象相等(equals()是判断两个对象是否相等的关键)
2.看看Hashset
<span style="white-space:pre"> </span>@Test
public void test2() {
String s1 = new String("zhaoxudong");
String s2 = new String("zhaoxudong");
System.out.println(s1 == s2);// false
System.out.println(s1.equals(s2));// true
System.out.println(s1.hashCode());// s1.hashcode()等于s2.hashcode()
System.out.println(s2.hashCode());
/**
* 此时add后,如果s1和s2是同一个对象,则会覆盖,hashset只有一个元素。
*/
Set hashset = new HashSet();
hashset.add(s1);
hashset.add(s2);
/**
* 结果:hashset只有一个元素。
* 原因:实质上在添加s1,s2时,运用上面说到的两点准则(因为String类已经重写了equals()方法和hashcode()方法,
* 所以在根据上面的第1.2条原则判定时,s1和s2在HashSet中被认为是同一个对象),可以知道hashset认为s1和s2是相等的,是在添加重复<span style="white-space:pre"> </span>元<span style="white-space:pre"> </span>素,所以让s2覆盖了s1;
*/
Iterator it = hashset.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
3.HashSet添加我们自己写的对象,没有重写equals和hashcode,没有实现
HashSet去重复功能
public class JtestHashCode {
<span style="white-space:pre"> </span>public static void main(String[] args) {
<span style="white-space:pre"> </span>HashSet hs = new HashSet();
<span style="white-space:pre"> </span>hs.add(new Student(1, "zhangsan"));
<span style="white-space:pre"> </span>hs.add(new Student(2, "lisi"));
<span style="white-space:pre"> </span>hs.add(new Student(3, "wangwu"));
<span style="white-space:pre"> </span>hs.add(new Student(1, "zhangsan"));
<span style="white-space:pre"> /**
<span style="white-space:pre"> </span> * 得出来的结果,存在重复的new Student(1, "zhangsan"),
<span style="white-space:pre"> </span> * 原因:由于我们没重写Student类的equals和hashcode,导致两个new Student(1, "zhangsan")不是同一对象,这就没有实现HashSet的去重复,
其实本来就不是同一个,但是要实现HashSet的去重复功能,必须就得重写Student类的equals和hashcode
<span style="white-space:pre"> </span> */</span>
<span style="white-space:pre"> </span>Iterator it = hs.iterator();
<span style="white-space:pre"> </span>while (it.hasNext()) {
<span style="white-space:pre"> </span>System.out.println(it.next());
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
}
class Student {
<span style="white-space:pre"> </span>int num;
<span style="white-space:pre"> </span>String name;
<span style="white-space:pre"> </span>Student(int num, String name) {
<span style="white-space:pre"> </span>this.num = num;
<span style="white-space:pre"> </span>this.name = name;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>public String toString() {
<span style="white-space:pre"> </span>return num + ":" + name;
<span style="white-space:pre"> </span>}
}
4 .HashSet添加我们自己写的对象,实现 HashSet去重复功能
public class JtestHashCode {
public static void main(String[] args) {
HashSet hs = new HashSet();
hs.add(new Student(1, "zhangsan"));
hs.add(new Student(2, "lisi"));
hs.add(new Student(3, "wangwu"));
hs.add(new Student(1, "zhangsan"));
/**
* 得出来的结果,HashSet去掉重复了,
* 原因:我们没重写Student类的equals和hashcode,在HashSet添加对象的时候,jdk会比较对象是否存在
*/
Iterator it = hs.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
class Student {
int num;
String name;
Student(int num, String name) {
this.num = num;
this.name = name;
}
public int hashCode() {
return num * name.hashCode();
}
public boolean equals(Object o) {
Student s = (Student) o;
return num == s.num && name.equals(s.name);
}
public String toString() {
return num + ":" + name;
}
}
F.