-
java.util.Set
接口和java.util.List
接口一样,同样继承自Collecion
接口,它与Collection
接口中的方法基本一致,并没有对Collection
接口进行功能上的扩充,只是比Collection
接口更加严格了,与List
接口不同的是,set
接口中的元素无序,并且都会以某种规则保证存入的元素不会出现重复。 -
Set
集合有多个子类,其中最常见的有:java.util.HashSet
和java.util.LinkedHashSet
这两个集合。 -
Set
集合取出元素的方法可以采用:迭代器和增强for。
1 HashSet集合介绍
-
java.util.HashSet
是Set
接口的一个实现类,它所存储的元素是不可重复的,并且所有元素都是无序的(即存储顺序不一致),java.util.HashSet
底层的实现是一个java.util.HashMap
支持。 -
HashSet
是根据对象的哈希值来确定元素在对象中的存储位置,因此具有良好的存取和查找性能(查询速度非常快),保证元素唯一性的方法依赖于:hashCode
和equals
方法。 -
set
接口的两大特点:不允许存储重复的元素;没有索引,没有带索引的方法,也不能使用普通的for循环遍历。
一个简单的set测试如下:
package com.zrz.set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class SetDemo01 {
public static void main(String[] args) {
Set<Integer> set = new HashSet<>();
//使用add的方法往集合中添加元素
set.add(1);
set.add(3);
set.add(2);
set.add(1);
//使用迭代器遍历set集合
Iterator<Integer> it = set.iterator();
while (it.hasNext()){
Integer n = it.next();
System.out.println(n);//1,2,3
}
System.out.println("______________________________________");
//使用增强for循环
for (Integer integer : set) {
System.out.println(integer);//1,2,3
}
}
}
HashSet集合存储数据的结构(哈希表)
- 什么是哈希表?
- 在JDK1.8之前,哈希表底层采用数组+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里,但是当hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8之后,哈希表存储采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。
- 哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址,是一个逻辑地址,是模拟出来得到的地址,不是数据实际存储的物理地址)
-
int hashCode()
返回该对象的哈希码值。
具体实现代码如下:
package com.zrz.HashCode;
public class HashCodeDemo {
public static void main(String[] args) {
//Person类继承了Object类,所以可以使用Object类中的hashCode方法。
Person p1 = new Person();
System.out.println(p1);//3f99bd52 下面哈希值的十六进制值
System.out.println(p1.hashCode());//1067040082
System.out.println(new Person().hashCode());//1325547227
//string类的哈希值:string重写Object中的hashCode方法
String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1.hashCode());//96354
System.out.println(s2.hashCode());//96354
System.out.println("重地".hashCode());//1179395
System.out.println("通话".hashCode());//1179395
}
}