文章目录
- 1. Set概念简介
- 2. Set接口定义及关系
- 3. Set接口常用的API
- 核心方法代码示例
- 4. Set的常见实现类特性
- HashSet
- LinkedHashSet
- TreeSet
- EnumSet
- ConcurrentSkipListSet
- 5. Set的实际案例扩展
- 去重
- 集合运算
- 成员资格测试
1. Set概念简介
Set接口概述:
Set
是 Java 集合框架中的一个接口,它继承自 Collection
接口。Set
的主要特点是不允许重复元素,并且大多数实现不保证元素的顺序(除了 LinkedHashSet
和 TreeSet
)。这使得 Set
成为需要确保唯一性的场景的理想选择。
import java.util.HashSet;
import java.util.Set;public class SetExample {public static void main(String[] args) {// 创建一个HashSet实例Set<String> set = new HashSet<>();// 添加元素到Set中set.add("apple");set.add("orange");set.add("banana");set.add("apple"); // 尝试添加重复元素// 打印Set的内容System.out.println(set); // 输出: [orange, banana, apple] (顺序可能不同)}
}
2. Set接口定义及关系
Set接口定义:
Set<E>
继承自 Collection<E>
,并进一步限制了不能包含重复元素。这意味着所有适用于 Collection
的方法同样适用于 Set
,但 Set
提供了额外的约束来确保元素的唯一性。
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;public class SetAndCollection {public static void main(String[] args) {// 创建一个Set实例Set<String> set = new HashSet<>();set.add("apple");set.add("orange");// Collection接口的方法也可以在Set上使用Collection<String> collection = set;System.out.println(collection.size()); // 输出: 2System.out.println(collection.contains("apple")); // 输出: true}
}
3. Set接口常用的API
核心方法代码示例
- add/remove/contains/clear
这些方法用于添加、移除、检查集合是否包含某个元素以及清空集合。
import java.util.HashSet;
import java.util.Set;public class SetOperations {public static void main(String[] args) {Set<String> set = new HashSet<>();set.add("apple");set.add("orange");set.add("banana");System.out.println(set.contains("apple")); // 输出: trueSystem.out.println(set.remove("orange")); // 输出: trueset.clear();System.out.println(set.isEmpty()); // 输出: true}
}
- retainAll/removeAll
retainAll
方法用于保留当前集合中存在的也存在于指定集合中的元素,而 removeAll
则移除当前集合中所有存在于指定集合中的元素。
import java.util.HashSet;
import java.util.Set;public class SetRetainRemove {public static void main(String[] args) {Set<String> set1 = new HashSet<>();set1.add("apple");set1.add("orange");set1.add("banana");Set<String> set2 = new HashSet<>();set2.add("orange");set2.add("grape");set1.retainAll(set2);System.out.println(set1); // 输出: [orange]set1.addAll(set2);set1.removeAll(set2);System.out.println(set1); // 输出: []}
}
- toArray/stream
toArray
方法将集合转换为数组,而 stream
方法返回一个流,可以进行流式处理如过滤、映射等操作。
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;public class SetToArrayStream {public static void main(String[] args) {Set<String> set = new HashSet<>(Arrays.asList("apple", "orange", "banana"));// 转换为数组Object[] array = set.toArray();System.out.println(Arrays.toString(array));// 使用流操作Set<String> filtered = set.stream().filter(s -> s.startsWith("a")).collect(Collectors.toSet());System.out.println(filtered); // 输出: [apple, banana]}
}
4. Set的常见实现类特性
HashSet
HashSet
是基于哈希表的 Set
实现,提供了快速查找、添加和删除性能,但它不保证元素的顺序,并允许一个 null
元素。
代码示例:使用HashSet
import java.util.HashSet;
import java.util.Set;public class HashSetExample {public static void main(String[] args) {Set<String> hashSet = new HashSet<>();hashSet.add("apple");hashSet.add(null); // 允许一个null元素System.out.println(hashSet);}
}
LinkedHashSet
LinkedHashSet
继承自 HashSet
,并且维护了一个双向链表来记录插入顺序,因此它既保持了插入顺序又具备 HashSet
的高效性能。
代码示例:使用LinkedHashSet
import java.util.LinkedHashSet;
import java.util.Set;public class LinkedHashSetExample {public static void main(String[] args) {Set<String> linkedHashSet = new LinkedHashSet<>();linkedHashSet.add("apple");linkedHashSet.add("orange");linkedHashSet.add("banana");System.out.println(linkedHashSet); // 输出保持插入顺序}
}
TreeSet
TreeSet
实现了 SortedSet
接口,能够对元素进行排序,默认按照自然顺序或根据提供的比较器进行排序。底层使用红黑树数据结构,保证了对数级别的性能。
代码示例:使用TreeSet
import java.util.TreeSet;
import java.util.Set;public class TreeSetExample {public static void main(String[] args) {Set<String> treeSet = new TreeSet<>();treeSet.add("apple");treeSet.add("orange");treeSet.add("banana");System.out.println(treeSet); // 按照字母顺序输出}
}
EnumSet
EnumSet
是枚举类型的专用集合,实现了 Set
接口,所有元素必须属于同一个枚举类型,提供了高效且紧凑的存储方式。
代码示例:使用EnumSet
import java.util.EnumSet;enum Color { RED, GREEN, BLUE }public class EnumSetExample {public static void main(String[] args) {EnumSet<Color> colors = EnumSet.of(Color.RED, Color.GREEN);System.out.println(colors);}
}
ConcurrentSkipListSet
ConcurrentSkipListSet
是线程安全的 SortedSet
实现,基于跳表(Skip List)结构,支持并发访问而不需要外部同步。
代码示例:使用ConcurrentSkipListSet
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.Set;public class ConcurrentSkipListSetExample {public static void main(String[] args) {Set<Integer> concurrentSet = new ConcurrentSkipListSet<>();concurrentSet.add(1);concurrentSet.add(2);concurrentSet.add(3);System.out.println(concurrentSet); // 线程安全且有序}
}
5. Set的实际案例扩展
去重
利用 Set
的唯一性特性,可以轻松去除列表或其他集合中的重复项。
import java.util.HashSet;
import java.util.List;
import java.util.Arrays;public class RemoveDuplicates {public static void main(String[] args) {List<String> list = Arrays.asList("apple", "orange", "banana", "apple");Set<String> set = new HashSet<>(list);System.out.println(set); // 输出: [orange, banana, apple] (顺序可能不同)}
}
集合运算
通过 retainAll
、addAll
和 removeAll
方法,可以实现两个集合之间的交集、并集和差集运算。
import java.util.HashSet;
import java.util.Set;public class SetOperationsExample {public static void main(String[] args) {Set<String> set1 = new HashSet<>(Arrays.asList("apple", "orange", "banana"));Set<String> set2 = new HashSet<>(Arrays.asList("orange", "grape"));// 交集Set<String> intersection = new HashSet<>(set1);intersection.retainAll(set2);System.out.println("交集: " + intersection);// 并集Set<String> union = new HashSet<>(set1);union.addAll(set2);System.out.println("并集: " + union);// 差集Set<String> difference = new HashSet<>(set1);difference.removeAll(set2);System.out.println("差集: " + difference);}
}
成员资格测试
Set
提供了高效的 contains
方法,可以在常量时间内确定某个对象是否为集合的一员。
import java.util.HashSet;
import java.util.Set;public class MembershipTest {public static void main(String[] args) {Set<String> set = new HashSet<>(Arrays.asList("apple", "orange", "banana"));System.out.println("Contains 'apple': " + set.contains("apple")); // 输出: trueSystem.out.println("Contains 'grape': " + set.contains("grape")); // 输出: false}
}