前言
HashSet 是 Set 接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的。这个必须要明白。重点、重点、重点。。。存储元素的两个特点:唯一、无序。
一、HashSet 集合的存储
1.案例描述
练习目标
了解 HashSet 集合的存储特点
需求分析
为了让初学者熟悉 HashSet 集合的用法,本案例将针对 HashSet 集合中元素不可重复的特点,对 HashSet 集合的存储和遍历过程进行演示。
设计思路(实现原理)
1) 编写一个类 Example09,在该类中定义一个 HashSet 集合 hs
2) 向集合 hs 中添加 6 个元素,其中有一些重复的元素
3) 用 size()方法获取添加完元素后集合中元素的个数
4) 用 Iterator 迭代器遍历集合的每一个元素
5) 观察在输出结果中,是否存在重复的元素
2.案例实现
Example09类代码:
package JHClass;
import java.util.*;
public class Example09 {
public static void main(String[] args) {
// 创建HashSet集合
HashSet hs = new HashSet();
//向HashSet集合中添加元素,其中包括重复元素
hs.add("abc2");
hs.add("abc2");
hs.add("abc1");
hs.add("abc4");
hs.add("abc4");
hs.add("abc3");
// 输出集合中元素的个数
System.out.println("添加后集合中元素个数:"+hs.size());
// 输出集合中每一个元素
Iterator it = hs.iterator();
System.out.println("添加后集合中包含以下元素:");
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
运行结果:
因为前言说过HashSet 集合存储的元素是不可重复的,并且元素都是无序的。所以输出结果如下:
注意:HashSet 集合在添加元素时,会判断要添加的元素现在集合中有没有,有的话就不会添加进去。集合中没有要添加的元素才会添加到HashSet 集合。所以我们添加了6个元素,而添加后集合中只有4个不同的元素。
3.案例总结
1、HashSet 是 Set 接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的。当向 HashSet 集合中添加一个对象时,首先会调用该对象的 hashCode()方法来确定元素的存储位置,然后再调 用对象的 equals()方法来确保该位置没有重复元素。
2、在本案例中,首先通过 add()方法向 HashSet 集合依次添加了六个字符串,然后通过 Iterator 迭代器 遍历所有的元素并输出打印。从打印结果可以看出取出元素的顺序与添加元素的顺序并不一致,并且重复 存入的字符串对象"abc2"和"abc4"被去除了,只添加了一次。
二、将Object类存入HashSet
1.案例描述
练习目标
掌握如何将对象存入 HashSet 集合并且去除重复对象
需求分析
HashSet 集合之所以能确保不出现重复的元素,是因为它在添加对象时,会先调用该对象的 hashCode()方法来确定元素的存储位置,再调用对象的 equals()方法来确保该位置没有重复元素。 为了将 Object 类存入 HashSet 集合,本案例将针对如何重写 Object 类中的hashCode()和 equals() 方法去除重复的 Object 对象进行演示。
设计思路(实现原理)
1) 设计一个 Person 类,在该类中定义两个变量 name 和 age
2) 在 Person 类中重写 hashCode()和 equals()方法
3) 编写类 Example10,在该类中定义一个 HashSet 集合
4) 将 Person 对象存入 HashSet 集合中,其中含有重复的 Person 对象
5) 遍历 HashSet 集合中的元素,观察结果是否含有重复的对象
2.案例实现
设计 Person 类,其代码如下:
package JHClass;
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 重写hashCode方法,返回name属性的哈希值
public int hashCode() {
return name.hashCode() + age * 2;
}
// 重写equals方法
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj instanceof Person) {
Person p = (Person) obj;
return this.name.equals(p.name) && this.age == p.age;
}
return false;
}
// 重写toString()方法
public String toString() {
return "Person " + name +" "+ age;
}
}
注意:equals方法选的是HashSet 集合中该位置没有对象,或者有对象但名字和年龄与要存的对象不同,才会返回false,把该对象添加到集合中。如果该哈希值位置有对象,并且和要存入对象的名字和年龄都相同,则会舍弃该对象,就不会存储到HashSet 集合中。
Example10类代码:
package JHClass;
import java.util.*;
public class Example10 {
public static void main(String[] args) {
// 创建HashSet对象
HashSet hs = new HashSet();
// 将Person对象存入集合
hs.add(new Person("lisa", 21));
hs.add(new Person("lisi", 32));
hs.add(new Person("lisi", 32));
hs.add(new Person("leilei", 31));
hs.add(new Person("lusi", 25));
hs.add(new Person("lusi", 25));
// 遍历集合中的元素
Iterator it = hs.iterator();
while (it.hasNext()) {
Person p = (Person) it.next();
System.out.println(p);
}
}
}
运行结果
3.案例总结
在本案例中,当 HashSet 集合的存入元素时,首先调用当前存入对象的 hashCode()方法获得 name 属性 的哈希值,然后根据对象的哈希值计算出一个存储位置。如果该位置上没有元素,则直接将元素存入,如 果该位置上有元素存在,则会调用 equals()方法让当前存入的元素依次和该位置上的元素进行比较,如果 返回的结果为 false 就将该元素存入集合,返回的结果为 true 则说明有重复元素,就将该元素舍弃。
执行过程图
总结
HashSet 集合主要还是要掌握前言说的HashSet 集合中存储的元素不可重复,无序这两个特点。将Object类存入HashSet计较难理解一些。