1: 实现Set接口(不能有重复的元素)的hash table(哈希表),依靠HashMap来实现的。
2: 我们应该为要存放到散列表的各个对象定义hashCode()和equals()。散列表又称为哈希表,基本思想:
3: 以结点的关键字为自变量,通过一定的函数关系(散列函数)计算出对应的函数值,以这个值作为该结点存储在散列表中的地址。
4: 当散列表中的元素存放太满,就必须进行再散列,将产生一个新的散列表,所有元素存放到新的散列表中,原先的散列表将被删除。在Java语言中,通过负载因子(load factor)来决定何时对散列表进行再散列。例如:如果负载因子是0.75,当散列表中已经有75%的位置已经放满,那么将进行再散列。
5: 负载因子越高(越接近1.0),内存的使用效率越高,元素的寻找时间越长。负载因子越低(越接近0.0),元素的寻找时间越短,内存浪费越多。
6: HashSet类的缺省负载因子是0.75。
实例:
package HashSet;
import java.util.HashSet;
import java.util.Iterator;
import com.sun.org.apache.xpath.internal.axes.IteratorPool;
class HashSetTest {
public static void main(String[] args){
HashSet hs = new HashSet();
hs.add("1");
hs.add("2");
hs.add("3");//不可以添加重复的元素
hs.add("1");
//没有提供get方法,用迭代器遍历
Iterator it = hs.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
结果:
3
2
1
变型实例:
HashSet存放Student 对象
package HashSet;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import com.sun.org.apache.xpath.internal.axes.IteratorPool;
class HashSetTest {
public static void main(String[] args){
HashSet hs = new HashSet();
//增加学生对象
hs.add(new Student(1,"xiaoxi"));
hs.add(new Student(2,"xiaozhu"));
hs.add(new Student(3,"xiaohong"));
hs.add(new Student(1,"xiaoxi"));
//没有提供get方法,用迭代器遍历
Iterator it = hs.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
class Student {
int num;
String name;
Student(int num, String name) {
this.name = name;
this.num = num;
}
//格式化输出格式
public String toString() {
return "num=" + num + ", name=" + name;
}
}
结果
num=1, name=xiaoxi
num=1, name=xiaoxi
num=2, name=xiaozhu
num=3, name=xiaohong
结果解析:
打印结果顺序与添加顺序不一致并且有重复的元素,Hashset不认为这是一个重复的元素,原因Hashset存储对象根据散列码计算对象的存储位置,散列码根据HashCode函数获取的,HashCode根据对象的内存地址得到散列码,因为new对象不同,地址不同,散列码不同,存储位置不同。解决办法,重写HashCode方法。
实例:利用重写hashCode()和equals()方法解决HashCode重复元素的问题
package HashSet;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import com.sun.org.apache.xpath.internal.axes.IteratorPool;
class HashSetTest {
public static void main(String[] args){
HashSet hs = new HashSet();
//增加学生对象
hs.add(new Student(1,"xiaoxi"));
hs.add(new Student(2,"xiaozhu"));
hs.add(new Student(3,"xiaohong"));
hs.add(new Student(1,"xiaoxi"));
//没有提供get方法,用迭代器遍历
Iterator it = hs.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
class Student {
int num;
String name;
Student(int num, String name) {
this.name = name;
this.num = num;
}
public int hashCode (){
return num * name.hashCode();
//num唯一标示学生对象,如果不能唯一标识乘以学生名字的hashCode最为散列码。
}
public boolean equals (Object object){
Student s = (Student)object;
return num==(s.num) && name.equals(s.name);
//根据名字和学号判断是否是重复的元素,是同一个对象,HashSet就不会存放了
}
//格式化输出格式
public String toString() {
return "num=" + num + ", name=" + name;
}
}
结果:
num=1, name=xiaoxi
num=3, name=xiaohong
num=2, name=xiaozhu