一、Set概述
java.util.Set
接口和java.util.List
接口一样,同样继承Collection接口,它与Collection接口中的方法基本一致,并没有对Collection接口进行功能上的扩充,只是比Collection接口更加严格,与List接口不同的是,Set接口中元素无序,并且都会以某种规则保证存入的元素不出现重复。
Set集合有多个子类,比如:
java.util.HashSet
、java.util.LinkedHashSet
Set特性:
- 无序
- 存取没有顺序
- 无下标
- 没有下标,所以没有带下标的方法,并且也不能使用普通for循环遍历
- 不可以重复
- 添加的元素不可以重复
二、HashSet
java.util.HashSet
是Set接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的(存取顺序不一致),java.util.HashSet
底层的实现其实是一个java.util.HashMap
支持。
HashSet是根据对象的
哈希值
来确定元素在集合中的存储位置,因此具有良好的存取和查找性能,保证元素唯一性的方式依赖于:hashCode
和equals
方法
1、HashSet集合特点
- 底层数据结构是哈希表
- 存取无序
- 不可以存储重复元素
- 没有下标,所以没有带下标的方法,并且也不能使用普通for循环遍历
2、入门程序
HashSet集合存储数据
package cn.com.example11;
import java.util.HashSet;
public class HashSetClass {
public static void main(String[] args) {
HashSet<String> hashSet = new HashSet<>();
hashSet.add("admin");
hashSet.add("user");
hashSet.add("guest");
hashSet.add("root");
System.out.println(hashSet);
}
}
3、哈希值
3.1、哈希值概述
哈希值:是JDK根据对象的地址或者字符串或者数字计算出来的int类型的数据
3.2、如何获取哈希值
Object 类中的public int hashCode():返回对象的哈希码值
3.3、哈希值的特点
- 同一个对象多次调用hashCode方法返回的哈希码值是相同的
- 默认情况下,不同对象的哈希码值是不同的,而重写了hashCode方法,可以实现让不同对象的哈希码值相同
3.4、哈希表结构
a、JDK1.8以前
底层数据结构:数组 + 链表
- 创建一个默认长度为16的数组
- 根据元素的哈希码值与数组的长度进行运算得出存储位置
- 判断当前位置是否为null,如果为null直接存储
- 如果不为null,说明有数据,通过equals比较属性值
- 如果一样,放弃存储,如果不一样,存入数据
新元素在老元素上面
b、JDK1.8以后
节点个数小于等于8个:
数组 + 链表
节点个数大于8个:
数组 + 红黑树
4、HashSet常用方法
和Collection一致
5、HashSet遍历方式
和Collection一致
三、TreeSet
1、TreeSet特点
- 不可以存储重复元素
- 没有索引
- 可以将元素按照规则进行排序
- TreeSet():根据其元素的自然排序进行排序
- TreeSet(Comparator comparator):根据指定的比较器进行排序
- 底层数据结构是二叉树,并且底层使用了TreeMap
2、入门程序
package cn.com.example11;
import java.util.TreeSet;
public class TreeSetClass {
public static void main(String[] args) {
TreeSet<String> treeSet = new TreeSet<>();
treeSet.add("admin");
treeSet.add("user");
treeSet.add("guest");
treeSet.add("root");
for (String s : treeSet) {
System.out.println(s);
}
}
}
四、LinkedHashSet
我们知道HashSet保证元素唯一,可是元素存放进去是没有顺序的,那么我们要保证有序,可以使用HashSet的一个子类
java.util.LinkedHashSet
,它是链表和哈希表组合的一个数据存储结构。
LinkedHashSet:元素唯一、有序
LinkedHashSet特点:底层是一个哈希表(数组+链表/红黑树) + 链表:多出的链表用于记录元素的存储顺序,保证元素有序
package cn.com.example11;
import java.util.LinkedHashSet;
public class LinkedHashSetClass {
public static void main(String[] args) {
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add("admin");
linkedHashSet.add("user");
linkedHashSet.add("guest");
linkedHashSet.add("root");
linkedHashSet.add("admin");
System.out.println(linkedHashSet);
}
}