/**
* @author StormWangxhu
* @version 创建时间:2017年11月4日 下午4:03:26
*
*/
Set集合
先来看看集合框架图:
- 与List接口相同点:
同样继承自Collection接口,它与Collection接口中的方法基本一致,并没有对Collection接口进行功能上的增强,但比Collection接口更加严格! - 不同点
Set接口中的元素 无序、不重复! 至于以什么样的方式保证不重复,其原因后面会说到。
先来结合代码看看HashSet集合中添加重复元素会发生什么:
package com.stormwang.SetTest;
import java.util.HashSet;
import java.util.Iterator;
/**
* @author StormWangxhu
* @version 创建时间:2017年11月4日 下午4:03:26
*
*/
public class HashSetDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
HashSet set= new HashSet();
//向集合中添加元素
set.add("java");
set.add("Friday");
set.add("java");
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
Object object = (Object) iterator.next();
System.out.println(object);
}
}
}
再来看看结果:
在代码中,重复了字符串Java,但是运行后,只保留下了一个。
且可以看出,取出顺序和加入顺序也不一致。
原因:
不重复是因为做了很多工作:当向Set集合中添加对象时,add().
步骤:
1、首先调用当前存入对象的hashCode()方法,获得该对象哈希值。
2、根据哈希值确定其存储位置。
3、判断该位置上是否有对象
(1)、无对象,则存入集合。
(2)、有对象 ———->>>调用equal()方法,比较对象是否相等。
(3)、
相等——->>>舍弃该对象
不相等——存入该集合。
下面根据图来理解一下:
则要想HashSet正常工作,就必须重写hashCode()方法、equals()方法。
下面以没有重写两个方法演示一下后果:
package com.stormwang.SetTest;
/**
* @author StormWangxhu
* @version 创建时间:2017年11月4日 下午4:35:50
*
*/
import java.util.HashSet;
import java.util.Iterator;
/**
* 不复写hashCode()方法、equals()方法
* */
public class HashDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建集合
HashSet set =new HashSet<>();
//创建Student对象
Student student = new Student("1", "Jack");
Student student2 = new Student("2", "mary");
Student student3 = new Student("3", "Rose");
Student student4 = new Student("3", "Rose");
set.add(student);
set.add(student2);
set.add(student3);
set.add(student4);
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
Object object = (Object) iterator.next();
System.out.println(object);
}
}
}
class Student{
private String id ;
private String name ;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//构造方法
public Student(String id,String name ) {
this.id = id;
this.name = name ;
}
//
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + "]";
}
}
看一下运行后效果:
看到: 出现了相同的值: [ id=3,name=Rose].
原因分析
是因为在类没有重写hashCode()方法,和equals()方法。这样的重复在HashSet集合中理应是不存在的。那么就重写这两个方法试试。
假设id相同的学生是一同一个学生。
看代码:
package com.stormwang.SetTest;
/**
* @author StormWangxhu
* @version 创建时间:2017年11月4日 下午4:35:50
*
*/
import java.util.HashSet;
import java.util.Iterator;
/**
* 不复写hashCode()方法、equals()方法
* */
public class HashDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建集合
HashSet set =new HashSet<>();
//创建Student对象
Student student = new Student("1", "Jack");
Student student2 = new Student("2", "mary");
Student student3 = new Student("3", "Rose");
Student student4 = new Student("3", "Rose");
set.add(student);
set.add(student2);
set.add(student3);
set.add(student4);
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
Object object = (Object) iterator.next();
System.out.println(object);
}
}
}
class Student{
private String id ;
private String name ;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//构造方法
public Student(String id,String name ) {
this.id = id;
this.name = name ;
}
//
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.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 (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
再来看看运行结果:
重复的没有了,保证了元素的不重复性。也会看到元素的无序性。
再看看HashSet的API
构造函数:
方法:
HashSet的一些常用方法
添加元素
hashset.add(E e):返回boolean型,如果此 set 中尚未包含指定元素,则添加指定元素;如果此 set 已包含该元素,则该调用不更改 set 并返回 false。
删除元素:
hashset.clear():从此 set 中移除所有元素。
hashset.remove(Object o):如果指定元素存在于此 set 中,则将其移除。
hashset.isEmpty():如果此 set 不包含任何元素,则返回 true。
hashset.contains(Object o):如果此 set 包含指定元素,则返回 true。
hashset.size():返回此 set 中的元素的数量(set 的容量)。
总结:
要想HashSet正常工作,必须重写hashCode()方法和equals()方法。
重写技巧:
右击——–>>source———->>Generate hashCode() and equals()….
就看到这儿吧,晚上再来一个实例练习HashSet()。