集合底层数据结构简单实现

一、LinkedList集合

LinkedList简介:

LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。
LinkedList 实现 List 接口,能对它进行队列操作。
LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。
LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。
LinkedList 是非同步的。

LinkedList底层源码:

  LinkedList实际上是通过双向链表去实现的。既然是双向链表,那么它的顺序访问会非常高效,而随机访问效率比较低
    既然LinkedList是通过双向链表的,但是它也实现了List接口{也就是说,它实现了get(int location)、remove(int location)等“根据索引值来获取、删除节点的函数”}。LinkedList是如何实现List的这些接口的,如何将“双向链表和索引值联系起来的”?
    实际原理非常简单,它就是通过一个计数索引值来实现的。例如,当我们调用get(int location)时,首先会比较“location”和“双向链表长度的1/2”;若前者大,则从链表头开始往后查找,直到location位置;否则,从链表末尾开始先前查找,直到location位置。
   这就是“双线链表和索引值联系起来”的方法。

代码模拟双向链表

class Demo11 {
    public static void main(String[] args) {
        /**
         * 1.创建数据
         */
        Node node1 = new Node("李云峰");
        Node node2 = new Node("刘文闯");
        Node node3 = new Node("刘承毅");

        /**
         * 2.将节点连接
         */
        node1.next = node2;
        node2.next = node3;
        node3.pre = node2;
        node2.pre = node1;


        /**
         * 3.设置双向链表的头尾节点
         */
        Node first = node1;
        Node last = node3;

        /**
         * 4.遍历双向链表
         */
        while (first != null) {
            System.out.println(first);
            // 指向下一节点
            first = first.next;
        }
    }
}

class Node {
    /**
     * 姓名
     */
    Object message;
    /**
     * 指向前一个节点
     */
    Node pre;
    /**
     * 指向后一个节点
     */
    Node next;

    public Node(Object message) {
        this.message = message;
    }

    @Override
    public String toString() {
        return (String) message;
    }
}

遍历结果:

李云峰
刘文闯
刘承毅

插入一个Node节点:  

 1 public static void main(String[] args) {
 2     /**
 3      * 1.创建数据
 4      */
 5     Node node1 = new Node("李云峰");
 6     Node node2 = new Node("刘文闯");
 7     Node node3 = new Node("刘承毅");
 8     /**
 9      * 2.将节点连接
10      */
11     node1.next = node2;
12     node2.next = node3;
13     node3.pre = node2;
14     node2.pre = node1;
15     /**
16      * 3.设置双向链表的头尾节点
17      */
18     Node first = node1;
19     Node last = node3;
20     // 添加一个节点
21     Node node4 = new Node("张志喜");
22     node3.pre = node4;
23     node2.next  = node4;
24     node4.next = node3;
25     node4.pre = node2;
26     /**
27      * 4.遍历双向链表
28      */
29     while (first != null) {
30         System.out.println(first);
31         // 指向下一节点
32         first = first.next;
33     }
34 }

遍历输出:

李云峰
刘文闯
张志喜
刘承毅

二、HashSet

HashSet这个类实现了Set集合,实际为一个HashMap的实例。对集合的迭代次序没有任何保证; 特别是,它不能保证订单会随着时间的推移保持不变。这个类允许null 元素(只允许有一个)

底层的存储结构(数组+链表+红黑树)

注意:同时满足(链表元素达到8个,Table长度大于64,会自动转换为红黑树数据数据结构进行存储)

 

 代码实现:

/**
 * @author zhangzhixi
 * @date 2021-6-19 12:47
 */
public class HashSet底层实现 {
    public static void main(String[] args) {
        // 1、创建一个数组,数组类型是Node
        Node[] table = new Node[10];
        // 2、创建节点
        Node node1 = new Node("刘文闯", null);

        // 3、将节点放到数组下标为2的table中去
        table[2] = node1;

        // 4、继续放入节点
        Node node2 = new Node("李云峰", null);

        // 4.1、将node2挂载到node1
        node1.next = node2;


        System.out.println(table[0]);
    }
}

class Node {
    String name;
    Node next;

    public Node(String name, Node next) {
        this.name = name;
        this.next = next;
    }

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

 

 

  

 

posted @ 2021-06-19 12:03  Java小白的搬砖路  阅读(139)  评论(0编辑  收藏  举报