Java Set
一、核心特性
• 无序性:存储顺序与插入顺序无关(HashSet 完全无序,LinkedHashSet 保持插入顺序)。
• 唯一性:元素不可重复,依赖 equals() 和 hashCode() 方法判断。
• 无索引:不能通过下标访问元素,遍历需用迭代器、增强 for 循环。
二、主要实现类及区别
1. HashSet(最常用)
• 底层:哈希表(数组 + 链表/红黑树),查询、添加、删除效率高(O(1))。
• 特点:完全无序,允许存储 null 元素(仅一个)。
• 去重关键:存入元素需重写 hashCode() 和 equals(),确保相同元素哈希值一致且 equals 为 true。
2. LinkedHashSet
• 底层:哈希表 + 双向链表,兼具 HashSet 效率和有序性。
• 特点:保持元素插入顺序,遍历顺序与插入顺序一致,性能略低于 HashSet。
3. TreeSet
• 底层:红黑树(自平衡二叉排序树),元素会自然排序或自定义排序。
• 特点:无 null 元素(会抛空指针异常),排序依赖 Comparable 或 Comparator。
• 排序方式:
◦ 自然排序:元素类实现 Comparable 接口,重写 compareTo() 方法。
◦ 自定义排序:创建 TreeSet 时传入 Comparator 接口实现类(或 Lambda 表达式)。
三、常用方法(实现 Collection 接口,核心方法如下)
• 添加:add(E e)(重复元素返回 false,不存入)、addAll(Collection c)。
• 删除:remove(Object o)、removeAll(Collection c)、clear()(清空集合)。
• 判断:contains(Object o)(判断是否包含元素)、isEmpty()(判断是否为空)。
• 遍历:增强 for 循环(for (E e : set) {})、迭代器(Iterator<E> it = set.iterator();)。
• 其他:size()(获取元素个数)、toArray()(转为数组)。
四、关键注意点
1. 去重逻辑:HashSet/LinkedHashSet 中,若元素未重写 hashCode() 和 equals(),会默认使用 Object 类的方法(仅判断地址值),导致无法去重。
2. TreeSet 排序冲突:若元素既不实现 Comparable,也未指定 Comparator,会抛 ClassCastException。
3. 线程安全:Set 接口的实现类(HashSet、LinkedHashSet、TreeSet)均非线程安全,多线程环境需用 Collections.synchronizedSet(Set) 或 CopyOnWriteArraySet。
