菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
379
0

Java基础之:Set——HashSet——LinkedHashSet

原创
05/13 14:22
阅读数 84253

 

Java基础之:Set——HashSet——LinkedHashSet

LinkedHashSet简单介绍

  1. LinkedHashSet是HashSet的子类

  2. LinkedHashSet根据元素的hashCode值来决定元素的存储位置,但它同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的。

  3. LinkedHashSet添加性能略低于HashSet,但在迭代访问Set里的全部元素时有很好的性能。(因为底层维护了一个hash表+双向链表)

  4. 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 + "]";
    }
}

案例说明:

  1. 在LinkedHastSet 中维护了一个hash表和双向链表( LinkedHashSet 有 head 和 tail )

  2. 每一个节点有 pre 和 next 属性, 这样可以形成双向链表。

  3. 在添加一个元素时,先求hash值,在求索引., 确定该元素在hashtable的位置,然后将添加的元素加入到双向链表(如果已经存在,不添加[原则和hashset一样])。

  4. 这样的话,我们遍历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;
    }
}

  

 

发表评论

0/200
379 点赞
0 评论
收藏