HashSet是Set接口的典型实现,大多数时候使用Set集合时就是使用这个实现类。HashSet按Hash算法来存储集合中的元素,因此具有很好的存取和查找性能。
HashSet具有以下特点:
不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化。
HashSet不是同步的,如果多个线程同时访问一个HashSet,必须通过代码来保证其同步。
集合元素可以是null。
Java Collections框架的HashSet类提供了哈希表数据结构的功能,它实现Set接口。
创建一个哈希集
为了创建哈希集,我们必须先导入java.util.HashSet包。
导入包后,就可以在Java中创建哈希集。
//具有8个容量和0.75负载因子的HashSet
HashSet<Integer> numbers = new HashSet<>(8, 0.75);
在这里,我们创建了一个名为的哈希集numbers。
注意,新的部分HashSet<>(8, 0.75)。这里,第一参数是容量,并且第二参数是负载因子。
capacity -该哈希集的容量为8。意味着,它可以存储8个元素。
loadFactor - 此哈希集的负载因子为0.6。这意味着,只要我们的哈希集填充了60%,元素就会移到新哈希表中,该哈希表的大小是原始哈希表的两倍。
默认容量和负载因子
创建散列表而不定义其容量和负载因子是可能的。例如,
//具有默认容量和负载因子的HashSet
HashSet<Integer> numbers1 = new HashSet<>();
默认,
哈希集的容量将为 16
负载因子将为 0.75
HashSet的方法
HashSet类提供了各种方法,这些方法使我们可以对集合执行各种操作。
将元素插入HashSet
add() - 将指定的元素插入集合
addAll() - 将指定集合的所有元素插入集合
例如,
import java.util.HashSet;
class Main {
public static void main(String[] args) {
HashSet<Integer> evenNumber = new HashSet<>();
// 使用 add() 方法
evenNumber.add(2);
evenNumber.add(4);
evenNumber.add(6);
System.out.println("HashSet: " + evenNumber);
HashSet<Integer> numbers = new HashSet<>();
// 使用 addAll() 方法
numbers.addAll(evenNumber);
numbers.add(5);
System.out.println("New HashSet: " + numbers);
}
}
输出结果
HashSet: [2, 4, 6]
New HashSet: [2, 4, 5, 6]
访问HashSet元素
要访问哈希集合的元素,我们可以使用iterator()方法。为了使用此方法,我们必须导入java.util.Iterator包。例如,
import java.util.HashSet;
import java.util.Iterator;
class Main {
public static void main(String[] args) {
HashSet<Integer> numbers = new HashSet<>();
numbers.add(2);
numbers.add(5);
numbers.add(6);
System.out.println("HashSet: " + numbers);
// 调用iterator()方法
Iterator<Integer> iterate = numbers.iterator();
System.out.print("使用Iterator的HashSet: ");
//访问元素
while(iterate.hasNext()) {
System.out.print(iterate.next());
System.out.print(", ");
}
}
}
输出结果
HashSet: [2, 5, 6]
使用Iterator的HashSet: 2, 5, 6,
删除元素
remove() - 从集合中删除指定的元素
removeAll() - 从集合中删除所有元素
例如,
import java.util.HashSet;
class Main {
public static void main(String[] args) {
HashSet<Integer> numbers = new HashSet<>();
numbers.add(2);
numbers.add(5);
numbers.add(6);
System.out.println("HashSet: " + numbers);
//使用remove()方法
boolean value1 = numbers.remove(5);
System.out.println("值5被删除? " + value1);
boolean value2 = numbers.removeAll(numbers);
System.out.println("所有的元素都被移除了吗? " + value2);
}
}
输出结果
HashSet: [2, 5, 6]
值5被删除? true
所有的元素都被移除了吗? true
Set操作方法
HashSet类的各种方法也可以用于执行各种set操作。
Set集合并集
执行两个集合之间的并集,我们可以使用addAll()方法。例如
import java.util.HashSet;
class Main {
public static void main(String[] args) {
HashSet<Integer> evenNumbers = new HashSet<>();
evenNumbers.add(2);
evenNumbers.add(4);
System.out.println("HashSet1: " + evenNumbers);
HashSet<Integer> numbers = new HashSet<>();
numbers.add(1);
numbers.add(3);
System.out.println("HashSet2: " + numbers);
//集合并集
numbers.addAll(evenNumbers);
System.out.println("Union is: " + numbers);
}
}
输出结果
HashSet1: [2, 4]
HashSet2: [1, 3]
Union is: [1, 2, 3, 4]
Set集合的交集
要执行两个集合之间的交集,我们可以使用retainAll()方法。例如
import java.util.HashSet;
class Main {
public static void main(String[] args) {
HashSet<Integer> primeNumbers = new HashSet<>();
primeNumbers.add(2);
primeNumbers.add(3);
System.out.println("HashSet1: " + primeNumbers);
HashSet<Integer> evenNumbers = new HashSet<>();
evenNumbers.add(2);
evenNumbers.add(4);
System.out.println("HashSet2: " + evenNumbers);
//集合的交集
evenNumbers.retainAll(primeNumbers);
System.out.println("交集: " + evenNumbers);
}
}
输出结果
HashSet1: [2, 3]
HashSet2: [2, 4]
交集: [2]
Set集合的差集
要计算两组之间的差集,我们可以使用removeAll()方法。例如,
import java.util.HashSet;
class Main {
public static void main(String[] args) {
HashSet<Integer> primeNumbers = new HashSet<>();
primeNumbers.add(2);
primeNumbers.add(3);
primeNumbers.add(5);
System.out.println("HashSet1: " + primeNumbers);
HashSet<Integer> oddNumbers = new HashSet<>();
oddNumbers.add(1);
oddNumbers.add(3);
oddNumbers.add(5);
System.out.println("HashSet2: " + oddNumbers);
//HashSet1和HashSet2之间的差集
primeNumbers.removeAll(oddNumbers);
System.out.println("Difference : " + primeNumbers);
}
}
输出结果
HashSet1: [2, 3, 5]
HashSet2: [1, 3, 5]
差集: [2]
Set集合的子集
要检查一个集合是否是另一个集合的子集,我们可以使用containsAll()方法。例如,
import java.util.HashSet;
class Main {
public static void main(String[] args) {
HashSet<Integer> numbers = new HashSet<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
System.out.println("HashSet1: " + numbers);
HashSet<Integer> primeNumbers = new HashSet<>();
primeNumbers.add(2);
primeNumbers.add(3);
System.out.println("HashSet2: " + primeNumbers);
//检查primeNumbers是否是numbers的子集
boolean result = numbers.containsAll(primeNumbers);
System.out.println("HashSet2是HashSet1的子集吗? " + result);
}
}
输出结果
HashSet1: [1, 2, 3, 4]
HashSet2: [2, 3]
HashSet2是HashSet1的子集吗? true
HashSet的其他方法
方法 | 描述 |
---|---|
clone() | 创建HashSet副本 |
contains() | 在中搜索HashSet指定的元素,并返回布尔结果 |
isEmpty() | 检查是否HashSet为空 |
size() | 返回HashSet的大小 |
clear() | 从HashSet中删除所有元素 |
为什么选择HashSet?
在Java中,如果我们必须随机访问元素,则通常使用HashSet。 这是因为哈希表中的元素是使用哈希码访问的。
元素的hashcode是唯一标识,它有助于标识散列表中的元素。
HashSet不能包含重复的元素。因此,每个散列集元素都有一个惟一的hashcode。
注意: HashSet不同步。也就是说,如果多个线程同时访问哈希集合,并且其中一个线程修改了哈希集合。然后,它必须在外部同步。