set为单列结合,继承于collection,无序,不可重复,无索引,有以下API:
2.1HashSet
无序,不重复,无索引。
public class HashSetDemo {
public static void main(String[] args) {
//1.定义一个集合
Set<String> set=new HashSet<>();
//2.添加元素
System.out.println(set.add("张三")); //true
System.out.println(set.add("张三")); //false 说明set集合不可重复
System.out.println(set.add("李四")); //true
System.out.println(set.add("王五")); //true
System.out.println(set.add("赵六")); //true
System.out.println(set); //[李四, 张三, 王五, 赵六] 说明set集合无序
//3.删除元素
System.out.println(set.remove("张三")); //true
System.out.println(set);
//4.是否包含该元素
System.out.println(set.contains("李四")); //true
//5.清空元素
set.clear();
//6.获取长度
System.out.println(set.size()); //已经清空,所以长度为0
}
}
2.2HashSet的三大循环
public class HashSetLoop {
public static void main(String[] args) {
//1.定义一个集合
Set<String> set=new HashSet<>();
//2.添加元素
set.add("张三");
set.add("李四");
set.add("王五");
set.add("赵六");
//3.增强for循环遍历
System.out.println("--------1.---------");
for (String s : set) {
System.out.print(s+" ");
}
//4.迭代器循环
System.out.println();
System.out.println("--------2.---------");
Iterator<String> iterator= set.iterator();
while (iterator.hasNext()){
String s = iterator.next();
System.out.print(s+" ");
}
//5.lambda循环
System.out.println();
System.out.println("--------3.---------");
set.forEach(s -> System.out.print(s+ " "));
}
}
2.3HashSet的底层原理
采用哈希表存储数据,是一种增删改查性能都比较好的结构。
JDK1.8之前:数组+链表
JDK1.8开始:数组+链表+红黑树
哈希值:对象的整数表现形式。
JDK1.8之前:①创建一个默认长度为16的,加载因子为0.75的数组table
②根据元素的哈希值跟数组的长度计算出存入的位置(int index=(数组长度-1)&哈希值)
③判断元素是否为null,直接存入。
④如果不为null,表示存在元素,则调用equal方法比较属性值
⑤如果一样,则不存入;存入数组,形成链表
JDK1.8之前:新元素存入数组,老元素挂在新元素下面
JDK1.8开始:新元素直接挂在老元素下面,当链表长度大于8且数组长度大于等于64时,链表会转化为红黑树。
1.HashSet为什么存和取得顺序不一样?
当从HashSet中获取元素时,Java会先根据元素的哈希值找到对应的桶位置,然后遍历该桶中的链表,查找是否包含要获取的元素。由于哈希表是无序的,因此链表中的元素顺序可能是随机的。
2.HashSet为什么没有索引
在HashSet中,元素的存储顺序是不固定的,因此无法通过索引来快速查找元素。
一个链表有多个值,即一个索可能有多个值。
2.4LinkedHashSet
特点:有序,无重复,无索引
底层多了一个双向链表来存储数据。
public class LinkedHashSetDemo {
public static void main(String[] args) {
//1.定义一个结合
LinkedHashSet<String> linkedHashSet=new LinkedHashSet<>();
//2.添加值
linkedHashSet.add("张三");
linkedHashSet.add("李四");
linkedHashSet.add("王五");
linkedHashSet.add("张三");
//3.删除元素
linkedHashSet.remove("张三");
//4.返回长度
System.out.println(linkedHashSet.size());
//5.判断元素是否存在
linkedHashSet.contains("李四");
//6.清空元素
linkedHashSet.clear();
System.out.println(linkedHashSet); //[张三, 李四, 王五] 有序且不重复
}
}
2.5LinkedHashSet的三大循环
public class LinkedHashSetLoop {
public static void main(String[] args) {
//1.定义一个结合
LinkedHashSet<String> linkedHashSet=new LinkedHashSet<>();
//2.添加值
linkedHashSet.add("张三");
linkedHashSet.add("李四");
linkedHashSet.add("王五");
//3.增强for循环遍历
System.out.println("--------1.---------");
for (String s : linkedHashSet) {
System.out.print(s+" ");
}
//4.迭代器循环
System.out.println();
System.out.println("--------2.---------");
Iterator<String> iterator= linkedHashSet.iterator();
while (iterator.hasNext()){
String s = iterator.next();
System.out.print(s+" ");
}
//5.lambda循环
System.out.println();
System.out.println("--------3.---------");
linkedHashSet.forEach(s -> System.out.print(s+ " "));
}
}
2.6TreeSet
特点:不重复,无索引,可排序
底层:基于红黑树的数据结构,增删改查的性能都比较好。
public class TreeSetDemo {
public static void main(String[] args) {
//1.定义一个集合
TreeSet<Integer> treeSet=new TreeSet<>();
//2.添加元素
treeSet.add(2);
treeSet.add(2);
treeSet.add(3);
treeSet.add(1);
treeSet.add(5);
//3.删除元素
treeSet.remove(2);
//4.返回长度
System.out.println(treeSet.size());
//5.判断是否存在
System.out.println(treeSet.contains(3));
//6.清空元素
treeSet.clear();
//7.判断为空
System.out.println(treeSet.isEmpty());
System.out.println(treeSet); // [1, 2, 3, 5] 无重复且排序
}
}
2.7TreeSet的三大循环
public class TreeSetDemo {
public static void main(String[] args) {
//1.定义一个集合
TreeSet<Integer> treeSet=new TreeSet<>();
//2.添加元素
treeSet.add(2);
treeSet.add(3);
treeSet.add(1);
treeSet.add(5);
//3.删除元素
treeSet.remove(2);
//4.返回长度
System.out.println(treeSet.size());
//5.判断是否存在
System.out.println(treeSet.contains(3));
//6.清空元素
treeSet.clear();
//7.判断为空
System.out.println(treeSet.isEmpty());
System.out.println(treeSet); // [1, 2, 3, 5] 无重复且排序
}
}