阅读并且总结linkedList源码内容 增删改查
-
增--addAll 基于索引将集合中的元素插入到链表某个特定位置的方法
public boolean addAll(int index, Collection<? extends E> c) {
checkPositionIndex(index); //检查指定的索引是不是超过了链表范围
Object[] a = c.toArray(); //将要插入的元素转换为数组
int numNew = a.length; //得到想要插入元素的长度/数量
if (numNew == 0) //没有要添加的元素,返回false
return false;
//如果要插入的是最后一个节点,则该节点的后继节点为null,前驱节点为链表的last,否则找到该索引处的节点及其前驱节点。
Node<E> pred, succ;
if (index == size) {
succ = null;
pred = last;
} else {
succ = node(index); //获取当前索引位置上的node节点
pred = succ.prev; //获取当前节点的前驱节点
}
//遍历要插入的元素数组,将每个元素插到链表里面去
for (Object o : a) {
@SuppressWarnings("unchecked") E e = (E) o;//强制转换?
Node<E> newNode = new Node<>(pred, e, null); //创建新的节点,前驱节点为pred,值为e,后继节点为null
if (pred == null) //如果前驱节点为空,那么它就成为新节点的第一个节点
first = newNode;
else pred.next = newNode; //否则将pred的后继节点指向这个新节点
pred = newNode; //又可以把当前插入的这个节点当作下一个要插入元素的前驱节点
}
if (succ == null) {
last = pred;
} else {
pred.next = succ; // 如果succ为null,也就是新加的节点放在了链表的最后一个节点后面,那么last就指向加入的新节点。
succ.prev = pred;
// 如果succ不为null,也就是新加的节点放在了链表中未被替换的位置进行插入,
那么将新增节点与原链表中断开的两个节点重新链接起来,
即前驱节点pred的next指针指向新增节点,新增节点的prev指针指向前驱节点;
后继节点的prev指针指向新增节点,新增节点的next指针指向后继节点。
}
size += numNew; //将newSize的值累加到size的值中,size表示当前LinkedList中元素的个数
modCount++; //次数+1
return true;}//返回true表示插入成功
}
public boolean remove(Object o) {
if (o == null) { //如果待删除对象为空
for (Node<E> x = first; x != null; x = x.next) { //遍历,查找匹配项
if (x.item == null) { //若当前节点存储的对象也为null
unlink(x); //调用这个方法删掉这个节点
return true; } //返回true表示删除成功
}
} else { //如果删除对象不为null
for (Node<E> x = first; x != null; x = x.next) { //遍历,查找匹配的项
if (o.equals(x.item)) { //找到了
unlink(x); 删除节点
return true; //true删除成功 }
}
}
return false; //失败
}
//set方法用于替换指定位置的元素,参数index为所要替换元素的下标,参数element为替换后的新元素
public E set(int index, E element) {
checkElementIndex(index); //检查待替换元素的下标是否合法
Node<E> x = node(index); //获取当前位置对应节点
E oldVal = x.item; //记录
x.item = element; //替换
return oldVal;
}
//get返回指定位置的元素
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
利用ArrayList模拟栈和队列
栈:
package com.collection.Static_Queue;
/**
* @Author:ZJ-JH
* @Description:
* @DateTime:2023/6/12 20:28
*/
import java.util.NoSuchElementException;
/**
* - push: 将元素压入栈顶
* - pop: 弹出栈顶元素
* - peek: 获取栈顶元素,不弹出
* - isEmpty: 判断栈是否为空
*/
public class Stack {
private Object[] array; // 栈的元素存储在数组中
private int capacity; // 栈的最大容量
private int top; // 栈顶元素所在位置的下标
public Stack(int capacity) {
this.capacity = capacity;
this.array = new Object[capacity];
this.top = -1; // 初始化时栈为空
}
/**
* 将元素压入栈顶
*/
public void push(Object element) {
if (top + 1 >= capacity) {
throw new IndexOutOfBoundsException("栈已满");
}
array[++top] = element; // 将元素放置到栈顶
}
/**
* 弹出栈顶元素
*/
public Object pop() {
if (isEmpty()) {
throw new NoSuchElementException("栈为空");
}
return array[top--]; // 返回并删除栈顶元素
}
/**
* 获取栈顶元素,不弹出
*/
public Object peek() {
if (isEmpty()) {
throw new NoSuchElementException("栈为空");
}
return array[top]; // 返回栈顶元素,不删除
}
/**
* 判断栈是否为空
*/
public boolean isEmpty() {
return top == -1; // 栈为空时栈顶下标为-1
}
}
队列
package com.collection.Static_Queue;
/**
* @Author:ZJ-JH
* @Description:
* @DateTime:2023/6/12 20:27
*/public class Queue {
private int front; // 队头指针
private int rear; // 队尾指针
private int maxSize; // 队列最大长度
private Object[] queueArray; // 数据存储数组
/**
* 构造函数,初始化队头、队尾指针和数据存储数组
*/
public Queue(int size) {
this.maxSize = size;
this.queueArray = new Object[maxSize];
this.front = 0;
this.rear = -1;
}
/**
* 插入元素到队末尾
*/
public void insert(Object element) {
if (rear == maxSize - 1) { // 队列已满
System.out.println("Queue is full.");
} else {
queueArray[++rear] = element;
}
}
/**
* 移除队头元素并返回该元素
*/
public Object remove() {
if (front > rear) { // 队列为空
System.out.println("Queue is empty.");
return null; } else {
return queueArray[front++];
}
}
/**
* 获取队头元素
*/
public Object peek() {
if (front > rear) { // 队列为空
System.out.println("Queue is empty.");
return null; } else {
return queueArray[front];
}
}
/**
* 判空
*/
public boolean isEmpty() {
return (front > rear);
}
/**
* 获取队列长度
*/
public int getSize() {
return (rear - front + 1);
}
}