HashSet集合在java.util包下。HashSet集合也有泛型,即集合里面存储数据的类型
HashSet集合是一个具体的类,继承了AbstractSet
HashSet集合实现类三个接口,分别是Set
HashSet类实现类Set接口,由哈希表(实际为HashMap实例)支持。对集合的迭代顺序不做任何保证。HashSet类允许null元素
HashSet接口的底层数据结构是哈希表HashMap
总结: 1、该集合的底层数据结构是哈希表HashMap 2、HashSet集合对集合的迭代顺序不作任何保证,即不保证存储和取出的元素顺序一致 3、没有带索引的方法,所以不能使用普通for循环进行遍历 4、由于是Set集合,所以是不包含重复元素的集合 5、该集合是不包含重复元素的集合
HashSet集合概述和特点的练习
xxxxxxxxxx
package ch15;
import java.util.HashSet;
public class a_3_1测试 {
public static void main(String[] args) {
//创建HashSet集合的对象
HashSet<String> hs = new HashSet<String>();
//添加元素
hs.add("hello");
hs.add("world");
hs.add("java");
hs.add("java");
//遍历.有两种遍历方式,分别是迭代器、增强for循环。这里使用增强for循环来实现遍历
for(String s : hs){
//注意输出顺序和存储顺序是不一致的,因为HashSet类对迭代顺序不作任何保证
//注意也不会输出重复元素
System.out.println(s);
}
}
}
HashSet集合保证元素唯一性的分析
x
package ch15;
import java.util.HashSet;
//这里不需要运行哦,运行不是重点,在'a_21_1'分析源码才是
public class a_4_0HashSet集合保证元素唯一性的源码分析 {
public static void main(String[] args) {
//创建HashSet集合的对象
HashSet<String> hs = new HashSet<String>();
//上面那行的选中HashSet,按Ctrl+B查看源码,进去找到add方法,选中那个add里面的put,继续查源码,再选中put里面的hash,继续查源码
//添加元素
hs.add("hello");
hs.add("world");
hs.add("world");
hs.add("java");
//遍历
for(String s : hs){
System.out.println(s);
}
//------------------------------------------------------------------------------------------------------------
/*
HashSet集合添加一个元素的过程,如下,注意前面标的数字顺序表示步骤:
1、调用对象的hashCode方法获取对象的哈希值
2、根据对象的哈希值计算对象的存储位置
3、该位置是否有元素存在
3.1、没有 --> 将元素存储到该位置 --> 返回false --> 调用equals方法,比较对象内容是否相等
3.2、有 --> 遍历该位置的所有元素,和新存入的元素比较哈希值是否相同 --> 有相同的 --> 调用equals方法,比较对象内容是否相等
4、返回true->说明元素重复,不存储
*/
//解释在‘a_19_2测试’中的"重地"和"通话"两个字符串的哈希值会存在相同,为什么重复的哈希值会被存储:
//因为:虽然哈希值相同,但是在equals()方法这里不同,所以最后还是判定为不重复
//总结
//HashSet集合存储元素:
//1、要保证元素唯一性,需要重写hashCode()和equals()
}
}
HashSet集合存储学生对象并遍历
需求:创建一个学生对象的集合,存储多个学生对象,使用程序实现在控制台遍历该集合 要求:学生对象的成员变量值相同,我们就认为是同一个对象
思路: 1、定义学生类 2、创建HashSet集合对象 3、创建学生对象 4、把学生添加到集合 5、遍历集合,使用增强for的遍历方式 6、在学生类里面重写hashCode和equals方法
注意:如果不在学生类里面重写hashCode和equals方法,则会导致同一个元素也会被存储进集合,即违背HashCode集合元素的唯一性
HashSet集合存储学生对象并遍历的练习
xxxxxxxxxx
package ch15;
public class a_6_1Student {
//成员变量
private String name;
private int age;
//无参构造方法
public a_6_1Student() {
}
//带参构造方法
public a_6_1Student(String name, int age) {
this.name = name;
this.age = age;
}
//成员变量对应的get、set方法
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和equals方法。可直接快捷键Alt+insert,选equals() and hashCode(),一直选Next
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
a_6_1Student that = (a_6_1Student) o;
if (age != that.age) return false;
return name != null ? name.equals(that.name) : that.name == null;
}
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
}
xxxxxxxxxx
package ch15;
import java.util.HashSet;
public class a_6_2测试 {
public static void main(String[] args) {
//创建HashSet集合对象
HashSet<a_6_1Student> hs = new HashSet<a_6_1Student>();
//创建学生对象
a_6_1Student s1 = new a_6_1Student("张三", 18);
a_6_1Student s2 = new a_6_1Student("李四", 19);
a_6_1Student s3 = new a_6_1Student("王五", 20);
a_6_1Student s4 = new a_6_1Student("王五", 20);
//注意:上面同一个对象也会存储进集合,即集合元素不唯一,如何使元素唯一呢
//解决方法:在学生类里面重写hashCode和equals方法。可直接快捷键Alt+insert,选equals() and hashCode(),一直选Next
//重写之后就能保证集合元素的唯一性了,即同一个对象不会被存储进集合
//把学生添加到集合
hs.add(s1);
hs.add(s2);
hs.add(s3);
hs.add(s4);
//遍历集合,使用增强for的遍历方式
for (a_6_1Student s : hs) {
System.out.println(s.getName() + "," + s.getAge());
}
}
}