容器-LinkedList
LinkedList
LinkedList的概述
LinkedList的底层使用双向链表实现。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YFvfuWIM-1681288911283)(E:\Java笔记\javaSE\集合(容器)(9)\集合\LinkedList.assets\image-20230406115511053.png)]](https://img-blog.csdnimg.cn/dce5ec55cd2442819cc502135833a5f9.png)
链表是一种线性数据结构,其中每个元素都是一个单独的对象,包含一个指向列表中下一个节点的引用。
它可以用于实现各种抽象数据类型,例如列表、堆栈、队列等。
LinkedList的优缺点
优点
- 插入和删除操作的时间复杂度为O(1),相比于数组的O(n)更加高效。
- 链表的大小可以动态调整,不像数组需要预先分配空间。
- 链表的节点可以在内存中部连续存储,因此可以更加的灵活的利用内存空间。
缺点
- 访问元素的时间复杂度为O(n),相比于数组的O(1)较低效。
- 链表需要额外的空间来存储指向下一个节点的指针,因此占用的空间比数组更大。
- 链表的随机访问效率比较低,因为需要从头开始遍历链表才能找到指定位置的节点。
LinkedList的创建方式
LinkedList linkedList = new LinkedList();
//向上转型
List linkedLists = new LinkedList();
常用方法,以及源码分析
| 方法 | 返回类型 | 解释 |
|---|---|---|
| add(E e) | boolean | 将指定元素添加到此列表的结尾 |
| add(int index, E element) | void | 将此列表中指定的位置插入指定的元素 |
| addFirst(E e) | void | 将指定元素插入此列表的开头 |
| addLast(E e) | void | 将指定元素添加到此列表的结尾 |
| clear() | void | 从此列表中移除所有元素 |
| get(int index) | E | 返回此列表中指定位置处的元素 |
| getFirst() | E | 返回此列表的第一个元素 |
| remove() | E | 获取并移除此列表的头(第一个元素) |
| remove(int index) | E | 移除此列表中指定位置的元素 |
| removeFirst() | E | 移除并返回此列表的第一个元素 |
| removelast() | E | 移除并返回此列表的最后一个元素 |
| set(int index,E element) | E | 将此列表中指定位置的元素替换为指定的元素 |
| size() | int | 返回此列表的元素数 |
add(E e)
源码分析:
通过调用 linkLast(E e) 方法将元素添加到链表的末尾。
linkLast(E e) 方法创建一个新的节点,并将其插入到链表的末尾。如果链表为空,则将新节点设置为第一个节点。否则,将新节点链接到最后一个节点。最后,更新链表的大小和 modCount 变量。
public boolean add(E e) {//调用linklast方法将元素添加到链表的尾端linkLast(e);//添加成功,返回truereturn true;}void linkLast(E e) {//获取链表的最后一个节点final Node<E> l = last;//创建最后一个节点,他的前驱节点是l,后去节点为null,数据为efinal Node<E> newNode = new Node<>(l, e, null);//将链表的尾节点指向新节点last = newNode;//判断节点是否为nullif (l == null)//为null则将节点指向新节点first = newNode;else//如果不为null,将原尾节点的后继节点指向新节点l.next = newNode;//聊表的大小加1size++;//修改计数器modCount++;}
案例:
public static void main(String[] args) {LinkedList linkedList = new LinkedList();//添加数据linkedList.add("张三");linkedList.add("李四");//输出此列表System.out.println(linkedList);}
add(int index, E element)
源码分析:
将元素添加到指定位置
public void add(int index, E element) {//检查索引是否越界checkPositionIndex(index);//索引与长度相等if (index == size)//在链表尾部添加数据linkLast(element);else//在指定位置之前添数据linkBefore(element, node(index));}private void checkPositionIndex(int index) {//判断索引是否合法if (!isPositionIndex(index))//不合法则抛出下标越界异常throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}void linkLast(E e) {//获取链表的最后一个节点final Node<E> l = last;//创建一个新的节点,他的前驱节点是l,后去节点为null,数据为efinal Node<E> newNode = new Node<>(l, e, null);//将链表的最后一个节点指向新节点last = newNode;//判断链表是否为nullif (l == null)//将第一个节点指向新节点first = newNode;//如果不为nullelse//将最后一个节点的下一个节点指向新节点l.next = newNode;//链表大小加1size++;//修改计数器加1modCount++;}void linkBefore(E e, Node<E> succ) {//获取指定位置的前一个节点final Node<E> pred = succ.prev;//创建一个新节点final Node<E> newNode = new Node<>(pred, e, succ);//将指定位置的前一个节点的下一个节点指向新节点succ.prev = newNode;//如果指定位置的前一个节点为null,if (pred == null)//将第一个节点指向新节点first = newNode;//如果指定位置的前一个节点不为nullelse//将前一个节点的下一个节点指向新节点pred.next = newNode;//链表大小加1size++;//修改计数器加1modCount++;}
案例:
public static void main(String[] args) {LinkedList linkedList = new LinkedList();linkedList.add("张三");linkedList.add("李四");System.out.println(linkedList);//位置1,添加数据linkedList.add(1,"王五");System.out.println(linkedList);
}
addFirst(E e)
源码分析:
将指定元素插入到此列表的开头
public void addFirst(E e) {// 在链表的头部添加一个新节点linkFirst(e);
}
private void linkFirst(E e) {// 获取头节点final Node> f = first;// 创建一个新节点,它的前驱节点为null,数据为e,后继节点为头节点ffinal Node> newNode = new Node<>(null, e, f);// 将头节点指向新节点first = newNode;// 如果头节点为null,说明if (f == null)//链表为空,将尾节点指向新节点last = newNode;// 否则将头节点的前驱节点指向新节点elsef.prev = newNode;// 链表长度加1size++;// 修改次数加1modCount++;}
案例:
public static void main(String[] args) {LinkedList linkedList = new LinkedList();linkedList.add("张三");linkedList.add("李四");System.out.println(linkedList);linkedList.add(1,"王五");System.out.println(linkedList);//列表开头添加数据linkedList.addFirst("赵六");System.out.println(linkedList);}
addLast(E e)
源码分析:
将指定元素添加到此列表的结尾
public void addLast(E e) {//在链表的尾部添加一个新节点linkLast(e);}
void linkLast(E e) {//获取链表的最后一个节点final Node<E> l = last;//创建一个新的节点,他的前驱节点是l,后去节点为null,数据为efinal Node<E> newNode = new Node<>(l, e, null);//将链表的最后一个节点指向新节点last = newNode;//判断链表是否为nullif (l == null)//将第一个节点指向新节点first = newNode;//如果不为nullelse//将最后一个节点的下一个节点指向新节点l.next = newNode;//链表大小加1size++;//修改计数器加1modCount++;}
案例:
public static void main(String[] args) {LinkedList linkedList = new LinkedList();linkedList.add("张三");linkedList.add("李四");System.out.println(linkedList);linkedList.add(1,"王五");System.out.println(linkedList);linkedList.addFirst("赵六");System.out.println(linkedList);//列表结尾添加数据linkedList.addLast("唐七");System.out.println(linkedList);
}
clear():
源码分析:
从此列表中移除所有元素
public void clear() {// 遍历链表中的每一个节点for (Node<E> x = first; x != null; ) {// 保存当前节点的下一个节点Node<E> next = x.next;// 将当前节点的数据项置为nullx.item = null;// 将当前节点的前驱和后继节点都置为nullx.next = null;x.prev = null;// 将当前节点指向下一个节点x = next;}// 将链表的头节点和尾节点都置为nullfirst = last = null;// 将链表的大小置为0size = 0;// 修改计数器modCount++;
}
案例:
public static void main(String[] args) {LinkedList linkedList = new LinkedList();linkedList.add("张三");linkedList.add("李四");linkedList.add(1,"王五");linkedList.addFirst("赵六");linkedList.addLast("唐七");System.out.println(linkedList);//清除此列表数据linkedList.clear();System.out.println(linkedList);;
}
get(int index)
源码分析:
返回此列表中指定位置处的元素
public E get(int index) {//校验索引是否合法checkElementIndex(index);//返回该索引对应的节点的数据return node(index).item;
}
private void checkPositionIndex(int index) {//判断索引是否合法if (!isPositionIndex(index))//不合法则抛出下标越界异常throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}
Node<E> node(int index) {// 如果要查找的节点在链表的前半部分if (index < (size >> 1)) {// 从头节点开始遍历Node<E> x = first;// 遍历到要查找的节点for (int i = 0; i < index; i++)// 指针指向下一个节点x = x.next;// 返回查找到的节点return x;// 如果要查找的节点在链表的后半部分} else {// 从尾节点开始遍历Node<E> x = last;// 遍历到要查找的节点for (int i = size - 1; i > index; i--)// 指针指向上一个节点 x = x.prev;// 返回查找到的节点return x;}}
案例:
public static void main(String[] args) {LinkedList linkedList = new LinkedList();linkedList.add("张三");linkedList.add("李四");linkedList.add(1,"王五");linkedList.addFirst("赵六");linkedList.addLast("唐七");System.out.println(linkedList);//获取指定位置的数据System.out.println(linkedList.get(2));
}
getFirst()
源码分析:
返回此列表的第一个元素
public E getFirst() {//获取链表的头节点final Node<E> f = first;//如果头节点为nullif (f == null)//抛出NoSuchElementException异常throw new NoSuchElementException();//返回头节点的数据return f.item;
}
案例:
public static void main(String[] args) {LinkedList linkedList = new LinkedList();linkedList.add("张三");linkedList.add("李四");linkedList.add(1,"王五");linkedList.addFirst("赵六"); linkedList.addLast("唐七");System.out.println(linkedList);//获取此列表的第一个节点System.out.println(linkedList.getFirst());}
remove()
源码分析:
获取并移除此里列表的头(第一个元素)
public E remove() {//调用移除第一个元素方法return removeFirst();
}
public E removeFirst() {// 获取链表的头节点final Node<E> f = first;// 如果头节点为空,if (f == null)//抛出NoSuchElementException异常throw new NoSuchElementException();// 返回调用调用unlinkFirst方法删除头节点并返回删除的元素return unlinkFirst(f);
}private E unlinkFirst(Node<E> f) {// assert f == first && f != null;// 获取头节点的元素final E element = f.item;// 获取头节点的下一个节点final Node<E> next = f.next;// 将头节点的元素置为空f.item = null;// 将头节点的下一个节点置为空,以便垃圾回收f.next = null; // help GC// 将链表的头节点指向原头节点的下一个节点first = next;// 如果原头节点的下一个节点为空if (next == null)//将链表的尾节点也置为空last = null;else// 否则将原头节点的下一个节点的前一个节点置为空next.prev = null;// 链表的大小减1size--;// 修改计数器加1modCount++;// 返回删除的元素return element;
}
案例:
public static void main(String[] args) {LinkedList linkedList = new LinkedList();linkedList.add("张三");linkedList.add("李四");linkedList.add(1,"王五");linkedList.addFirst("赵六");linkedList.addLast("唐七");//获取并移除此列表的第一个节点System.out.println(linkedList.remove());//输出此列表的全部数据System.out.println(linkedList);
}
remove(int index)
源码分析:
移除指定列表中的指定位置的元素
//删除指定位置的节点
public E remove(int index) {// 检查索引是否越界checkElementIndex(index);// 删除并返回指定位置的节点return unlink(node(index));
}
// 检查索引是否越界
private void checkElementIndex(int index) {// 如果索引越界if (!isElementIndex(index))//则抛出IndexOutOfBoundsException异常throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
// 删除指定节点
E unlink(Node<E> x) {// 获取节点的值 final E element = x.item;// 获取下一个节点final Node<E> next = x.next;// 获取上一个节点final Node<E> prev = x.prev;// 如果上一个节点为空if (prev == null) {// 将下一个节点设为头节点first = next;} else {// 将上一个节点的下一个节点设为当前节点的下一个节点prev.next = next;// 将当前节点的上一个节点设为空x.prev = null;}// 如果下一个节点为空if (next == null) {// 将上一个节点设为尾节点last = prev;} else {// 将下一个节点的上一个节点设为当前节点的上一个节点next.prev = prev;// 将当前节点的下一个节点设为空x.next = null;}// 将当前节点的值设为空x.item = null;// 链表大小减一size--;// 修改次数加一modCount++;// 返回删除的节点的值return element;
}// 获取指定位置的节点
Node<E> node(int index) {// 如果索引小于链表大小的一半if (index < (size >> 1)) {// 从头节点开始遍历Node<E> x = first;for (int i = 0; i < index; i++)// 遍历到指定位置x = x.next;// 返回指定位置的节点return x;// 如果索引大于等于链表大小的一半} else {// 从尾节点开始遍历Node<E> x = last;for (int i = size - 1; i > index; i--)// 遍历到指定位置x = x.prev;// 返回指定位置的节点return x;}
}
案例:
public static void main(String[] args) {LinkedList linkedList = new LinkedList();linkedList.add("张三");linkedList.add("李四");linkedList.add(1,"王五");linkedList.addFirst("赵六");linkedList.addLast("唐七");//移除此列表的指定位置的节点System.out.println(linkedList.remove(1));//输出此列表的全部数据System.out.println(linkedList);
}
removeFirst()
源码分析:
移除并返回列表的第一个元素
// 删除链表的头节点
public E removeFirst() {// 获取头节点final Node<E> f = first;// 如果头节点为空,if (f == null)//抛出NoSuchElementException异常throw new NoSuchElementException();// 否则,调用unlinkFirst方法删除头节点return unlinkFirst(f);
}private E unlinkFirst(Node<E> f) {// assert f == first && f != null;// 获取头节点的元素final E element = f.item;// 获取头节点的下一个节点final Node<E> next = f.next;// 将头节点的元素置为空f.item = null;// 将头节点的下一个节点置为空,以便垃圾回收f.next = null; // help GC// 将链表的头节点指向原头节点的下一个节点first = next;// 如果原头节点的下一个节点为空if (next == null)//将链表的尾节点也置为空last = null;else// 否则将原头节点的下一个节点的前一个节点置为空next.prev = null;// 链表的大小减1size--;// 修改计数器加1modCount++;// 返回删除的元素return element;
}
案例:
public static void main(String[] args) {LinkedList linkedList = new LinkedList();linkedList.add("张三");linkedList.add("李四");linkedList.add(1,"王五");linkedList.addFirst("赵六");linkedList.addLast("唐七");//移除并返回列表的第一个元素System.out.println(linkedList.removeFirst());//输出此列表的全部数据System.out.println(linkedList);
}
removelast()
源码分析:
移除并返回此列表最后一个元素
// 从链表的尾部删除一个节点
public E removeLast() {// 获取尾节点final Node<E> l = last;// 如果尾节点为空if (l == null)//抛出NoSuchElementException异常throw new NoSuchElementException();// 调用unlinkLast方法删除尾节点return unlinkLast(l);
}
// 删除链表中的一个节点
private E unlinkLast(Node<E> l) {// assert l == last && l != null;// 获取节点的数据final E element = l.item;// 获取节点的前一个节点final Node<E> prev = l.prev;// 将节点的数据置为空l.item = null;// 将节点的前一个节点置为空 l.prev = null; // help GC// 将尾节点指向前一个节点last = prev;// 如果前一个节点为空if (prev == null)// 将头节点置为空first = null;else// 将前一个节点的指针置为空prev.next = null;// 链表大小减1size--;// 修改计数器加1modCount++;// 返回被删除节点的数据return element;
}
案例:
public static void main(String[] args) {LinkedList linkedList = new LinkedList();linkedList.add("张三");linkedList.add("李四");linkedList.add(1,"王五");linkedList.addFirst("赵六");linkedList.addLast("唐七");//移除并返回列表的最后一个元素System.out.println(linkedList.removeLast());//输出此列表的全部数据System.out.println(linkedList);
}
set(int index,E element)
源码分析:
将此列表中指定位置的元素替换为指定的元素
public E set(int index, E element) {//检查索引是否越界checkElementIndex(index);// 获取指定索引的节点Node<E> x = node(index);// 获取原节点的值E oldVal = x.item;// 将指定索引的节点的值设置为新值x.item = element;// 返回原节点的值return oldVal;
}private void checkElementIndex(int index) {// 如果索引越界if (!isElementIndex(index))//抛出IndexOutOfBoundsException异常throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}Node<E> node(int index) {// assert isElementIndex(index);// 如果指定索引小于链表长度的一半,则从头节点开始遍历if (index < (size >> 1)) {Node<E> x = first;for (int i = 0; i < index; i++)x = x.next;return x;// 如果索引大于等于链表长度的一半,则从尾节点开始遍历} else {Node<E> x = last;for (int i = size - 1; i > index; i--)x = x.prev;return x;}}
案例:
public static void main(String[] args) {LinkedList linkedList = new LinkedList();linkedList.add("张三");linkedList.add("李四");linkedList.addFirst("赵六");linkedList.addLast("唐七");System.out.println("原数据:"+linkedList);//指定位置的值替换为指定的元素linkedList.set(2,"小明");System.out.println("修改后的数据:"+linkedList);
}
size()
源码分析:
返回此列表的元素个数
public int size() {//返回链表的长度return size;
}
案例:
public static void main(String[] args) {LinkedList linkedList = new LinkedList();linkedList.add("张三");linkedList.add("李四");linkedList.addFirst("赵六");linkedList.addLast("唐七");System.out.println(linkedList.size());
}
线程安全
LinkedList不是线程安全的,如果需要在多线程环境下使用LinkedList,需要使用Collections.synchronizedList方法将其包装成线程安全的List
List<String> linkedList = new LinkedList<>();
List<String> synchronizedList = Collections.synchronizedList(linkedList);
观众老爷看完觉得不错点个赞

相关文章:
容器-LinkedList
LinkedList LinkedList的概述 LinkedList的底层使用双向链表实现。 链表是一种线性数据结构,其中每个元素都是一个单独的对象,包含一个指向列表中下一个节点的引用。 它可以用于实现各种抽象数据类型,例如列表、堆栈、队列等。 LinkedLis…...
Flask 路由和视图函数
Flask 路由和视图函数一、路由 (Routing)二、视图函数 (View Functions)三、动态路由四、HTTP方法五、总结在Flask中,路由和视图函数是两个核心概念,它们协同工作以处理用户请求并生成响应。一、路由 (Routing) 路由是URL到Python函数的映射。当用户访问…...
Linux主机 SSH 通过密钥登录
我们一般使用 PuTTY 等 SSH 客户端来远程管理 Linux 服务器。但是,一般的密码方式登录,容易有密码被暴力破解的问题。所以,一般我们会将 SSH 的端口设置为默认的 22 以外的端口,或者禁用 root 账户登录。其实,有一个更…...
中国信息安全测评中心-自主原创测评
信息技术产品自主原创测评是适应我国经济社会发展的需要,是适应国际知识产权保护的发展趋势,鼓励信息技术产业的自主创新和维护权利人合法权益的重要举措。 信息技术产品自主原创测评业务是指在开发者自主声明的基础上,通过对关键技术实现的全…...
redis杂谈之部分重同步的实现
背景: 部分重同步则用于处理断线后重复制情况:当从服务器在断线 后重新连接主服务器时,如果条件允许,主服务器可以将主从服务器连 接断开期间执行的写命令发送给从服务器,从服务器只要接收并执行这 些写命令ÿ…...
多态部分参考答案
一、选择题 1、下列关于动态联编的描述中,错误的是()。 A.动态联编是以虚函数为基础 B.动态联编是运行时确定所调用的函数代码的 C.动态联编调用函数操作是指向对象的指针或对象引用 D.动态联编…...
【高项】项目人力资源管理,沟通管理与干系人管理(十大管理)
【高项】项目人力资源管理,沟通管理与干系人管理(十大管理) 文章目录1、人力资源管理1.1 什么是人力资源管理?1.2 如何进行人力资源管理?(过程)1.3 人力资源管理工具1.4 人力资源管理文件2、沟通…...
Wikijs简介-强大可扩展的开源维基软件
Wikijs - 最强大 最可扩展的开源维基软件 使用 wiki.js 美丽直观的界面,让文档成为写作的乐趣! 优点 🔧 随时随地安装 几乎适用于任何平台,并与PostgreSQL、MySQL、MariaDB、MS SQL Server 或 SQLite 兼容! ⚙️ 管…...
微博舆情分析系统的设计与实现(python)
背景分析 随着互联网大趋势的到来,社会的方方面面,各行各业都在考虑利用互联网作为媒介将自己的信息更及时有效地推广出去,而其中最好的方式就是建立网络管理系统,并对其进行信息管理。由于现在网络的发达,微博舆情分析系统的资讯信息通过网络进行信息管理掀起了热潮,所…...
【AUTOSAR】【Lin通信】LinTrcv
目录 一、概述 二、功能说明 2.1 LIN收发器驱动程序操作模式 2.2 LIN收发器硬件操作模式 2.3 LIN收发器唤醒类型 2.4 LIN收发器唤醒模式 2.5 错误分类 2.5.1 开发错误 三、API接口 3.1 API定义 一、概述 该规范规定了模块LIN收发器驱动程序的功能、API和配置。它负责…...
UE4C++学习篇(十九)-- 动画蒙太奇初级使用
用一个第三人称的射击案例来简单介绍一下动画蒙太奇的使用,动画蒙太奇的具体介绍这里就不多说了,不知道的小伙伴可以去搜一下了解。 这里介绍角色射击,射击的时候播放一个射击动画。 选中需要创建出动画蒙太奇的动画,点击创建&am…...
子集和问题
目录 子集和问题 程序设计 程序分析 子集和问题 【问题描述】子集和问题的一个实例为〈S,c〉。其中,S={ x1 , x2 ,…,xn }是一个正整数的集合,c是一个正整数。子集和问题判定是否存在S的一个子集S1,使得: 试设计一个解子集和问题的回溯法。 对于给定的正整数的集…...
苹果蓝牙耳机太贵了买哪个替代?苹果蓝牙耳机平替推荐
随着人们生活水平的提高,蓝牙耳机已经遍布在我们生活的各个角落。同时随着科技的发展,许多人果粉选择苹果耳机平替。下面我们一起来看看2023年有哪些适用于苹果的平替蓝牙耳机吧! 一、南卡小音舱Lite2蓝牙耳机 蓝牙版本:5.3 售…...
CK-UR05-US桌面式超高频RFID发卡器开发手册之USB控制命令格式
CK-UR05-US桌面式超高频RFID发卡器支持USB控制命令格式,本文重点就此格式展开说明! CK-UR05-US桌面式超高频RFID发卡器1、取版本号(GetReaderVersion) 功能:取读写器的硬件、软件版本 命令码: 02H 命令参数:无 命令包: 『40H 02H 02H BCH』 举例: 如…...
【华为OD机试】1025 - 字符串加解密
文章目录一、题目🔸题目描述🔸输入输出🔸样例1二、代码参考作者:KJ.JK🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 &#x…...
阿里云版GPT官宣,我们问了它10个问题
4月7日,阿里云宣布自研大模型“通义千问”,目前已开始邀请用户测试体验。 阿里达摩院在NLP自然语言处理等前沿科研领域早已布局多年,并于2019年启动大模型研发,通义千问便是其最新成果,相当于阿里云版的“ChatGPT”。 …...
ORM框架之NHibernate
什么是NHibernate NHibernate是一个开源的对象关系映射(ORM)框架,它允许开发人员使用面向对象的方式来访问关系型数据库。它是Hibernate框架的C#版本,Hibernate框架是Java平台上的ORM框架。 使用NHibernate,您可以将…...
凑微分练习
前言 在学习第一类换元法(凑微分法)时,我们常常需要凑微分。为了更加熟练地运用凑微分法,下面有几道凑微分例题供大家练习。 记住df(x)f′(x)dxdf(x)f(x)dxdf(x)f′(x)dx 例题1 dx‾d(ax)dx\underline{\quad}d(ax)dxd(ax)dx‾…...
JavaWeb——多线程使用哈希表
目录 一、HashMap 1、定义 二、HashTable 1、定义: 2、区别: 三、ConcurrentHashMap 1、定义: 2、优化 (1)、加锁粒度不同——触发锁冲突的频率不同 (2)、充分利用CAS机制——无锁编程…...
anaconda permission denied
可能是路径不对 我的是只写了dir,没写文件名,而我要的是某个文件的路径,所以就报这个错。 具体,我需要某个权重的路径,比如pytorch_resnet50.pth,但我只写了这个权重所在的dir,比如F:/software/…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
