java集合类学习笔记之LinkList

1、简述

    LinkList的底层其实就是一个双向链表,所谓的链表就是一个LinkList内部静态静态类(Node),对LinkList的所有操作本质上就是通过对LinkList中新建的Node对象

  进行关联引用

2、实现

    a、构造方法:

        LinkList一共提供了两种构造方法:

    

 /**
     * Constructs an empty list.
     */
    public LinkedList() {
    }

    /**
     * Constructs a list containing the elements of the specified
     * collection, in the order they are returned by the collection‘s
     * iterator.
     *
     * @param  c the collection whose elements are to be placed into this list
     * @throws NullPointerException if the specified collection is null
     */
    public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }

    b、定义内部私有属性

        

transient int size = 0;

    /**
     * Pointer to first node.
     * Invariant: (first == null && last == null) ||
     *            (first.prev == null && first.item != null)
     */
    transient Node<E> first;

    /**
     * Pointer to last node.
     * Invariant: (first == null && last == null) ||
     *            (last.next == null && last.item != null)
     */
    transient Node<E> last;

    LinkList的内部属性只有三个,一个是LinkList的长度,另外两个分别是第一个节点和最后一个节点,每次对LinkList进行更新操作之后,第一个节点和最后一个节点的值都会进行相应的变化。

3、LinkList操作

   增加操作:

      add(E e):

    

/**
     * Appends the specified element to the end of this list.
     *
     * <p>This method is equivalent to {@link #addLast}.
     *
     * @param e element to be appended to this list
     * @return {@code true} (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        linkLast(e);
        return true;
    }

/**
     * Links e as last element.
     */
    void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }

    调用add(E e)操作LinkList的时候先new一个Node对象,并设置该节点的上一个元素为之前的最后一个节点,然后再将之前最后一个节点的next属性指向新建的节点

    add(int index, E element):

  

 /**
     * Inserts the specified element at the specified position in this list.
     * Shifts the element currently at that position (if any) and any
     * subsequent elements to the right (adds one to their indices).
     *
     * @param index index at which the specified element is to be inserted
     * @param element element to be inserted
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public void add(int index, E element) {
        checkPositionIndex(index);

        if (index == size)
            linkLast(element);
        else
            linkBefore(element, node(index));
    }
 /**
     * Inserts element e before non-null Node succ.
     */
    void linkBefore(E e, Node<E> succ) {
        // assert succ != null;
        final Node<E> pred = succ.prev;
        final Node<E> newNode = new Node<>(pred, e, succ);
        succ.prev = newNode;
        if (pred == null)
            first = newNode;
        else
            pred.next = newNode;
        size++;
        modCount++;
    }

     调用add(int index, E element)操作的时候和add(E element)方法是一样的,就是通过改变index位置节点的中的next和prev属性的值,再将新创建的节点的next指向原来index位置的节点

 LinkList的删除更新操作本质其实就是通过对内部节点的next和prev属行引用的值进行改变,所以在这里就不再对那些操作一一叙述了

总结:

   之前因为刚看完ArrayList,ArrayList内部是通过数组来对内部数据的保存,所以开始一直纠结这LinkList的数据是保存在哪里的,其实LinkList的数据是直接保存在jvm中的,因为往LinkList中增加数据的时候,其实就是new了一个ArrayList的静态内部类的对象,只不过LinkList的first和last属性指向了这些对象的引用,所以这些对象是一直不会被gc回收的,当LinkList删除一个元素的时候,只不过是将其他的节点对那个节点的引用给删除,然后被删除的那个对象没了引用就会被gc回收。这样的实现方式导致了LinkList里面的元素的jvm中的分布是杂乱的,所以当你根据下标去获取LinkList中的元素是只能通过一个个的去遍历,这样也就导致了它的读取效率低

 

  

时间: 2024-08-28 01:18:43

java集合类学习笔记之LinkList的相关文章

Java集合类学习笔记(Set集合)

