本次博客带领大家了解集合中的Set接口实现类-LinkedHashSet。
LinkedHashSet的全面说明
- LinkedHashSet 是 HashSet 的子类。
- LinkedHashSet 底层是一个 LinkedHashMap,底层维护了一个数组+双向链表。
- LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置,同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的。
- LinkedHashSet 不允许添重复元素。
LinkedHashSet的低层机制
Set set = new LinkedHashSet();
set.add(new String("AA"));
set.add(456);
set.add(456);
set.add(new Customer("李",1001));
set.add(123);
set.add("ld");
System.out.println(set);
//1.LinkedHashSet 加入顺序和取出元素/数据的顺序一致
//2.LinkedHashSet 底层维护的是一个LinkedHashMap(是HashMap的子类)
//3.LinkedHashSet 底层结构(数组+双向链表)
//4.添加第一次时,直接将 数组table 扩容到16 ,存放的节点类型LinkedHashMap$Entry
//5.数组是 LinkedHashMap$Node[] 存放的元素/数据是 LinkedHashMap$Entry类型
说明:
- 在LinkedHashSet 中维护了一个hash表和双向链表(LinkedHashSet 有 head 和 tail)。
- 每一个节点有before 和 after 属性,这样可以形成双向链表。
- 在添加一个元素时,先求hash值,在求索引,确定该元素在table的位置,然后将添加的元素加入到双向链表(如果已经存在,不添加)。
- 这样的话,我们遍历LinkedHashSet 也能确保插入顺序和遍历顺序一致。
LinkedHashSet的练习
练习:Car 类(属性:name,price) ,如果 name 和 price一样,则认为是相同元素,就不能添加。
public class LinkedHashSetExercise {
public static void main(String[] args) {
LinkedHashSet linkedHashSet = new LinkedHashSet();
linkedHashSet.add(new Car("奥拓",1000));
linkedHashSet.add(new Car("奥迪",10000));
linkedHashSet.add(new Car("法拉利",100000));
linkedHashSet.add(new Car("奥迪",10000));
linkedHashSet.add(new Car("保时捷",1000000));
linkedHashSet.add(new Car("奥迪",10000));
System.out.println("LinkedHashSet="+linkedHashSet);
}
}
class Car{
private String name;
private double price;
public Car(String name, double price) {
this.name = name;
this.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;
}
@Override
public String toString() {
return "\nCar{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
//重写equals 方法和hashCode
//当 name 和 price 相同时,就返回相同的hashCode 值,equals返回TRUE
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Car car = (Car) o;
return Double.compare(car.price, price) == 0 &&
Objects.equals(name, car.name);
}
@Override
public int hashCode() {
return Objects.hash(name, price);
}
}