黑马程序员技术交流社区
标题:
关于hashSet的总结
[打印本页]
作者:
gzbbxu
时间:
2013-6-27 16:48
标题:
关于hashSet的总结
,HashSet:数据结构是哈希表,线程是非同步的
哈希表是按照哈希值来存储的
不是同一对象,但是地址值是一样的,这个时候他会在该地址值下顺延。
保证元素唯一性的原理:判断元素的hashCode值是否相同
如果相同,还会继续判断元素的equals方法,是否为true;添加失败就为假。
HashSet是如何保证元素唯一性的呢?
是通过元素的两个方法,hashCode和equals来完成。
如果元素的HashCode值相同,才会判断euqals是否为true,如果元素的hashscode值不同,不会调用equals.(建立一个比较有针对性的hashcode会比较高效一些)
import java.util.HashSet;
import java.util.Iterator;
/**
* HashSet存储自定义对象
*
* @author Administrator 网hashset存入自定义对象,姓名和年龄相同为同一个人,重复元素
*/
public class Test2 {
public static void main(String[] args) {
HashSet hs = new HashSet();
hs.add(new Person("a1", 11));
hs.add(new Person("a2", 12));
hs.add(new Person("a3", 13));
hs.add(new Person("a2", 12));
//hs.add(new Person("a4", 14));
Iterator it = hs.iterator();
while (it.hasNext()) {
Person p = (Person) it.next();
sop(p.getName()+"::"+p.getAge());
}
}
public static void sop(Object obj) {
System.out.println(obj);
}
}
class Person {
private String name;
public String getName() {
return name;
}
public int getAge() {
return age;
}
private int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
public boolean equals(Object obj) {
if (!(obj instanceof Person)) {
return false;
}
Person p = (Person) obj;
return this.name.equals(p.name) && this.age == p.age;
}
}
复制代码
以上打印结果为:
a2::12
a1::11
a2::12
a3::13
equals没有被调用。因为比较先看地址。new 出来的,都有自己独立的hashcode,有自己的位置存储,都存进去了,不用再读equals方法了。
现在要覆盖Person 的hashcode方法,建立Person对象自己的哈希值。怎么建立哈希值呢?你的判断条件是什么,依据条件来生成哈希值,这里按照姓名年龄判断是不是同一个元素,那就依据这个条件判断哈希值。
import java.util.HashSet;
import java.util.Iterator;
/**
* HashSet存储自定义对象
*
* @author Administrator 网hashset存入自定义对象,姓名和年龄相同为同一个人,重复元素
*/
public class Test2 {
public static void main(String[] args) {
HashSet hs = new HashSet();
hs.add(new Person("a1", 11));
hs.add(new Person("a2", 12));
hs.add(new Person("a3", 13));
hs.add(new Person("a2", 12));
//hs.add(new Person("a4", 14));
Iterator it = hs.iterator();
while (it.hasNext()) {
Person p = (Person) it.next();
sop(p.getName()+"::"+p.getAge());
}
}
public static void sop(Object obj) {
System.out.println(obj);
}
}
class Person {
private String name;
public String getName() {
return name;
}
public int getAge() {
return age;
}
private int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
public int hashCode(){
System.out.println(this.name+"....hashcode");
//按照条件设置hashcode
return name.hashCode()+this.age*39;//39没有特殊意思,也可以是其他,容易导致hashcode相同,尽量保持哈希值的唯一
//不科学的比较方式 return 60;
}
public boolean equals(Object obj) {
if (!(obj instanceof Person)) {
return false;
}
Person p = (Person) obj;
System.out.println(this.name+".euqals.."+p.name);
return this.name.equals(p.name) && this.age == p.age;
}
}
复制代码
非科学打印结果为
a1....hashcode
a2....hashcode
a2.euqals..a1
a3....hashcode
a3.euqals..a2
a3.euqals..a1
a2....hashcode
a2.euqals..a3
a2.euqals..a2
a3::13
a2::12
a1::11
HashSet判断和删除的依据
注意:对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。先判断hashCode,hashcode如果有的话, 再判断equals.
import java.util.HashSet;
import java.util.Iterator;
/**
* HashSet存储自定义对象
*
* @author Administrator 网hashset存入自定义对象,姓名和年龄相同为同一个人,重复元素
*/
public class Test2 {
public static void main(String[] args) {
HashSet hs = new HashSet();
hs.add(new Person("a1", 11));
hs.add(new Person("a2", 12));
hs.add(new Person("a3", 13));
hs.add(new Person("a2", 12));
//hs.add(new Person("a4", 14));
sop(hs.contains(new Person("a1",11)));
hs.remove(new Person("a1",11));
Iterator it = hs.iterator();
while (it.hasNext()) {
Person p = (Person) it.next();
sop(p.getName()+"::"+p.getAge());
}
}
public static void sop(Object obj) {
System.out.println(obj);
}
}
class Person {
private String name;
public String getName() {
return name;
}
public int getAge() {
return age;
}
private int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
public int hashCode(){
System.out.println(this.name+"....hashcode");
//按照条件设置hashcode
return name.hashCode()+this.age*39;//39没有特殊意思,也可以是其他,容易导致hashcode相同,尽量保持哈希值的唯一
//不科学的比较方式 return 60;
}
public boolean equals(Object obj) {
if (!(obj instanceof Person)) {
return false;
}
Person p = (Person) obj;
System.out.println(this.name+".euqals.."+p.name);
return this.name.equals(p.name) && this.age == p.age;
}
}
复制代码
ArrayList判断元素是否存在,和删除元素只依赖于equals,而hashSet依赖于hashCode和equals
作者:
gzbbxu
时间:
2013-6-27 16:48
连续听了两遍总算弄明白了,,求鼓励啊
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2