linklist在java_java集合类学习笔记之LinkList

1、简述

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

进行关联引用

2、实现

a、构造方法:

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

/*** Constructs an empty list.*/

publicLinkedList() {

}/*** Constructs a list containing the elements of the specified

* collection, in the order they are returned by the collection's

* iterator.

*

*@paramc the collection whose elements are to be placed into this list

*@throwsNullPointerException 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 Nodefirst;/*** Pointer to last node.

* Invariant: (first == null && last == null) ||

* (last.next == null && last.item != null)*/

transient Node last;

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

3、LinkList操作

增加操作:

add(E e):

/*** Appends the specified element to the end of this list.

*

*

This method is equivalent to {@link#addLast}.

*

*@parame element to be appended to this list

*@return{@codetrue} (as specified by {@linkCollection#add})*/

public booleanadd(E e) {

linkLast(e);return true;

}/*** Links e as last element.*/

voidlinkLast(E e) {final Node l =last;final Node newNode = new Node<>(l, e, null);

last=newNode;if (l == null)

first=newNode;elsel.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).

*

*@paramindex index at which the specified element is to be inserted

*@paramelement element to be inserted

*@throwsIndexOutOfBoundsException {@inheritDoc}*/

public void add(intindex, E element) {

checkPositionIndex(index);if (index ==size)

linkLast(element);elselinkBefore(element, node(index));

}/*** Inserts element e before non-null Node succ.*/

void linkBefore(E e, Nodesucc) {//assert succ != null;

final Node pred =succ.prev;final Node newNode = new Node<>(pred, e, succ);

succ.prev=newNode;if (pred == null)

first=newNode;elsepred.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中的元素是只能通过一个个的去遍历,这样也就导致了它的读取效率低

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值