-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathSet.java
More file actions
131 lines (109 loc) · 3.97 KB
/
Set.java
File metadata and controls
131 lines (109 loc) · 3.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import java.util.*;
public class Set {
private static final int INITIAL_CAPACITY = 16; // 初始哈希表容量
private static final float LOAD_FACTOR = 0.75f; // 负载因子
private LinkedList<Object>[] buckets; // 哈希桶数组,指定为存储 Object 类型的 LinkedList
private int capacity; // 哈希表容量
private int size; // 当前元素个数
// FNV-1a 哈希函数(用于计算哈希值)
private long fnvHash(Object key) {
byte[] bytes = key.toString().getBytes(); // 将键转换为字节数组
long hash = 2166136261L; // 初始哈希值,使用 long 类型
for (byte b : bytes) { // 对每个字节进行哈希计算
hash ^= b;
hash *= 16777619;
}
return hash;
}
// 创建 Set 并初始化
@SuppressWarnings("unchecked")
public Set() {
this.capacity = INITIAL_CAPACITY;
this.size = 0;
this.buckets = new LinkedList[capacity]; // 创建指定大小的桶数组
for (int i = 0; i < capacity; i++) {
buckets[i] = new LinkedList<Object>(); // 初始化每个桶为链表
}
}
// 扩容 Set
private void resize() {
int newCapacity = capacity * 2;
@SuppressWarnings("unchecked")
LinkedList<Object>[] newBuckets = new LinkedList[newCapacity];
// 重新哈希所有元素
for (int i = 0; i < capacity; i++) {
for (Object key : buckets[i]) {
int newIndex = (int) (fnvHash(key) % newCapacity); // 使用新的容量计算索引
if (newBuckets[newIndex] == null) {
newBuckets[newIndex] = new LinkedList<Object>(); // 指定泛型类型
}
newBuckets[newIndex].add(key); // 将元素重新插入到新的桶中
}
}
// 更新容量和桶数组
capacity = newCapacity;
buckets = newBuckets;
}
// 添加元素到 Set
public void add(Object key) {
// 判断是否需要扩容
if ((float) size / capacity > LOAD_FACTOR) {
resize(); // 扩容
}
int index = (int) (fnvHash(key) % capacity); // 计算索引
LinkedList<Object> bucket = buckets[index];
// 查找桶中是否已经有相同的元素
if (bucket.contains(key)) {
System.out.println("Exist node: index=" + index + " key=" + key);
return; // 已存在则不添加
}
// 没有找到相同的元素,进行插入
bucket.add(key);
size++;
// 打印调试信息:打印插入后的 node
System.out.println("Adding node: index=" + index + " key=" + key);
}
// 检查元素是否在 Set 中
public boolean contains(Object key) {
int index = (int) (fnvHash(key) % capacity);
return buckets[index].contains(key);
}
// 删除元素
public void remove(Object key) {
int index = (int) (fnvHash(key) % capacity);
LinkedList<Object> bucket = buckets[index];
if (bucket.remove(key)) {
size--;
System.out.println("Removed node: key=" + key);
}
}
// 获取 Set 中的元素个数
public int size() {
return size;
}
// 遍历 Set 并打印元素
public void print() {
for (int i = 0; i < capacity; i++) {
for (Object key : buckets[i]) {
System.out.print(key + " ");
}
}
System.out.println();
}
public static void main(String[] args) {
// 创建 Set 实例
Set set = new Set();
Integer[] values = {10, 20, 20, 30, 40, 40, 50};
// 添加元素
for (int value : values) {
set.add(value);
}
// 打印 Set 内容
set.print();
// 检查元素是否存在
System.out.println("Contains 30? " + set.contains(30));
// 删除元素
set.remove(30);
set.print();
}
}