Java基礎之:Set——HashSet——LinkedHashSet
阿新 • • 發佈:2020-12-26
LinkedHashSet簡單介紹
-
LinkedHashSet是HashSet的子類
-
LinkedHashSet根據元素的hashCode值來決定元素的儲存位置,但它同時使用連結串列維護元素的次序
-
LinkedHashSet新增效能略低於HashSet,但在迭代訪問Set裡的全部元素時有很好的效能。(因為底層維護了一個hash表+雙向連結串列)
-
LinkedHashSet底層是一個LinkedHashMap,維護的連結串列是一個雙向連結串列。
使用案例:
package class_TreeSet_LinkedHashSet; import java.util.LinkedHashSet; import java.util.Set; public class ClassTest02_LinkedHashSet { @SuppressWarnings({ "unchecked", "rawtypes" }) public static void main(String[] args) { Set set = new LinkedHashSet(); set.add(new String("AA")); set.add(456); set.add(456); set.add(new Customer("劉",1001)); set.add(123); System.out.println(set); } } class Customer{ private String name; private int id; public Customer(String name, int id) { super(); this.name = name; this.id = id; } @Override public String toString() { return "Customer [name=" + name + ", id=" + id + "]"; } }
案例說明:
-
在LinkedHastSet 中維護了一個hash表和雙向連結串列( LinkedHashSet 有 head 和 tail )
-
每一個節點有 pre 和 next 屬性, 這樣可以形成雙向連結串列。
-
在新增一個元素時,先求hash值,在求索引., 確定該元素在hashtable的位置,然後將新增的元素加入到雙向連結串列(如果已經存在,不新增[原則和hashset一樣])。
-
這樣的話,我們遍歷LinkedHashSet 也能確保插入順序和遍歷順序一致。
簡單使用案例
使用的Car 類(屬性:name,price), 需要重寫hashCode和equlas 方法. 如果 name 和 price 一樣,就不能加入到LinkedHashSet
package class_TreeSet_LinkedHashSet; import java.util.LinkedHashSet; public class ClassWork01 { @SuppressWarnings({ "unchecked", "rawtypes" }) public static void main(String[] args) { Car car1 = new Car("蔚來SE",460000); Car car2 = new Car("吉普",660000); Car car3 = new Car("蔚來SE",460000); LinkedHashSet linkedHashSet = new LinkedHashSet(); linkedHashSet.add(car1); linkedHashSet.add(car2); linkedHashSet.add(car3); for(Object obj:linkedHashSet) { System.out.println(obj); } } } class Car{ private String name; private double price; public Car(String name, double price) { super(); this.name = name; this.price = price; } @Override public String toString() { return "Car [name=" + name + ", price=" + price + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } //可以自己定義對比機制,也可以系統生成。 //alt + shift + s --> h //右鍵 --> Source --> Generate hashCode() and equals() @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); long temp; temp = Double.doubleToLongBits(price); result = prime * result + (int) (temp ^ (temp >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Car other = (Car) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (Double.doubleToLongBits(price) != Double.doubleToLongBits(other.price)) return false; return true; } }