HashSet 是 Java 集合框架中最常用的去重容器,基於 HashMap 實現,提供 O(1) 平均時間複雜度的增刪查操作。深入理解其底層機制對避免常見陷阱至關重要。
public static void testNormal() {
Set set = new HashSet();
set.add("字符串");
set.add(new Integer(1));
set.add(123.45); // 自動裝箱
System.out.println(set.size()); // 3
set.add("字符串"); // 重複忽略
System.out.println(set.size()); // 仍為 3
System.out.println(set.contains(123.45)); // true
set.remove(123.45);
System.out.println(set.size()); // 2
}
class MyObject {
private String name;
private int age;
@Override
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof MyObject)) return false;
MyObject o = (MyObject) obj;
return this.age == o.age && this.name.equals(o.name);
}
@Override
public int hashCode() {
return name.hashCode() + String.valueOf(age).hashCode();
}
}
MyObject obj = new MyObject("java2000", 2);
set.add(obj);
obj.setAge(3); // 修改導致 hashCode 變化
set.contains(obj); // 可能返回 false!
set.add(obj); // 重複添加成功,造成內存洩漏風險
class MyObject3 {
private String name;
private int age;
private int HASHCODE = Integer.MIN_VALUE;
@Override
public int hashCode() {
if (HASHCODE == Integer.MIN_VALUE) {
HASHCODE = name.hashCode() + String.valueOf(age).hashCode();
}
return HASHCODE;
}
}
