让你能够上手set集合
一.HashSet
Java 中的 HashSet
是一个集合类,它实现了 Set
接口,并基于哈希表实现。HashSet
不允许存储重复的元素,并且不保证集合元素的顺序。HashSet
的基本特性和遍历方法如下:
特点:
无序,不重复,无索引
(一).基础
1. **初始化**:
可以使用不同的构造函数来创建一个 `HashSet`:
// 创建一个空的 HashSet
HashSet<String> set1 = new HashSet<>();
// 创建一个包含另一个集合的 HashSet
Collection<String> collection = Arrays.asList("A", "B", "C");
HashSet<String> set2 = new HashSet<>(collection);
// 创建一个指定初始容量的 HashSet
HashSet<String> set3 = new HashSet<>(50);
// 创建一个指定初始容量和加载因子的 HashSet
HashSet<String> set4 = new HashSet<>(50, 0.75f);
- 基本操作:
HashSet<String> set = new HashSet<>();
// 添加元素
set.add("A");
set.add("B");
// 检查元素是否存在
boolean containsA = set.contains("A"); // true
boolean containsC = set.contains("C"); // false
// 删除元素
set.remove("A");
// 获取集合大小
int size = set.size(); // 1
// 清空集合
set.clear();
// 判断集合是否为空
boolean isEmpty = set.isEmpty(); // true
(二).遍历
HashSet
提供了多种遍历方式:
- 使用 Iterator:
HashSet<String> set = new HashSet<>(Arrays.asList("A", "B", "C"));
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
String element = iterator.next();
System.out.println(element);
}
- 使用增强 for 循环:
for (String element : set) {
System.out.println(element);
}
- 使用 forEach 方法和 Lambda 表达式:
set.forEach(element -> {
System.out.println(element);
});
//简写形式,完整的lambda表达式是创建匿名内部类实现accept方法
三种经典遍历,都可以使用
(三).示例代码
下面是一个完整的示例代码,展示了 HashSet
的基本操作和遍历方法:
import java.util.HashSet;
import java.util.Iterator;
public class HashSetExample {
public static void main(String[] args) {
// 创建一个 HashSet
HashSet<String> set = new HashSet<>();
// 添加元素
set.add("A");
set.add("B");
set.add("C");
set.add("D");
// 打印集合元素
System.out.println("HashSet 元素: " + set);
// 检查元素是否存在
if (set.contains("B")) {
System.out.println("集合包含元素 B");
}
// 删除元素
set.remove("C");
System.out.println("删除元素 C 后: " + set);
// 遍历集合 (使用 Iterator)
Iterator<String> iterator = set.iterator();
System.out.println("使用 Iterator 遍历:");
while (iterator.hasNext()) {
String element = iterator.next();
System.out.println(element);
}
// 遍历集合 (使用增强 for 循环)
System.out.println("使用增强 for 循环遍历:");
for (String element : set) {
System.out.println(element);
}
// 遍历集合 (使用 forEach 方法和 Lambda 表达式)
System.out.println("使用 forEach 方法和 Lambda 表达式遍历:");
set.forEach(element -> {
System.out.println(element);
});
// 遍历集合 (使用 Stream API)
System.out.println("使用 Stream API 遍历:");
set.stream().forEach(System.out::println);
// 清空集合
set.clear();
System.out.println("清空集合后: " + set);
}
}
二.linkedhashset
LinkedHashSet
是 Java 集合框架中的一个类,它继承自 HashSet
并实现了 Set
接口。LinkedHashSet
维护了元素的插入顺序,这意味着当我们遍历集合时,元素会按照它们被插入的顺序返回。它通过双重链表来维护这种顺序。
特点:
有序,不重复,无索引
底层仍然是hash表,但每个元素添加双链表机制记录顺序
(一).基础
- 初始化:
可以使用不同的构造函数来创建一个LinkedHashSet
:
// 创建一个空的 LinkedHashSet
LinkedHashSet<String> set1 = new LinkedHashSet<>();
// 创建一个包含另一个集合的 LinkedHashSet
Collection<String> collection = Arrays.asList("A", "B", "C");
LinkedHashSet<String> set2 = new LinkedHashSet<>(collection);
// 创建一个指定初始容量的 LinkedHashSet
LinkedHashSet<String> set3 = new LinkedHashSet<>(50);
// 创建一个指定初始容量和加载因子的 LinkedHashSet
LinkedHashSet<String> set4 = new LinkedHashSet<>(50, 0.75f);
- 基本操作:
LinkedHashSet<String> set = new LinkedHashSet<>();
// 添加元素
set.add("A");
set.add("B");
// 检查元素是否存在
boolean containsA = set.contains("A"); // true
boolean containsC = set.contains("C"); // false
// 删除元素
set.remove("A");
// 获取集合大小
int size = set.size(); // 1
// 清空集合
set.clear();
// 判断集合是否为空
boolean isEmpty = set.isEmpty(); // true
(二).遍历
LinkedHashSet
提供了多种遍历方式:
- 使用 Iterator:
LinkedHashSet<String> set = new LinkedHashSet<>(Arrays.asList("A", "B", "C"));
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
String element = iterator.next();
System.out.println(element);
}
- 使用增强 for 循环:
for (String element : set) {
System.out.println(element);
}
- 使用 forEach 方法和 Lambda 表达式:
set.forEach(element -> {
System.out.println(element);
});
还是经典三种遍历方式
三.TreeSet
TreeSet
是 Java 集合框架中的一个类,它实现了 NavigableSet
接口,并基于 TreeMap
实现。TreeSet
保证了集合中的元素是有序的,默认情况下是按照元素的自然顺序进行排序的,或者可以通过提供的比较器进行排序。TreeSet
不允许存储重复的元素。
TreeSet并不是 Set的子类,而是实现了 NavigableSet接口,NavigableSet接口又扩展了SortedSet接口,而SortedSet接口是Set接口的子接口。因此,TreeSet间接地实现了 `Set` 接口。
特点:
不重复,无索引,可排序
底层是红黑树实现
在treeset里面添加数据会默认进行排序,从小到大
(一).基础
- 初始化:
可以使用不同的构造函数来创建一个TreeSet
:
// 创建一个空的 TreeSet
TreeSet<String> set1 = new TreeSet<>();
// 创建一个包含另一个集合的 TreeSet
Collection<String> collection = Arrays.asList("A", "B", "C");
TreeSet<String> set2 = new TreeSet<>(collection);
// 创建一个使用自定义比较器的 TreeSet
Comparator<String> comparator = (s1, s2) -> s2.compareTo(s1); // 降序排序
TreeSet<String> set3 = new TreeSet<>(comparator);
- 基本操作:
TreeSet<String> set = new TreeSet<>();
// 添加元素
set.add("A");
set.add("B");
// 检查元素是否存在
boolean containsA = set.contains("A"); // true
boolean containsC = set.contains("C"); // false
// 删除元素
set.remove("A");
// 获取集合大小
int size = set.size(); // 1
// 清空集合
set.clear();
// 判断集合是否为空
boolean isEmpty = set.isEmpty(); // true
(二).遍历
set经典三件套,跟上面一样增强for,迭代器与lambda表达式
(三).排序
(1).默认排序规则
基本数据类型
<1.对于int,double这种,按照数据大小进行排序
<2.对于string这种字符串类型,按照ASCII码表数字的升序进行排序,如果是多字符比较,则从首字母开始比较,与字符长度无关,比如ac c a,最后排序为a ac c
--多字符比较,从首字母开始从左到右一次比较,空字符要比任何字符要小
比如 ac 与aca比较,最后ac更小
例:ac abc a d aca ab 最后比较结果为a ab abc ac aca d
当前面的字符确认了大小关系后面就不用看了
(2).自定义对象排序
通过指定比较规则进行排序
<自然排序/默认排序>
javabean类通过实现comparable接口指定比较规则
1.javabean类实现comparable接口
2.重写compareto方法
public int compareto(Object o)
{
//规则
return this.getage-o.getage;//年龄从小到大排序
//Object o 是树中已经存在的值
//this是代表要添加到树中的值
//return的值
//负数 认为添加的元素是小的,放在左边
//0 添加的元素已经存在,舍弃
//整数 认为添加的元素是大的存在右边
}
<比较器排序>
创建对象的时候传递比较器指定规则
// 使用匿名内部类实现比较器
TreeSet<Person> personSet = new TreeSet<>(new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2){
// 按照年龄从大到小排序
return p2.getAge() - p1.getAge();
}
});