集合之浅谈HashSet
程序员文章站
2022-05-23 14:18:30
...
HashSet的底层存储结构
此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。
hashSet的继承结构
hashSet的底层结构实现图
HashSet的特性
- hashSet是唯一的(不重复)此实现是通过重写对象的hashCode与equals方法
1.先计算hash
int hash = hash(key);
2.根据hash值去散列桶中找链表对应得index
int i = indexFor(hash, table.length);
3.根据index去遍历链表看是否有相应的对象
for (Entry<K,V> e = table[i]; e != null; e = e.next)
4.如果存在对象就判断old 的hash值与new 的hash是否相等
if(e.hash == hash) {
if(((k = e.key) == key || key.equals(k)))
不做处理
else
添加
}else{
不添加
}
- 无序的(存入的顺序与取出的顺序不能保证一致)
- 线程不安全的(此实现不是同步的)
HasHSet存储自定义的对象示例
定义Student对象:
/**
* @Description 学生model 根据姓名与年龄来判断是否为同一个学生
* @Author xiaoqx <aaa@qq.com>
* @Version V1.0.0
* @Since 2017/9/25
*/
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.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;
}
/**
* 重写hashCode 方法
* 之所以要乘30
* 是否防止 age=32 name.hashCode=28 60
* age=28 name.hashCode=32 60
* @return
*/
public int hashCode(){
return this.name.hashCode()+this.age*30;
}
public boolean equals(Object obj){
Student s1 = (Student) obj;
boolean isSame = (this.name.hashCode()+this.age*30)-(s1.name.hashCode()+s1.age*30)==0?true:false;
if(isSame){
if(this.name.equals(s1.name))
return true;
else
return false;
}
return false;
}
@Override
public String toString() {
return this.name+":"+age;
}
}
测试HashSet的存储:
/**
* @Description 查看HashSet add方法的底层原理。
* HashSet中元素是唯一的,hashSet的底层结构是Hash表,hash表是存储 链表的动态数组组成。
* 1.hashSet.add()先是通过对象的hashCode来判断是否相同,如果相同在通过equals方法来判断
* HashSet是无序的(存入的顺序与取出的顺序可能不同)
*
* @Author xiaoqx <aaa@qq.com>
* @Version V1.0.0
* @Since 2017/9/25
*/
public class HashSetAdd {
public static void main(String[]args){
HashSet hashSet = new HashSet();
Student s1 = new Student("zhangsan",20);
Student s2 = new Student("wangwu",21);
Student s3 = new Student("lisi",20);
Student s4 = new Student("zhangsan",24);
Student s5 = new Student("zhangsan",20);
hashSet.add(s1);
hashSet.add(s2);
hashSet.add(s3);
hashSet.add(s4);
hashSet.add(s5);
Iterator it = hashSet.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
输出结果:
wangwu:21
zhangsan:24
lisi:20
zhangsan:20
上一篇: Java中的泛型类,泛型方法,泛型接口