Set接口中的方法和Collection一致。
HashSet内部数据结构是哈希表,是不同步的,集合中的元素是唯一的。
示例:
public class HashSetDemo {
public static void main(String[] args) {
HashSet hs = new HashSet();
hs.add("hehe");
hs.add("heihei");
hs.add("haha");
hs.add("xixi");
//hs.add("hehe");//如果有两个hehe,则最后只打印一个,因为不许重复
Iterator it = hs.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
此程序的输出结果是无序的。
16-6,哈希表
1,哈希表是哈希算法,是内核的一种存储数据的算法,查找起来非常快,其底层为数组结构,哈希算法可以根据数据的属性来算出相应的在数组中的位置,直接将数据存储进去,取得时候不用遍历,将这个数据调用hashCode方法,算出位置,去相应的位置有没有该元素,就不用找其他位置的元素是否匹配了。
2,哈希表确定元素是否相同的步骤:
(1)判断的是两个元素的哈希值是否相同,如果相同,再判断两个对象的内容是否相同。
(2)判断哈希值相同,其实判断的是对象的hashCode方法,判断内容相同,用的是equals方法。
注意:如果哈希值不同,是不需要判断equals的。
16-7,HashSet存储自定义对象
1,如何保证HashSet的元素的唯一性呢?
是通过对象的hashCode方法和equals方法来完成确定对象的唯一性的。
如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。
如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true,如果为true,视为相同元素,就进行存储。
记住:如果元素要存储到HashSet集合中,必须覆盖hashCode方法和equals方法。
一般情况下,如果定义的类会产生很多对象,比如:人,学生,书,通常都需要覆盖equals,hashCode方法。
这是判断对象是否相同的依据。
2,存储自定义对象实例:
public class Person {
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
//重写hashCode和equals方法
@Override
public int hashCode() {
return name.hashCode() + age * 27;
}
@Override
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(!(obj instanceof Person)) {
throw new ClassCastException("类型错误");
}
Person p = (Person)obj;
return this.name.equals(p.name) && this.age == p.age;
}
}
存储自定义对象类:
//往HashSet集合中存储Person对象,如果姓名和年龄相同,视为同一个人,相同元素。
public class HashSetTest {
public static void main(String[] args) {
HashSet hs = new HashSet();
/*
HashSet结合数据结构是哈希表,所以存储元素的时候,
使用元素的hashCode方法来确定位置,如果位置相同,
再通过元素的equals方法来确定是否相同。
*/
hs.add(new Person("lisi4",24));
hs.add(new Person("lisi7",27));
hs.add(new Person("lisi1",21));
hs.add(new Person("lisi9",29));
hs.add(new Person("lisi7",27));//若不重写hashCode和equals方法,这里也会输出lisi7,27,不保证唯一性
Iterator it = hs.iterator();
while(it.hasNext()) {
Person p = (Person)it.next();
System.out.println(p.getName()+"..."+p.getAge());
}
}
}
16-8,集合框架-练习
需求:取出ArrayList中的重复元素。
public class ArrayListTest{
public static void main(String[] args) {
ArrayList al = new ArrayList();
al.add("abc1");
al.add("abc2");
al.add("abc2");
al.add("abc1");
al.add("abc");
System.out.println(al);
al = getSingleElement(al);
System.out.println(al);
}
public static ArrayList getSingleElement(ArrayList al) {
//定义一个临时容器
ArrayList temp = new ArrayList();
//迭代al集合
Iterator it = al.iterator();
while(it.hasNext()) {
Object obj = it.next();
//判断被迭代到的元素是否在临时容器中存在。
if(!temp.contains(obj)) {
temp.add(obj);
}
}
return temp;
}
}
结果:abc1,abc2,abc2,abc1,abc
abc1,abc2,abc
16-9,LinkedHashSet集合
特点:具有可迭代顺序的Set接口的哈希表,和链接列表实现。
说白了,此集合可以保证对象唯一且有序。而HashSet是无