java用linkedlist编写学生类_Java容器类研究5:LinkedList

本文探讨了Java中的LinkedList作为队列和双端队列的使用,它通过内部的双向链表结构实现。LinkedList的访问操作由于需要遍历,效率较低。此外,还详细解析了LinkedList的ListIterator实现和Spliterator的分割策略,其中Spliterator在分裂时会尝试将链表元素转换为数组并采用非均衡的分裂策略,以提高性能。
摘要由CSDN通过智能技术生成

java.util.LinkedList

Java中有现成的队列可以用吗

有,就是LinkedList。LinkedList实现的接口如下,其实也可以当做stack使用:

public class LinkedList

extends AbstractSequentialList

implements List, Deque, Cloneable, java.io.Serializable

Deque是一个双端队列的接口,而Deque又继承了接口Queue。所以LinkedList可以作为队列、双端队列来使用。

AbstractSequentialList提供了顺序访问的方法,当然,大部分方法都依赖于ListIterator来实现,所以将锅甩给了子类。

LinkedList用什么结构来实现

同样很简单,是一个Node的双向链表结构。

private static class Node {

E item;

Node next;

Node prev;

Node(Node prev, E element, Node next) {

this.item = element;

this.next = next;

this.prev = prev;

}

}

有属性first和last记录着链表的开始和结束节点。

在链表中通过下标取值是低效的

在LinkedList中,大量的方法需要先获得指定下标的节点,具体实现如下:

Node node(int index) {

// assert isElementIndex(index);

if (index < (size >> 1)) {

Node x = first;

for (int i = 0; i < index; i++)

x = x.next;

return x;

} else {

Node x = last;

for (int i = size - 1; i > index; i--)

x = x.prev;

return x;

}

}

可以看出,开发者已经尽力优化,根据index大小决定从何处开始遍历。

LinkedList实现了自己的ListIterator

遍历方法利用了链表结构的特性,进行遍历。其中有如下属性记录遍历状态。

private Node lastReturned; //记录最近一次返回的节点

private Node next; //记录下一个要返回的节点

private int nextIndex; //记录下一个要返回的位置

private int expectedModCount = modCount; //记录期望的修改次数

LinkedList的Spliterator采用什么样的分割策略

LinkedList每次划分,不是采用的1/2策略,而是每次分裂出来的一块数据都增加一个BATCH_UNIT(1024)的大小。比较有趣的是,每次分裂出来的Spliterator并不是LinkedList自己实现的Spliterator,而是一个ArraySpliterator,ArraySpliterator采用的是1/2的分裂策略。所以LinkedList每次分裂都想尽可能快的分裂出更多的元素,并且分裂过程中将链表结构转化为数组结构,这样做可能是出于性能的考虑,具体什么原因还是比较纳闷的。

//该方法位于class LLSpliterator中

public Spliterator trySplit() {

Node p;

int s = getEst();

if (s > 1 && (p = current) != null) {

int n = batch + BATCH_UNIT;

if (n > s)

n = s;

if (n > MAX_BATCH)

n = MAX_BATCH;

//copy到数组中

Object[] a = new Object[n];

int j = 0;

do { a[j++] = p.item; } while ((p = p.next) != null && j < n);

current = p;

batch = j;

est = s - j;

//这里返回的不是LLSpliterator,其实是ArraySpliterator

return Spliterators.spliterator(a, 0, j, Spliterator.ORDERED);

}

return null;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值