HashSet 中存入的元素不能重复,且是无序的。
是通过对象的HashCode 和equals方法来保证对象的唯一性的。
下图演示一下HashSet的存储元素的哈希算法。
示例代码
import java.util.HashSet;
import java.util.Iterator;
public class HashSetDemo {
/**
* @param args
*/
public static void main(String[] args) {
HashSet hs = new HashSet();
hs.add("hehe");
// hs.add("heihei");
hs.add("hahah");
hs.add("xixi");
hs.add("hehe");
hs.add("xixi");
hs.add("xixi");
hs.add("xixi");
hs.add("xixi");
hs.add("xixi");
Iterator it = hs.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
控制台打印输出:
练习: 往hashSet集合中存储Person对象。如果姓名和年龄相同,视为同一个人。视为相同元素。
首先创建一个实体类,定义Person属性及获取方法。
package cn.itcast.p.bean;
public class Person /*extends Object*/ implements Comparable {
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
/*@Override
public int hashCode() {
System.out.println(this+".......hashCode");
return name.hashCode()+age*27; //将age和name设置成为hashCode。
// return 100;
}
@Override
public boolean equals(Object obj) {
if(this == obj)
return true;
if(!(obj instanceof Person))
throw new ClassCastException("类型错误");
System.out.println(this+"....equals....."+obj);
Person p = (Person)obj;
return this.name.equals(p.name) && this.age == p.age; //通过对比当前对象与下个将要比较的对象的姓名和age 是否相同来确定是否为同一个对象。
}*/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString(){
return name+":"+age;
}
@Override
public int compareTo(Object o) {
Person p = (Person)o;
int temp = this.age-p.age;
return temp==0?this.name.compareTo(p.name):temp;
// int temp = this.name.compareTo(p.name);
// return temp==0?this.age-p.age:temp;
/*
if(this.age>p.age)
return 1;
if(this.age<p.age)
return -1;
else{
return this.name.compareTo(p.name);
}
*/
}
}
创建对象并为对象属性赋值
import java.util.HashSet;
import java.util.Iterator;
import cn.itcast.p.bean.Person;
/*
* 往hashSet集合中存储Person对象。如果姓名和年龄相同,视为同一个人。视为相同元素。
*/
public class HashSetTest {
/**
* @param args
*/
public static void main(String[] args) {
HashSet hs = new HashSet();
/*
* HashSet集合数据结构是哈希表,所以存储元素的时候,
* 使用的元素的hashCode方法来确定位置,如果位置相同,在通过元素的equals来确定是否相同。
*
*/
hs.add(new Person("lisi4",24));
hs.add(new Person("lisi7",27));
hs.add(new Person("lisi1",21));
hs.add(new Person("lisi9",29));
hs.add(new Person("lisi7",27));
Iterator it = hs.iterator();
while(it.hasNext()){
Person p = (Person)it.next();
System.out.println(p);
// System.out.println(p.getName()+"...."+p.getAge());
}
}
}
控制台输出。
既然是不可重复的,元素为什么会出现重复呢?
仔细查看API和源码发现HashSet没有特有的HashCode和equals方法,是继承的Object类中的HashCode和equals方法。
我们代码中用来区分人与人不同的元素是人民name 和年龄age 。那么就得覆盖重写Object类中的HashCode 和.equals()方法。
@Override
public int hashCode() {
System.out.println(this+".......hashCode");
return name.hashCode()+age*27; //将age和name设置成为hashCode。
// return 100;
}
@Override
public boolean equals(Object obj) {
if(this == obj)
return true;
if(!(obj instanceof Person))
throw new ClassCastException("类型错误");
System.out.println(this+"....equals....."+obj);
Person p = (Person)obj;
return this.name.equals(p.name) && this.age == p.age; //通过对比当前对象与下个将要比较的对象的姓名和age 是否相同来确定是否为同一个对象。
}
重写方法以后就没有重复的元素了。