JAVA集合(三)-LinkedList

LinkedList是常用的一种List的实现类,采取单向链表的结构

在LinkedList中,以一个内部的Node类来代表集合中的对象,对象的值赋给item属性,Node中的next属性指向当前对象的后一个对象,prev属性指向对象的前一个对象。同时也用了两个node属性,一个first代表链表的第一个元素
一个last代表链表的末尾,LinkedList具体实现方法如下:

一.LinedList继承结构
java.lang.Object
     -java.util.AbstractCollection<E>
          -java.util.AbstractList<E>
               -java.util.AbstractSequentialList<E>
                    -java.util.LinkedList<E>

实现的接口:List<E>, Deque<E>, Cloneable, Serializable

二.实现方法介绍:
2.1 构造方法
~LinkedList() 默认构造器,创建一个空的list
~LinkedList(Collection<? extends E> c) 创建一个list,里面包含指定集合中的所有元素

2.2 add 插入对象

~void addFirst(E e) 在开头添加元素
~void addLast(E e) 在末尾添加元素
~void add(E element) 在末尾添加指定的元素
~void add(int index, E element) 在指定的索引位置,增加指定的元素
~public boolean addAll(Collection<? extends E> c) 插入集合中的所有对象
~public boolean addAll(int index, Collection<? extends E> c) 在指定位置插入集合中的对象

源码分析:

 public boolean add(E e) {
       linkLast(e);
       return true ;
 }

往list末尾添加一个对象

 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++;
    }

获取末尾对象,创建一个新的node对象,node的prev指向末尾元素,如果末尾为空,即这个list中还未添加对象,则将first指向newNode,否则添加到末尾。

LinkedList的add方法不用考虑像arrayList一样进行扩容和复制数据的问题,但是每增加一个数据,都需要创建一个新的Node<E> 对象


2.3 remove 删除对象

~E removeFirst() 删除链表的第一个对象,返回删除的对象
~E removeLast() 删除链表的最后一个对象
~boolean remove(Object o)  删除指定的对象
~E remove(int index) 删除指定位置的对象
~E remove() 调用removeFirst

public boolean remove(Object o) {
          //判断删除的对象是否为null
        if (o == null ) {
            for (Node<E> x = first ; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);
                    return true ;
                }
            }
        } else {
            //循环遍历找到指定的对象
            for (Node<E> x = first ; x != null; x = x.next) {
                if (o.equals(x.item )) {
                    unlink(x);
                    return true ;
                }
            }
        }
        return false ;
    }

E unlink (Node<E> x) {
        // 获取指定对象的属性
        final E element = x.item ;
        final Node<E> next = x.next ;
        final Node<E> prev = x.prev ;
        //判断是否为首元素
        if (prev == null) {
            first = next;
        } else {
            //把x从链表中去掉
            prev. next = next;
            x. prev = null;
        }

        if (next == null) {
            last = prev;
        } else {
            next. prev = prev;
            x. next = null;
        }
        //x的属性都赋值为空,让GC处理掉
        x. item = null;
        size--;
        modCount++;
        return element;
    }

LinkedList删除元素比ArrayList简单很多,毕竟ArrayList将当前元素所在位置后的元素通过复制往前移动一位

2.4 get 获取对象

~E get(int index) 获取指定位置的元素
~E getFirst() 获取首元素
~E getLast() 获取末尾元素

源码分析:
  public E get (int index) {
         //入参检验
        checkElementIndex(index);
        return node(index).item ;
    }
 Node<E> node (int index) {
         // 判断index在列表的前半部 还是 后半部,根据结果从表首开始遍历,还是从表尾开始遍历
        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x. next;
            return x;
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x. prev;
            return x;
        }
    }

LinkedList的元素是存放到链表里面的,所以get操作相对ArrayList来说要复杂一些

2.5 contains 判断集合中是否存在这个元素

~boolean contains(Object o) 

三.LinkedList总结

~jdk1.7 中的linkedList采用单向链表的方式实现

~LinkedList在插入元素的时候需要创建一个新的node对象,在查找元素的时候需要遍历链表,在删除元素的时候,要遍历链表,找到指定的元素进行删除

~LinkedList是非线程安全的


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值