前言

之前的内容中,我们分析总结了List集合及实现类ArrayList源码,并对数组扩容原理进行深度解析。本节内容主要学习总结接口List的另一个重要实现类LinkedList。先看一下LinkedList的UML类图:

  • LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。
  • LinkedList 实现 List 接口,能对它进行队列操作。

LinkedList是一个实现了List接口和Deque接口的双端链表。

LinkedList底层的链表结构使它支持高效的插入和删除操作,另外它实现了Deque接口,使得LinkedList类也具有队列的特性。

LinkedList不是线程安全的,如果想使LinkedList变成线程安全的,可以调用静态类Collections类中的synchronizedList方法:

List<Object> linkedList = Collections.synchronizedList(new LinkedList<>());

LinkedList类的内部结构分析

来看一下LinkedList类的内部私有类Node:

    private static class Node<E> {// 节点E item;// 后继节点Node<E> next;// 前驱节点Node<E> prev;Node(Node<E> prev, E element, Node<E> next) {this.item = element;this.next = next;this.prev = prev;}}

这个类就代表双端链表的节点Node,有三个属性:前驱节点、本节点值、后继节点。


LinedList类Demo

【1】无参构造方法

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

【2】按照集合的迭代器返回的顺序构造一个包含指定集合元素的列表。

public LinkedList(Collection<? extends E> c) {this();addAll(c);
}

举个栗子:

package com.hl.magic.items.day11.collection.list;import org.junit.Before;
import org.junit.Test;import java.util.Iterator;
import java.util.LinkedList;/*** 链表LinkedList* List接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括 null)。* 除了实现 List 接口外,LinkedList类还为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。* 这些操作允许将链接列表用作堆栈、队列或双端队列。* <p>* 链表LinkedList实现 Deque 接口,为 add、poll 提供先进先出队列操作,以及其他堆栈和双端队列操作。* <p>* <p>* 【1】LinkedList特点* 线程不同步,线程不安全* 增删的速度快,查询的速度慢* <p>* 【3】LinkedList集合存储的数据结构是链表结构,提供了大量的首尾操作的方法。* void addFirst(E e);* void addLast(E e);* * E   getFirst();* E  getLast();* * E removeFirst();* E   removeLast();** @author administrator* @date 2020/09/25 15:13*/
public class LinkedListBaseTest {private LinkedList<Integer> linkedList;/*** LinkedList的基本操作*/@Beforepublic void test_before() {linkedList = new LinkedList<>();// 添加元素到链表开头linkedList.addFirst(0);// 添加元素到链表开头linkedList.add(1);// 将元素添加在指定索引位置处linkedList.add(2, 2);// 添加元素到链表末尾linkedList.addLast(3);System.out.println("-----------------------------------------");System.out.println("LinkedList(直接输出的): " + linkedList);}@Testpublic void test_LinkedList() {System.out.println("-----------------------------------------");// 返回此列表的第一个元素System.out.println("getFirst()获得第一个元素: " + linkedList.getFirst());// 返回此列表的最后一个元素System.out.println("getLast()获得第最后一个元素: " + linkedList.getLast());// 移除并返回此列表的第一个元素System.out.println("removeFirst()删除第一个元素并返回该元素: " + linkedList.removeFirst());// 移除并返回此列表的最后一个元素System.out.println("removeLast()删除最后一个元素并返回该元素: " + linkedList.removeLast());System.out.println("After remove:" + linkedList);// 判断此列表包含指定元素,如果是,则返回trueSystem.out.println("contains()方法判断列表是否包含1这个元素:" + linkedList.contains(1));// 返回此列表的元素个数System.out.println("该linkedList的大小 : " + linkedList.size());System.out.println("-----------------------------------------");}/*** 位置访问操作*/@Testpublic void test_set() {System.out.println("-----------------------------------------");// 将此列表中指定位置的元素替换为指定的元素linkedList.set(1, 3);System.out.println("After set(1, 3):" + linkedList);// 返回此列表中指定位置处的元素System.out.println("get(1)获得指定位置(这里为1)的元素: " + linkedList.get(1));System.out.println("-----------------------------------------");}/*** search位置访问操作*/@Testpublic void test_search(){System.out.println("-----------------------------------------");linkedList.add(3);System.out.println("After add(3):" + linkedList);// 返回此列表中首次出现的指定元素的索引System.out.println("indexOf(3): " + linkedList.indexOf(3));// 返回此列表中最后出现的指定元素的索引System.out.println("lastIndexOf(3): " + linkedList.lastIndexOf(3));System.out.println("-----------------------------------------");}/*** Queue操作*/@Testpublic void test_queue(){System.out.println("-----------------------------------------");// 获取但不移除此列表的头System.out.println("peek(): " + linkedList.peek());// 获取但不移除此列表的头System.out.println("element(): " + linkedList.element());// 获取并移除此列表的头Integer poll = linkedList.poll();System.out.println("poll element: " + poll);System.out.println("After poll():" + linkedList);// 获取并移除此列表的头linkedList.remove();System.out.println("After remove():" + linkedList);// 将指定元素添加到此列表的末尾linkedList.offer(4);System.out.println("After offer(4):" + linkedList);System.out.println("-----------------------------------------");}/*** Deque操作*/@Testpublic void test_deque() {System.out.println("-----------------------------------------");// 在此列表的开头插入指定的元素linkedList.offerFirst(2);System.out.println("After offerFirst(2):" + linkedList);// 在此列表末尾插入指定的元素linkedList.offerLast(5);System.out.println("After offerLast(5):" + linkedList);// 获取但不移除此列表的第一个元素System.out.println("peekFirst(): " + linkedList.peekFirst());// 获取但不移除此列表的第一个元素System.out.println("peekLast(): " + linkedList.peekLast());// 获取并移除此列表的第一个元素linkedList.pollFirst();System.out.println("After pollFirst():" + linkedList);// 获取并移除此列表的最后一个元素linkedList.pollLast();System.out.println("After pollLast():" + linkedList);// 将元素推入此列表所表示的堆栈(插入到列表的头)linkedList.push(2);System.out.println("After push(2):" + linkedList);// 从此列表所表示的堆栈处弹出一个元素(获取并移除列表第一个元素)linkedList.pop();System.out.println("After pop():" + linkedList);linkedList.add(3);// 从此列表中移除第一次出现的指定元素(从头部到尾部遍历列表)linkedList.removeFirstOccurrence(3);System.out.println("After removeFirstOccurrence(3):" + linkedList);// 从此列表中移除最后一次出现的指定元素(从尾部到头部遍历列表)linkedList.removeLastOccurrence(3);System.out.println("After removeFirstOccurrence(3):" + linkedList);System.out.println("-----------------------------------------");}@Testpublic void test_for(){System.out.println("-----------------------------------------");linkedList.clear();for (int i = 0; i < 100000; i++) {linkedList.add(i);}// iterator迭代器遍历long start = System.currentTimeMillis();Iterator<Integer> iterator = linkedList.iterator();while (iterator.hasNext()) {iterator.next();}long end = System.currentTimeMillis();System.out.println("Iterator:" + (end - start) + " ms");// 顺序遍历(随机遍历)start = System.currentTimeMillis();for (int i = 0; i < linkedList.size(); i++) {linkedList.get(i);}end = System.currentTimeMillis();System.out.println("for:" + (end - start) + " ms");// 另一种增强for循环遍历start = System.currentTimeMillis();for (Integer i : linkedList);end = System.currentTimeMillis();System.out.println("foreach:" + (end - start) + " ms");// 通过pollFirst()或pollLast()来遍历LinkedListLinkedList<Integer> temp1 = new LinkedList<>();temp1.addAll(linkedList);start = System.currentTimeMillis();while (temp1.size() != 0) {temp1.pollFirst();}end = System.currentTimeMillis();System.out.println("pollFirst()或pollLast():" + (end - start) + " ms");// 通过removeFirst()或removeLast()来遍历LinkedListLinkedList<Integer> temp2 = new LinkedList<>();temp2.addAll(linkedList);start = System.currentTimeMillis();while (temp2.size() != 0) {temp2.removeFirst();}end = System.currentTimeMillis();System.out.println("removeFirst()或removeLast():" + (end - start) + " ms");System.out.println("-----------------------------------------");}
}

关于LinkedList相关推荐

  1. 什么是LinkedList?什么时候使用它呢?Java LinkedList结构、用法及源码解析

    前言:我们学习java时都知道ArrayList实现List接口,LinkedList也实现List接口,但我们平时用的时候LinkedList却很少被用到.那么,LinkedList什么时候该用到呢 ...

  2. 比较ArrayList、LinkedList、Vector

    翻译人员: 铁锚 翻译时间: 2013年12月2日 原文链接: ArrayList vs. LinkedList vs. Vector 1. List概述 List,就如图名字所示一样,是元素的有序列 ...

  3. java arraylist和list_Java中ArrayList和LinkedList区别

    原文链接:http://pengcqu.iteye.com/blog/502676 一般大家都知道ArrayList和LinkedList的大致区别: 1.ArrayList是实现了基于动态数组的数据 ...

  4. java链表list_java集合之linkedList链表基础

    LinkedList链表: List接口的链接列表实现.允许存储所有元素(包含null).使用频繁增删元素. linkedList方法: void addFirst(E e) 指定元素插入列表的开头 ...

  5. 【java】兴唐第二十一节(LinkedList和泛型)

    LinkedList知识点 1.实现了Iterable接口的类具有迭代功能. 2.List接口为Collection的子类,表示线形数据列表,其实现类有:ArrayList(数组线性表)与Linked ...

  6. arraylist 后往前遍历_面试官:谈谈常用的Arraylist和Linkedlist的区别

    Arraylist:底层是基于动态数组,根据下表随机访问数组元素的效率高,向数组尾部添加元素的效率高:但是,删除数组中的数据以及向数组中间添加数据效率低,因为需要移动数组. 例如最坏的情况是删除第一个 ...

  7. Java编程的逻辑 (39) - 剖析LinkedList

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...

  8. ArrayList与LinkedList区别

    1.ArrayList实现了基于动态数组的数据结构,LinkedList是实现了基于链表的数据结构. 2.对于随机访问get/set,ArrayList优于LinkedList,因为LinkedLis ...

  9. 某团技术拷问:ArrayList 和 LinkedList 哪个更占空间?

    HR力荐了一个工作 4 年,目前年薪 40W+ 的候选人. 看他简历,从 JVM.MySQL.Redis,再到悲观锁.乐观锁一个都不缺,并发编程.分布式也都接触过,像是个实力派! 着急用人,就赶紧叫人 ...

  10. 从面试角度分析LinkedList源码

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 注:本系列文章中用到的jdk版本均为java8 Linke ...

最新文章

  1. 在Ubuntu 14.04 64bit上安装百度云Linux客户端BCloud
  2. linux下单节点oracle数据库间ogg搭建
  3. python dict 字典 清空
  4. [YTU]_2877(结构体---职工信息结构体)
  5. Nginx反代Mogilefs分布式储存示例
  6. d3.js 共享交换平台demo
  7. Too Many Segments (hard version) CodeForces - 1249D2(贪心+容器vector+set)
  8. 编译hotspot_从Hotspot JIT编译器打印生成的汇编代码
  9. React Native 实现物流进度信息
  10. 吴恩达获英特尔投资!这次,英特尔拿出7.85亿砸向AI创业公司
  11. hdu 1213 “How Many Tables”(并查集基本到优化)
  12. express 内存溢出问题分析定位
  13. java onfocus_[Java教程]onfocus和onblur应用代码实例
  14. Intriguing properties of neural networks——L-BFGS attack
  15. 洛克菲勒家族是如何发家的,我们都看看
  16. Explain是什么?Explain能干嘛?
  17. happy hacking keybord(hhkb pro)键盘 翻新真假判别(realforce键盘也一样)
  18. JS买卖股票的时机含手续费 LeetCode714
  19. 2020神舟几号发射_中国宇宙飞船发射到神州几号了
  20. 【Web技术】919- 前端关于单点登录的知识

热门文章

  1. iphone4水滴壁纸_如何为您的iPhone制作好的动态壁纸
  2. Could not read from boot medium. System halted.
  3. 毕业新生找工作面试有哪些需要注意?
  4. Sonar问题:String literals should not be duplicated
  5. 4G网速10倍于3G?内行人笑而不语
  6. 计算机术语写祝福语,祝福词语大全
  7. pynq、Linux下的EDUP无线网卡联wifi配置、嵌入式Linux上没有wlan0
  8. origin绘图软件中文版下载和安装教程
  9. 仿斗鱼滑动拼图验证码控件
  10. 25岁的年轻人,要想清两件事