Set集合不允许包含相同的元素,如果试图把两个相同的元素加入同一个Set集合中,则添加操作失败,add()方法返回false,且新元素不会被加入. HashSet类的特点: 不能保证元素的排列顺序,顺序可能与添加顺序不同,也有可能发生变化. HashSet不是同步的,如果多个线程同时访问并修改一个HashSet时,必须保证其同步. 元素值可以是null. LinkedHashSet类的特点: 是HashSet类的子类,它根据元素的hashCode值来决定元素的存储位置,但同时使用链表维护元素的次

Java集合类学习笔记

前言:下载Java的API,需要使用接口时,可在API中进行查询. 1.collection接口:可理解为一个动态的对象数组,不同的是集合中对象的内容可以任意扩充. 特点:性能高:易扩展和修改. 常用子类接口:List.Set.Queue. 2.List接口有ArrayList.vector子类,两者的使用方法相同,不同的是ArrayList是异步处理方式,性能高,但是非线程安全:vector同步处理方式,性能低,但是线程安全.在不要求线程安全的时候采用ArrayList子类. 使用实例: pa

Java集合类学习笔记(各种Map实现类的性能分析)

HashMap和Hashtable的实现机制几乎一样,但由于Hashtable是一个古老的.线程安全的集合,因此HashMap通常比Hashtable要快. TreeMap比HashMap和Hashtable要慢(尤其在插入.删除key-value对时更慢),TreeMap中的key-value总是处于有序状态,无需专门进行排序操作. LinkedHashMap比HashMap慢一点,因为它需要维护链表来保持Map中key-value时的添加顺序. IdentityHashMap采用与HashM

Java集合类学习笔记(Map集合)

Map用于保存具有映射关系的数据,因此Map集合里保存着两组数据,一组用于保存Map的key,一组用于保存key所对应的value. Map的key不允许重复. HashMap和Hashtable都是Map接口的典型实现类,他们的关系类似于ArrayList和Vector的关系. HashMap和Hashtable的区别: Hashtable是一个线程安全的Map实现,但HashMap是线程不安全的实现. Hashtable不允许使用null作为key和value,HashMap可以使用. Li

Java集合类学习笔记(各种线性表性能分析)

ArrayList.LinkedList是线性表的两种典型实现:基于数组的线性表和基于链的线性表. Queue代表了队列,Deque代表了双端队列. 一般来说,由于数组以一块连续内存区来保存所有的数组元素,所以数组在随机访问时性能最好: 而内部以链表作为底层实现的集合在执行插入.删除操作时有较好的性能. 总体来说,ArrayList的性能比LinkedList性能要好,因此大部分时候都应该考虑ArrayList. 关于使用List集合有如下建议: 如果需要遍历List集合元素,对于ArrayLi

Java集合类学习笔记(List集合)

List集合是指一个元素有序.可重复的集合,集合中每个元素都有其对应的顺序索引. ArrayList和Vector作为List集合的两个典型实现,完全支持List接口的全部功能,并且在用法上几乎完全相同. ArrayList和Vector的显著区别是: ArrayList不是线程安全的,Vector是线程安全的.

java nio学习笔记(一)

位置保留,待用 java nio学习笔记(一),布布扣,bubuko.com

JAVA基础学习笔记(2)

看了几天的视频了,都没时间来写下学习笔记,今天来写下第二次的学习笔记,前几天看的给忘记了,就写最新看到的吧 主要内容:1.类的变量与函数(方法) 2.对象的存储方式 3.新建一个对象及对象的赋值与调用 4.空对象 5.匿名对象 1.类的变量与函数(方法) class Dog      //类名 { String name;  //变量的声明 int age; String color; void bark()   //方法的定义(返回值为空,不带参数) { System.out.println(

java排序学习笔记

前面写了js的排序实现,总得玩玩java的哈. 同样,冒泡.选择.快速(这三个之前实现过也写过文章).堆排序,然后做比较. 主要遇到的难点: - -||想轻松点写个封装计时的逻辑,不想每调用一个排序就要写一个计时代码.想想,还是javascript写起来方便: java的话,我想到的方法是写一个抽象类:抽象出排序方法,实现一个排序计时方法(该方法调用了抽象排序,但在先后排序时加入计时代码[感觉像是aop操作]): 接着所有排序类都继承这个抽象类,并实现排序方法,调用的时候直接调用继承的排序计时方