LinkedList源码分析

成员变量

private transient Entry<E> header = new Entry<E>(null, null, null);
链表头元素

private transient int size = 0;
链表大小

构造方法

public LinkedList() {
		header.next = header.previous = header;
	}
无参构造。初始化链表头,将其next、previoous都指向其自身。

public LinkedList(Collection<? extends E> c) {
		this();
		addAll(c);
	}
该构造首先调用无参构造,然后将Collection中的元素加入到集合中。

方法

getFirst

public E getFirst() {
		if (size == 0)
			throw new NoSuchElementException();

		return header.next.element;
	}
返回链表中的第一个元素

getLast

public E getLast() {
		if (size == 0)
			throw new NoSuchElementException();

		return header.previous.element;
	}
返回链表中最后一个元素,由于其内部实现是双向链表,故直接调用header.previous.element即可。

removeFirst

public E removeFirst() {
		return remove(header.next);
	}
删除链表中的第一个元素,并返回其值,具体实现参见remove方法

removeLast

public E removeLast() {
		return remove(header.previous);
	}
删除链表中最后一个元素,并返回其值

addFirst

public void addFirst(E e) {
		addBefore(e, header.next);
	}
在链表头部插入一个元素

addLast

public void addLast(E e) {
		addBefore(e, header);
	}
在链表添加尾部插入一个元素

contains

public boolean contains(Object o) {
		return indexOf(o) != -1;
	}
检查是否包含指定元素

size

public int size() {
		return size;
	}
返回链表中元素的个数

add

public boolean add(E e) {
		addBefore(e, header);
		return true;
	}
在链表尾部加入一个元素
public void add(int index, E element) {
		addBefore(element, (index == size ? header : entry(index)));
	}
在某个位置加入元素

remove

public boolean remove(Object o) {
		if (o == null) {
			for (Entry<E> e = header.next; e != header; e = e.next) {
				if (e.element == null) {
					remove(e);
					return true;
				}
			}
		} else {
			for (Entry<E> e = header.next; e != header; e = e.next) {
				if (o.equals(e.element)) {
					remove(e);
					return true;
				}
			}
		}
		return false;
	}
删除某个元素,首先判断元素是否为null,然后进行相关的查找。

public E remove(int index) {
		return remove(entry(index));
	}
删除某一位置的元素

addAll

public boolean addAll(Collection<? extends E> c) {
		return addAll(size, c);
	}
将集合添加到链表的尾部
public boolean addAll(int index, Collection<? extends E> c) {
		if (index < 0 || index > size) //边界范围校验
			throw new IndexOutOfBoundsException("Index: " + index + ", Size: "
					+ size);
		Object[] a = c.toArray(); //将集合转化成数组
		int numNew = a.length; //数组的长度
		if (numNew == 0)
			return false; //空集合则不用添加
		modCount++;  //结构变动变量自增

		Entry<E> successor = (index == size ? header : entry(index)); //确定集合元素添加到哪个元素之前,记为E
		Entry<E> predecessor = successor.previous; //保存E的前一个元素
		for (int i = 0; i < numNew; i++) { //循环要加入到链表的集合,
			Entry<E> e = new Entry<E>((E) a[i], successor, predecessor); //构建元素并将其next和previous分别指向E、E.previous。
			predecessor.next = e; //将E.previous的next指向新节点,这样新节点就会插入到链表中。仔细考虑此处并没有立即将successor的previous指向新节点,而是在整个循环结束之后才处理。
			predecessor = e; //将新构建的元素赋值给predecessor,即E.previous为新插入的节点,如此反复最终将这些集合元素添加到链表中
		}
		successor.previous = predecessor; //修复E的previous指向

		size += numNew; //链表大小调整
		return true;
	}
将集合中的元素添加到链表指定位置,方法具体解释见代码后的注释。

clear

public void clear() {
		Entry<E> e = header.next;
		while (e != header) {
			Entry<E> next = e.next;
			e.next = e.previous = null;
			e.element = null;
			e = next;
		}
		header.next = header.previous = header;
		size = 0;
		modCount++;
	}
清空链表

get

public E get(int index) {
		return entry(index).element;
	}
返回某个位置的值

set

public E set(int index, E element) {
		Entry<E> e = entry(index);
		E oldVal = e.element;
		e.element = element;
		return oldVal;
	}
设置某个位置的值

indexOf

public int indexOf(Object o) {
		int index = 0;
		if (o == null) {
			for (Entry e = header.next; e != header; e = e.next) {
				if (e.element == null)
					return index;
				index++;
			}
		} else {
			for (Entry e = header.next; e != header; e = e.next) {
				if (o.equals(e.element))
					return index;
				index++;
			}
		}
		return -1;
	}
返回某个元素在链表中首次出现的位置,未找到则返回-1

lastIndexOf

public int lastIndexOf(Object o) {
		int index = size;
		if (o == null) {
			for (Entry e = header.previous; e != header; e = e.previous) {
				index--;
				if (e.element == null)
					return index;
			}
		} else {
			for (Entry e = header.previous; e != header; e = e.previous) {
				index--;
				if (o.equals(e.element))
					return index;
			}
		}
		return -1;
	}
返回某个元素在链表中最后出现的位置,未找到则返回-1

peek

public E peek() {
		if (size == 0)
			return null;
		return getFirst();
	}
返回链表中的第一元素

element

public E element() {
		return getFirst();
	}
