[Java][集合][List系列][LinkedList]

继承关系

java.util
类 LinkedList

java.lang.Object
继承者 java.util.AbstractCollection
继承者 java.util.AbstractList
继承者 java.util.AbstractSequentialList
继承者 java.util.LinkedList

所有已实现的接口:
Serializable, Cloneable, Iterable, Collection, Deque, List, Queue

源码分析

LinkedList实际上是通过双向链表去实现的。
获取元素方法get()方法直接调用node(int index)方法。
(实际原理非常简单,它就是通过一个计数索引值来实现的。例如,当我们调用get(int location)时,首先会比较“location”和“双向链表长度的1/2”;若前者大,则从链表头开始往后查找,直到location位置;否则,从链表末尾开始先前查找,直到location位置。)
因此,访问效率上,根据索引的随机访问很慢,顺序访问效率高。当然,本身就是适用于链表场景。
* 所以,千万不要用链表来做随机访问元素的事,除非特例,否则一定是你用错数据结构了*
/**
* Returns the (non-null) Node at the specified element index.
*/
Node node(int index){

    if (index < (size >> 1)) {
        Node<E> x = first;
        for (int i = 0; i < index; i++)
            x = x.next; //不断替换链表的下一个节点引用,即链表挨个查找下去,直到index位置
        return x;
    } else {
        Node<E> x = last;
        for (int i = size - 1; i > index; i--)
            x = x.prev;//同理
        return x;
    }

}

遍历

1、Iterator
2、fori
慎用,效率低,玩死你的cpu
3、foreach
4、从API获得元素节点对象,沿链表挨个循环调用访问
如:
while(list.pollFirst() != null){
;
}

多线程访问

如果多个线程同时访问一个链接列表,有两种方式:
1、自己实现同步操作,保证读写列表的操作是同步的
2、使用 Collections.synchronizedList 方法来“包装”该列表
List list = Collections.synchronizedList(new LinkedList(…));
所谓包装,很贴切,就是用修饰模式,加了个壳,所有list方法变成同步操作
static List synchronizedList(List list, Object mutex) {
return (list instanceof RandomAccess ?
new SynchronizedRandomAccessList<>(list, mutex) :
new SynchronizedList<>(list, mutex));
}

static class SynchronizedList
extends SynchronizedCollection
implements List {
final List list;
SynchronizedList(List list) {
super(list);
this.list = list;
}
public E get(int index) {
synchronized (mutex) {return list.get(index);}
}
public E set(int index, E element) {
synchronized (mutex) {return list.set(index, element);}
}
… …
}

特点小结

(01) LinkedList 实际上是通过双向链表去实现的。
(02) 容量上,增长受限于内存,没有显性限制
(03) LinkedList的克隆函数,即是将全部元素克隆到一个新的LinkedList对象中。
(04) LinkedList实现java.io.Serializable。当写入到输出流时,先写入“容量”,再依次写入“每一个节点保护的值”;当读出输入流时,先读取“容量”,再依次读取“每一个元素”。
(05) 由于LinkedList实现了Deque,而Deque接口定义了在双端队列两端访问元素的方法。提供插入、移除和检查元素的方法。每种方法都存在两种形式:一种形式在操作失败时抛出异常,另一种形式返回一个特殊值(null 或 false,具体取决于操作)。
(06) LinkedList可以作为FIFO(先进先出)的队列,作为FIFO的队列时,下表的方法等价:

队列方法 等效方法
add(e) addLast(e)
offer(e) offerLast(e)
remove() removeFirst()
poll() pollFirst()
element() getFirst()
peek() peekFirst()

(07) LinkedList可以作为LIFO(后进先出)的栈,作为LIFO的栈时,下表的方法等价:

栈方法 等效方法
push(e) addFirst(e)
pop() removeFirst()
peek() peekFirst()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值