前言
牢记认Collection图谱
一、Set集合是什么
Set集合是一种用于存储无序、不重复元素的集合。
二、Set集合特点
- 唯一性:Set集合中的元素都是唯一的,不允许出现重复。
- 无序性:Set集合不保证元素的顺序,即无法对元素进行排序。Set集合中元素的插入、删除和查找操作的时间复杂度都是O(1),
- Set集合不允许插入null元素。
- Set 中的元素是基于哈希表实现的,因此 Set 具有快速的查找和插入速度。
三、常见的实现类
1. HashSet集合
HashSet基于HashMap实现,底层采用HashMap来保存元素,
注意:HashSet没有get()方法
。(后面会介绍HashMap的使用及结构)
1.1 HashSet常用方法
1.1.1添加元素:可以使用add()方法向HashSet中添加元素
HashSet<String> hashSet = new HashSet<String>();
hashSet.add("apple");
hashSet.add("banana");
hashSet.add("orange");
1.1.2 移除元素:可以使用remove()方法获取HashSet中的元素
public class AppMain {
public static void main(String[] args) {
HashSet<String> hashSet = new HashSet<>();
hashSet.add("apple");
hashSet.add("banana");
hashSet.add("orange");
boolean banana = hashSet.remove("banana");
System.out.printf("删除banana是否成功: %s%n删除之后hashSet的值为%s", banana, hashSet);
}
}
删除banana是否成功: true
删除之后hashSet的值为[orange, apple]
1.1.3是否包含某个元素:使用contains()方法
public class AppMain {
public static void main(String[] args) {
HashSet<String> hashSet = new HashSet<>();
hashSet.add("apple");
hashSet.add("banana");
hashSet.add("orange");
boolean banana = hashSet.contains("banana");
System.out.printf("hashSet是否包含banana:%s%n", banana);
}
}
hashSet是否包含banana:true
1.1.4 遍历集合,两种方式:使用迭代器(Iterator)或for-each循环遍历
public class AppMain {
public static void main(String[] args) {
HashSet<String> hashSet = new HashSet<>();
hashSet.add("apple");
hashSet.add("banana");
hashSet.add("orange");
Iterator<String> iterator = hashSet.iterator();
while (iterator.hasNext()) {
String element = iterator.next();
System.out.printf("当前值为:%s%n", element);
}
}
}
当前值为:banana
当前值为:orange
当前值为:apple
public class AppMain {
public static void main(String[] args) {
HashSet<String> hashSet = new HashSet<>();
hashSet.add("apple");
hashSet.add("banana");
hashSet.add("orange");
for (String element : hashSet) {
System.out.printf("当前值为:%s%n", element);
}
}
}
当前值为:banana
当前值为:orange
当前值为:apple
2.LinkedHashSet集合
- 它是HashSet的子类,继承了HashSet的无序性、不保证迭代顺序、不允许存储重复元素的特点。
- LinkedHashSet在内部通过链表维护了元素的插入顺序,可以保证取出的顺序和存入的顺序一致。
LinkedHashSet的使用方法和HashSet一直,这里提一点的是,当我们将LinkedHashSet或者HashSet转为stream流以后,我们就有了很多操作空间,下面只是单独举几例:
2.1 LinkedHashSet之Stream流操作
2.1.1 获取第一个值
public class AppMain {
public static void main(String[] args) {
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<String>();
linkedHashSet.add("apple");
linkedHashSet.add("banana");
linkedHashSet.add("orange");
Optional<String> first = linkedHashSet.stream().findFirst();
System.out.println(first.get());
}
}
apple
2.2.2 Stream流的过滤操作
public class AppMain {
public static void main(String[] args) {
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<String>();
linkedHashSet.add("apple");
linkedHashSet.add("banana");
linkedHashSet.add("orange");
linkedHashSet.add("");
List<String> collect = linkedHashSet.stream().filter(item -> item.contains("an")).collect(Collectors.toList());
System.out.println(collect);
}
}
[banana, orange]
这些转为流操作的是java8的特性,有时间可以学习下,java8的stream流在我们常用开发中,虽然能简化很多代码,但是复杂的语句造成可读性变差,所以一般简便的用法值得使用,复杂的语句还是尽量少使用,以免增加后期维护成本
这里可以看看小码哥呀的文章:Java8新特性:Stream流
3 TreeSet
TreeSet 是一个基于红黑树(一种自平衡二叉查找树)实现的 Set 集合,它保证了集合中的元素是有序的。TreeSet 不仅可以存储基本数据类型的元素,而且可以存储对象,只要这个对象实现了 Comparable 接口或者在创建 TreeSet 的时候传入一个 Comparator 对象。
3.1 TreeSet特点
1.有序性:TreeSet 中的元素是有序的,根据元素的自然顺序或者创建 TreeSet 时传入的 Comparator 来确定顺序。
2.唯一性:TreeSet 中的元素必须是唯一的,不会允许重复的元素存在。
3.高效的查找、插入和删除操作:由于 TreeSet 是基于红黑树实现的,因此对于查找、插入和删除操作的时间复杂度可以达到 O(log n)。
TreeSet同样有add()方法,remove()方法,contains()方法,也是需要迭代器(Iterator)或for-each循环遍历,这里说点其他的。
3.1.1 正序
public class AppMain {
public static void main(String[] args) {
TreeSet<String> treeSet = new TreeSet<>();
treeSet.add("f");
treeSet.add("k");
treeSet.add("a");
treeSet.add("t");
treeSet.add("g");
System.out.printf("默认会以按小到大的排序:%s", treeSet);
}
}
3.1.2 倒序
public class AppMain {
public static void main(String[] args) {
TreeSet<String> treeSet = new TreeSet<>(Comparator.reverseOrder());
treeSet.add("f");
treeSet.add("k");
treeSet.add("a");
treeSet.add("t");
treeSet.add("g");
System.out.printf("默认会以按小到大的排序:%s", treeSet);
}
}
默认会以按大到小的排序:[t, k, g, f, a]
3.1.3 自定义
public static void main(String[] args) {
TreeSet<Integer> treeSet = new TreeSet<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
// 与下面等价 return o1.compareTo(o2);
return (o1 < o2) ? -1 : ((o1 == o2) ? 0 : 1);
}
});
treeSet.add(2);
treeSet.add(7);
treeSet.add(3);
treeSet.add(6);
treeSet.add(4);
System.out.printf("默认会以按小到大的排序:%s", treeSet);
}
}
默认会以按小到大的排序:[2, 3, 4, 6, 7]
总结
以上就是Set的基本使用。