返回链表中的第一个元素,该方法同上面的peek方法的区别在于当链表为空时,peek返回为null,而element方法抛出NoSuchElementException异常

poll

public E poll() {
		if (size == 0)
			return null;
		return removeFirst();
	}
返回链表中的第一个元素,并将其在链表中移除,当链表为空时返回null

remove

public E remove() {
		return removeFirst();
	}
返回链表中的第一个元素,并将其从链表中移除,当链表为空时抛出NoSuchElementException异常

offer

public boolean offer(E e) {
		return add(e);
	}
在链表的尾部加入元素

offerFirst

public boolean offerFirst(E e) {
		addFirst(e);
		return true;
	}
在链表的头部加入元素

offerLast

public boolean offerLast(E e) {
		addLast(e);
		return true;
	}
在链表的尾部加入元素

peekFirst

public E peekFirst() {
		if (size == 0)
			return null;
		return getFirst();
	}
返回链表第一个元素,当链表为空时返回null

peekLast

public E peekLast() {
		if (size == 0)
			return null;
		return getLast();
	}
返回链表的最后一个元素,当链表为空时返回null

entry

private Entry<E> entry(int index) {
		if (index < 0 || index >= size)
			throw new IndexOutOfBoundsException("Index: " + index + ", Size: "
					+ size);
		Entry<E> e = header;
		if (index < (size >> 1)) {
			for (int i = 0; i <= index; i++)
				e = e.next;
		} else {
			for (int i = size; i > index; i--)
				e = e.previous;
		}
		return e;
	}
该方法为私有方法,返回某个位置的元素




资源下载链接为: https://pan.quark.cn/s/d0b0340d5318 在当今数字化时代,FPGA(现场可编程门阵列)凭借其高度灵活性和卓越性能,在电子设计领域占据着举足轻重的地位。它能够使设计者根据自身需求对硬件逻辑进行定制,因而在通信、图像处理、嵌入式系统、数据中心等多个领域得到了广泛应用。本压缩包内提供的学习资料全面覆盖了FPGA的基础知识和实践应用,对于无论是初入此领域的学习者还是希望进一步提升技能的进阶者来说,都是一份极具价值的学习资源。 VHDL硬件描述语言:VHDL(超高速集成电路硬件描述语言)是FPGA设计中极为重要的高级语言之一。它不仅可以用来描述复杂的数字逻辑系统,还能用于系统仿真和综合。《VHDL硬件描述语言与数字逻辑电路设计》这本书将帮助读者深入了解VHDL的基本语法、数据类型、运算符、进程语句、结构体等核心概念,并通过大量实例讲解如何运用VHDL来描述和实现各种数字逻辑电路。 VHDL语言100例详解:实践是掌握知识的关键。《VHDL语言100例详解》通过丰富的代码示例,从基础的逻辑门到复杂的数字系统设计(如计数器、寄存器、移位寄存器、加法器、比较器、编码器、解码器、多路选择器、状态机等)进行了全面覆盖。书中对每个例子的设计思路和工作原理都进行了详细解释,旨在帮助读者巩固理论知识并提升实际编程能力。 深入浅出玩转FPGA:这本书的目标是帮助读者轻松掌握FPGA的实战技能。它详细介绍了FPGA的基本架构,包括可配置逻辑块(CLB)、输入/输出块(IOB)、块存储器(BRAM)等;阐述了FPGA设计流程,如原理图输入、VHDL/Verilog编程、逻辑综合、布局布线、下载验证等;还提供了FPGA在实际项目中的应用案例,如信号处理、图像处理、协议接口设计等。 通过学习这三本书,你将能够: 熟练掌握VHDL语言的基本语法和设计技巧; 深入
资源下载链接为: https://pan.quark.cn/s/dab15056c6a5 IntelliJ IDEA 使用指南 IntelliJ IDEA 是一款由 JetBrains 公司开发的知名 Java 集成开发环境(IDE),凭借其智能代码补全、高效代码导航和强大的调试工具,深受开发者青睐。本中文文档专为初学者设计,旨在帮助他们快速掌握 IntelliJ IDEA 的基础操作与高级功能。 启动 IntelliJ IDEA 后,用户将看到包含菜单栏、工具栏、项目视图、结构视图、编辑区及底部运行/调试控制台的主界面。熟悉这些区域的功能对日常开发至关重要。用户可通过“File”>“Settings”(Windows/Linux)或“IntelliJ IDEA”>“Preferences”(Mac)自定义 IDE 配置,如键盘快捷键、代码风格和字体大小等。 创建新项目:通过“File”>“New”>“Project”,选择项目类型及构建工具(如 Maven 或 Gradle),并按向导完成设置。 导入现有项目:选择“File”>“Open”,找到项目目录,IDE 将自动识别项目结构并加载配置。 智能补全:编写代码时,IDE 会根据上下文提供实时的类、方法或变量补全建议。 格式化代码:通过“Code”>“Reformat Code”,可自动调整代码格式,使其符合设定规范。 Git 集成:IDE 内置 Git 支持,可在 IDE 内完成添加、提交、推送等操作。 其他版本控制系统:还支持 SVN、Mercurial 等,便于团队协作。 调试器:功能强大,支持断点、步进执行、查看变量值等,助力开发者定位和修复问题。 单元测试:集成 JUnit 等测试框架,支持编写和运行单元测试,保障代码质量。 在“Settings”>“Plugins”中,用户可搜索并安装各类插件,如 Lombo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值