基本概念
HashSet
是 Java 集合框架中的一个类,用于存储不重复的元素。它基于哈希表实现,提供了快速的查找、添加和删除操作。
内部实现机制
HashSet
基于 HashMap
实现,内部维护了一个 HashMap
对象,每个元素作为 HashMap
的键存储,值则是一个固定的对象(通常是一个常量)。
主要字段
private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object();
主要方法
add(E e)
: 通过map.put(e, PRESENT)
实现。remove(Object o)
: 通过map.remove(o)
实现。contains(Object o)
: 通过map.containsKey(o)
实现。size()
: 通过map.size()
实现。
常用方法
boolean add(E e)
: 将指定元素添加到集合中,如果元素已存在,则不添加并返回false
。boolean remove(Object o)
: 从集合中移除指定元素,如果存在则返回true
,否则返回false
。boolean contains(Object o)
: 如果集合中包含指定元素,则返回true
。int size()
: 返回集合中的元素个数。void clear()
: 清空集合中的所有元素。boolean isEmpty()
: 如果集合为空,则返回true
。Iterator<E> iterator()
: 返回集合中元素的迭代器。
示例代码
示例1:基本操作
import java.util.HashSet;
public class HashSetBasicExample {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("Apple");
set.add("Banana");
set.add("Orange");
System.out.println("Set: " + set);
System.out.println("Contains 'Banana': " + set.contains("Banana"));
set.remove("Banana");
System.out.println("Set after removal: " + set);
System.out.println("Set size: " + set.size());
}
}
输出结果
Set: [Apple, Banana, Orange]
Contains 'Banana': true
Set after removal: [Apple, Orange]
Set size: 2
示例2:集合操作
import java.util.HashSet;
public class HashSetOperationsExample {
public static void main(String[] args) {
HashSet<String> set1 = new HashSet<>();
set1.add("Apple");
set1.add("Banana");
set1.add("Orange");
HashSet<String> set2 = new HashSet<>();
set2.add("Banana");
set2.add("Grape");
set2.add("Orange");
// 并集
HashSet<String> union = new HashSet<>(set1);
union.addAll(set2);
System.out.println("Union: " + union);
// 交集
HashSet<String> intersection = new HashSet<>(set1);
intersection.retainAll(set2);
System.out.println("Intersection: " + intersection);
// 差集
HashSet<String> difference = new HashSet<>(set1);
difference.removeAll(set2);
System.out.println("Difference: " + difference);
}
}
输出结果
Union: [Apple, Banana, Orange, Grape]
Intersection: [Banana, Orange]
Difference: [Apple]
示例3:自定义类的集合操作
import java.util.HashSet;
public class HashSetCustomClassExample {
public static void main(String[] args) {
HashSet<Employee> employees = new HashSet<>();
Employee emp1 = new Employee(1, "John");
Employee emp2 = new Employee(2, "Jane");
Employee emp3 = new Employee(1, "John"); // 与 emp1 相同
employees.add(emp1);
employees.add(emp2);
employees.add(emp3); // 不会被添加
for (Employee emp : employees) {
System.out.println(emp);
}
}
}
class Employee {
private int id;
private String name;
public Employee(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public int hashCode() {
return id;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Employee employee = (Employee) obj;
return id == employee.id && name.equals(employee.name);
}
@Override
public String toString() {
return "Employee{id=" + id + ", name='" + name + "'}";
}
}
输出结果
Employee{id=1, name='John'}
Employee{id=2, name='Jane'}
高级应用场景
1. 数据去重
在处理大量数据时,可能会遇到重复数据的情况。HashSet
可以用来过滤掉重复数据,确保集合中的元素唯一。
import java.util.HashSet;
import java.util.List;
public class DataDeduplication {
public static void main(String[] args) {
List<String> dataList = List.of("apple", "banana", "apple", "orange", "banana");
HashSet<String> uniqueData = new HashSet<>(dataList);
System.out.println("Unique Data: " + uniqueData);
}
}
输出结果
Unique Data: [apple, banana, orange]
2. 快速查找
HashSet
的查找操作时间复杂度为 O(1),适合用于需要快速查找的场景。
import java.util.HashSet;
public class FastLookupExample {
public static void main(String[] args) {
HashSet<Integer> set = new HashSet<>();
for (int i = 0; i < 1000000; i++) {
set.add(i);
}
long startTime = System.nanoTime();
boolean contains = set.contains(999999);
long endTime = System.nanoTime();
System.out.println("Contains 999999: " + contains);
System.out.println("Lookup Time: " + (endTime - startTime) + " ns");
}
}
输出结果
Contains 999999: true
Lookup Time: [时间值,通常非常小]
3. 集合运算
HashSet
提供了方便的集合运算方法,如并集、交集和差集。这些运算在处理集合数据时非常有用。
import java.util.HashSet;
public class SetOperationsExample {
public static void main(String[] args) {
HashSet<String> setA = new HashSet<>();
setA.add("A");
setA.add("B");
setA.add("C");
HashSet<String> setB = new HashSet<>();
setB.add("B");
setB.add("C");
setB.add("D");
// 交集
HashSet<String> intersection = new HashSet<>(setA);
intersection.retainAll(setB);
System.out.println("Intersection: " + intersection);
// 并集
HashSet<String> union = new HashSet<>(setA);
union.addAll(setB);
System.out.println("Union: " + union);
// 差集
HashSet<String> difference = new HashSet<>(setA);
difference.removeAll(setB);
System.out.println("Difference: " + difference);
}
}
输出结果
Intersection: [B, C]
Union: [A, B, C, D]
Difference: [A]