<pre name="code" class="java">package cn.itcast_03;
import java.util.HashSet;
import java.util.Set;
/*
* Set集合的特点就是:唯一性,无序性
*更改类名或者文件名称快捷键:alt+shift+r
*/
public class SetDemo {
public static void main(String[] args) {
// 创建set
Set<String> set = new HashSet<String>();
//添加元素到集合中
set.add("hello");
set.add("world");
set.add("java");
set.add("hello");
set.add("java");
set.add("hello");
for (String str : set) {
System.out.println(str);
}
}
}
需求:存储自定义对象,并去掉重复值。
* 同一个对象的成员值都相同,我们则认为这是同一个对象。
*
* A:第一步按照正常做法,我们发现并没有去掉重复值。所以,我们要重写equals()方法。
* B:第二步,我们重写equals()方法。还是没有解决问题,这个时候,我们就应该去思考程序哪里出问题了
* C:分析哪里出问题呢?
* 这个时候我们找到问题原因:add方法里面有问题。
* 所以看add方法的源码。
* D:通过查看源码,我们找到了最终的判断条件:
* e.hash == hash && ((k = e.key) == key || key.equals(k))
* 注意:hash是和hashCode()方法相关的。
*
* 这个判断有两个条件:
* 第一个条件:e.hash == hash 依赖hashCode()方法进行比较。
* 第二个条件:((k = e.key) == key || key.equals(k))
*
* HashSet集合是怎么保证元素的唯一性的?
* HashSet集合底层数据结构是哈希表。
* 哈希表底层依赖于两个方法:hashCode()和equals()方法。
* 先执行hashCode()值的比较:
* 相同:
* 继续走equals()方法去比较成员的值。
* 返回true:对象的成员值相同,那么就是同一个对象。不存储到集合中。
* 返回false:对象的成员值不同相同,那么就添加到集合中。
* 不同:直接添加到集合中。
*
* 以后如果涉及到Hash这种数据结构,你要明白可能需要重写两个方法hashCode()和equals()。
* A:重写hashCode()是为了保证能走equals(),优化它,是为了提高效率。
* B:重写equals()是为了比较成员的内容。
* 如果你真不知道这两个方法该怎么重写:请自动生成即可。
import java.util.HashSet;
import java.util.Iterator;
import cn.itcast_01.Student;
/*
* HashSet存储字符串案例
*/
public class HashSetDemo {
public static void main(String[] args) {
// 创建集合对象
HashSet<String> hs = new HashSet<String>();
// 创建并添加元素
hs.add("hello");
hs.add("world");
hs.add("java");
hs.add("java");
//遍历
System.out.println("---迭代器遍历----------");
Iterator<String> it = hs.iterator();
while (it.hasNext()) {
String s = it.next();
System.out.println(s);
}
System.out.println("---增强for----------");
for (String str : hs) {
System.out.println(str);
}
System.out.println("-------------");
HashSet<Student> hashSet = new HashSet<>();
// 创建元素对象
Student s1 = new Student("貂蝉", 18);
Student s2 = new Student("大乔", 27);
Student s3 = new Student("小乔", 20);
Student s4 = new Student("蔡文姬", 22);
Student s5 = new Student("大乔", 27);
Student s6 = new Student("大乔", 17);
Student s7 = new Student("蔡文姬", 22);
hashSet.add(s1);
hashSet.add(s2);
hashSet.add(s3);
hashSet.add(s4);
hashSet.add(s5);
hashSet.add(s6);
hashSet.add(s7);
Iterator< Student>iterator = hashSet.iterator();
/** 此处的打印说明 HashSet具有set的<span style="color: rgb(79, 118, 203); font-family: Monaco; font-size: 11px;">唯一性无序性特点</span> */
while (iterator.hasNext()) {
Student student = iterator.next();
System.out.println(student.toString());
}
}
}
<pre name="code" class="java">package cn.itcast_01;
public class Student {
private String name;
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
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;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
// System.out.println("-----------");
// 此处的打印说明HashSet 经过hashCode进行 比较
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
打印结果:
---迭代器遍历----------
world
java
hello
---增强for----------
world
java
hello
-------------
Student [name=蔡文姬, age=22]
Student [name=大乔, age=17]
Student [name=貂蝉, age=18]
Student [name=大乔, age=27]
Student [name=小乔, age=20]