LinkedHashSet源码解读

LinkedHashSet

1、在LinkedHashSet 中维护一个hash表的双向链表 LinkedHashSet有head和tail

2、每一个节点有pre和next属性这样形成一个双向链表

3、在添加一个元素先求hash值再求索引 确定该元素在hashtable的位置

然后将添加的元素加入到双向链表中如果已经存在不添加

tail.next = newElement

new,Element.pre=tail

tail = newElement

4、这样保证了 插入顺序和取出数据一致


package com.company.Collection.Set_;

import java.util.LinkedHashSet;
import java.util.Set;

public class LinkedHashSet_ {
    public static void main(String[] args) {
        //分析一下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("ZJQ");
        System.out.println("set"+set);
        //1、LinkedHashSet 加入顺序和取出元素/数据顺序一致
        //2、LinkedHashSet 底层维护的是一个LinkedHashMap(是hashmap的之类)
       //3、LinkedHashSet 底层结构(数组+双向链表)
    }
}
class Customer{
    private String name;
    private int age;
    public Customer(String name,int age){
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Customer{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

4、初始化为

大小为16 table 初始化大小 table是node 类别

在这里插入图片描述

每个node节点存放的是在这里插入图片描述

5、数组是 在这里插入图片描述

存放的节点在这里插入图片描述

static class Entry<K,V> extends HashMap.Node<K,V> {
    Entry<K,V> before, after;
    Entry(int hash, K key, V value, Node<K,V> next) {
        super(hash, key, value, next);
    }
}

其中 Entry 继承了 HashMap.Node 继承关系是在内部类中完成的

table的 after 即 hash中entryket

在这里插入图片描述

练习:

比较先比较 hash值是否相同 再比较 内容是否相同

如果要确定两个对象的是否相同

//本题中 只要是名称和价格相同则认为就是对象相同

//则需要重写hashcode方法

//步骤如下

在这里插入图片描述

选择java7版本

在这里插入图片描述

选择认为相同内容就选择hash值相同的属性

在这里插入图片描述

package com.company.Collection.Set_;

import java.util.LinkedHashSet;
import java.util.LinkedList;

public class LinkedHashSetExercise {
    public static void main(String[] args) {
        LinkedHashSet linkedHashSet = new LinkedHashSet();
        linkedHashSet.add(new Car("奥托",10000));
        linkedHashSet.add(new Car("奥迪",300000));
        linkedHashSet.add(new Car("法拉利",1000000000));
        linkedHashSet.add(new Car("奥迪",300000));

    }
}
class Car{
    private String name;
    private double price;
    public Car(String name, double price){
        this.name = name;
        this.price = price;
    }

    @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Car car = (Car) o;

        if (Double.compare(car.price, price) != 0) return false;
        return name != null ? name.equals(car.name) : car.name == null;
    }

    @Override
    public int hashCode() {
        int result;
        long temp;
        result = name != null ? name.hashCode() : 0;
        temp = Double.doubleToLongBits(price);
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        return result;
    }
}



.hashCode() : 0;
        temp = Double.doubleToLongBits(price);
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        return result;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`LinkedHashSet` 是 Java 集合框架中 `Set` 接口的一个实现,它维护了一个双向链表来保证元素的插入顺序。它是 `HashSet` 的一个变种,后者不会记录插入顺序,因此 `LinkedHashSet` 在需要维护插入顺序的情况下非常有用。 `LinkedHashSet` 是基于 `LinkedHashMap` 来实现的。`LinkedHashMap` 通过在 `HashMap` 的基础上添加了一对儿前后指针,形成了双向链表。这样一来,它就可以记录插入顺序,也可以实现快速的访问。 下面是一个简化版的 `LinkedHashSet` 的源码结构,用于展示其基本的实现方式: ```java public class LinkedHashSet<E> extends HashSet<E> implements Set<E>, Cloneable, java.io.Serializable { private static final long serialVersionUID = -2851667679971038690L; public LinkedHashSet(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor, true); } public LinkedHashSet(int initialCapacity) { super(initialCapacity, .75f, true); } public LinkedHashSet() { super(16, .75f, true); } public LinkedHashSet(Collection<? extends E> c) { super(Math.max(2*c.size(), 11), .75f, true); addAll(c); } @Override public Spliterator<E> spliterator() { return Spliterators.spliterator(this, Spliterator.DISTINCT | Spliterator.ORDERED); } // 由于 LinkedHashSet 是基于 LinkedHashMap 实现的,所以这里返回 LinkedHashMap 实例 @Override public Iterator<E> iterator() { return backingMap().keySet().iterator(); } // 以下是不重要的方法实现,省略... // 由于 LinkedHashSet 是基于 LinkedHashMap 实现的,这里可以访问 LinkedHashMap 的实例 private LinkedHashMap<E, ?> backingMap() { return (LinkedHashMap<E, ?>) backingMap; } } ``` 可以看到,`LinkedHashSet` 的大部分方法都是委托给 `HashSet` 的,而 `HashSet` 又是委托给其背后的一个 `HashMap`(实际上是 `LinkedHashMap`)来完成实际操作的。`LinkedHashSet` 只是添加了一些必要的构造函数,并且对外提供了一个迭代器来按照插入顺序访问元素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值