数据结构 - 2(顺序表10000字详解)
一:List
1.1 什么是List
在集合框架中,List是一个接口,继承自Collection。

Collection也是一个接口,该接口中规范了后序容器中常用的一些方法,具体如下所示:

Iterable也是一个接口,Iterable接口表示实现该接口的类是可以逐个元素进行遍历的,
站在数据结构的角度来看,List就是一个线性表,即n个具有相同类型元素的有限序列,在该序列上可以执行增删改查以及变量等操作。
List中常用的方法如下所示:
| 方法 | 解释 |
|---|---|
| boolean add(E e) | 尾插 e |
| void add(int index, E element) | 将 e 插入到 index 位置 |
| boolean addAll(Collection<? extends E> c) | 尾插 c 中的元素 |
| E remove(int index) | 删除 index 位置元素 |
| boolean remove(Object o) | 删除遇到的第一个 o |
| E get(int index) | 获取下标 index 位置元素 |
| E set(int index, E element ) | 将下标 index 位置元素设置为 element |
| void clear() | 清空 |
| boolean contains(Object o) | 判断 o 是否在线性表中 |
| int indexOf(Object o) | 返回第一个 o 所在下标 |
| int lastIndexOf(Object o) | 返回最后一个 o 的下标 |
| List < E> subList(int fromIndex, int toIndex) | 截取部分 list |
1.2 List的使用
注意:List是个接口,并不能直接用来实例化。
如果要使用,必须去实例化List的实现类。在集合框架中,ArrayList和LinkedList都实现了List接口。
使用实例如下:
List<String> arrayList = new ArrayList<>(); // 使用ArrayList实现
List<Integer> linkedList = new LinkedList<>(); // 使用LinkedList实现//添加元素
arrayList.add("Apple");
arrayList.add("Banana");
arrayList.add("Orange");//添加元素
linkedList.add(10);
linkedList.add(20);
linkedList.add(30);
我们通过向上转型,分别调用了ArrayList和LinkedList中的add重写方法,这两个方法在ArrayList和LinkedList中都有自己的实现方式
二: ArrayList的使用
2.1 什么是线性表
线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列…
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
比如说:

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
2.2ArrayList简介

【说明】
- ArrayList是以泛型方式实现的,使用时必须要先实例化,并指定一下泛型参数
- ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问
- ArrayList实现了Cloneable接口,表明ArrayList是可以clone的
- ArrayList实现了Serializable接口,表明ArrayList是支持序列化的
- 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者
CopyOnWriteArrayList - ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表
2.3 ArrayList的使用
| 方法 | 解释 |
|---|---|
| ArrayList() | 无参构造 |
| ArrayList(Collection<? extends E> c) | 利用其他 Collection 构建 ArrayList |
| ArrayList(int initialCapacity) | 指定顺序表初始容量 |
ArrayList(Collection<? extends E> c) 是一个构造函数,它接受一个实现了 Collection 接口的对象 c。这个构造函数会将 c 中的所有元素添加到新创建的 ArrayList 中。
通常情况下,ArrayList 是按照元素的添加顺序来存储的,而 ArrayList(Collection<? extends E> c) 可以方便地将另一个集合的元素全部添加到当前的 ArrayList 中。
例如,假设有一个 List 对象 list,可以使用如下代码创建一个新的 ArrayList,并将 list 中的所有元素添加到新的 ArrayList 中:
ArrayList<String> arrayList = new ArrayList<>(list);
在上述代码中,ArrayList<String> arrayList 是一个新创建的 ArrayList 对象,它包含了 list 中的所有元素。
注意:ArrayList(Collection<? extends E> c) 的泛型参数要与 ArrayList 的泛型参数类型一致或构成子类父类的关系,即它们需要是相同类型或者是其子类型。
2.4 ArrayList的常用方法
| 方法 | 解释 |
|---|---|
| boolean add(E e) | 尾插 e |
| void add(int index, E element) | 将 e 插入到 index 位置 |
| boolean addAll(Collection<? extends E> c) | 尾插 c 中的元素 |
| E remove(int index) | 删除 index 位置元素 |
| boolean remove(Object o) | 删除遇到的第一个 o |
| E get(int index) | 获取下标 index 位置元素 |
| E set(int index, E element) | 将下标 index 位置元素设置为element |
| void clear() | 清空 |
| boolean contains(Object o) | 判断 o 是否在线性表中 |
| int indexOf(Object o) | 返回第一个 o 所在下标 |
| int lastIndexOf(Object o) | 返回最后一个 o 的下标 |
| List< E > subList(int fromIndex, int toIndex) | 截取部分 list |
使用实例:
public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("JavaSE");list.add("JavaWeb");list.add("JavaEE");list.add("JVM");list.add("测试课程");System.out.println(list);// 获取list中有效元素个数System.out.println(list.size());// 获取和设置index位置上的元素,注意index必须介于[0, size)间System.out.println(list.get(1));list.set(1, "JavaWEB");System.out.println(list.get(1));// 在list的index位置插入指定元素,index及后续的元素统一往后搬移一个位置list.add(1, "Java数据结构");System.out.println(list);// 删除指定元素,找到了就删除,该元素之后的元素统一往前搬移一个位置list.remove("JVM");System.out.println(list);// 删除list中index位置上的元素,注意index不要超过list中有效元素个数,否则会抛出下标越界异常list.remove(list.size()-1);System.out.println(list);// 检测list中是否包含指定元素,包含返回true,否则返回falseif(list.contains("测试课程")){list.add("测试课程");}// 查找指定元素第一次出现的位置:indexOf从前往后找,lastIndexOf从后往前找list.add("JavaSE");System.out.println(list.indexOf("JavaSE"));System.out.println(list.lastIndexOf("JavaSE"));// 使用list中[0, 4)之间的元素构成一个新的SubList返回,但是和ArrayList共用一个elementData数组List<String> ret = list.subList(0, 4);System.out.println(ret);list.clear();System.out.println(list.size());
}
2.5 ArrayList的遍历
ArrayList 可以使用三方方式遍历:for循环+下标、foreach、使用迭代器
public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);// 使用下标+for遍历for (int i = 0; i < list.size(); i++) {System.out.print(list.get(i) + " ");}System.out.println();// 借助foreach遍历for (Integer integer : list) {System.out.print(integer + " ");}System.out.println();//迭代器遍历Iterator<Integer> it = list.listIterator();while(it.hasNext()){System.out.print(it.next() + " ");}System.out.println();
}
下面我们讲解一下使用迭代器遍历的方式
迭代器是用于遍历集合(如列表、数组等)中的元素的一种接口。它提供了一种统一的方式来访问和处理集合中的元素,而不需要暴露集合的内部实现细节。
迭代器有以下几个主要的方法:
hasNext(): 检查迭代器中是否还有下一个元素,如果有则返回true,否则返回false。next(): 返回迭代器的下一个元素,并将迭代器的位置向后移动。remove(): 从迭代器指向的集合中移除迭代器返回的最后一个元素。
使用迭代器,你可以按顺序访问集合中的每一个元素,而不需要知道集合的内部结构或者索引。这样可以提供更灵活和独立的遍历方式。
在这段代码中,Iterator<Integer> it = list.listIterator(); 这行代码的作用是创建一个整数类型的迭代器 it,并将其初始化为列表的迭代器。这样我们就可以使用 it 来遍历并访问列表中的元素。
while(it.hasNext()){System.out.print(it.next() + " ");}
在上述示例中,it.hasNext() 检查迭代器中是否还有下一个元素,如果有,则执行循环内部代码。it.next() 返回迭代器的下一个元素,并将迭代器的位置向后移动。你可以在循环内部处理当前元素,例如打印出来。
迭代器是一次性的,即只能从头到尾进行一次遍历。如果需要重新遍历集合,你需要重新创建一个新的迭代器。
注意:
- ArrayList最长使用的遍历方式是:for循环+下标 以及 foreach
- 迭代器是设计模式的一种,后序容器接触多了再给大家铺垫
2.6ArrayList的扩容机制
ArrayList是一个动态类型的顺序表,当我们向 Java 的 ArrayList 中添加元素时,ArrayList 会自动扩容,以容纳更多的元素。ArrayList 的扩容机制如下:
-
初始容量:每个 ArrayList 对象都有一个初始容量。在创建 ArrayList 对象时,如果没有指定初始容量大小,则默认为10。这意味着初始时 ArrayList 可以容纳最多10个元素。
-
操作次数:当我们向 ArrayList 中添加新元素时,ArrayList 会根据当前存储的元素数量和内部数组的长度进行判断。每次添加元素的操作都会增加 ArrayList 的操作次数。
-
扩容策略:当 ArrayList 的操作次数达到其内部数组长度时,就会触发扩容操作。ArrayList 的默认扩容因子是1.5倍,即每次扩容后的容量为当前容量的1.5倍。
-
数组拷贝:扩容时,ArrayList 会创建一个新的数组,将原有元素拷贝到新数组中。这个过程涉及到数组的创建和数据的拷贝,所以在扩容操作时可能会对性能产生一定的影响。
需要注意的是,扩容是一个相对耗时的操作,因为它涉及到数据的拷贝和存储空间的重新分配。因此,在知道需要存储大量元素的情况下,为 ArrayList 显式指定一个初始容量,可以减少扩容操作的次数,提高性能。
ArrayList 的扩容策略是在底层数组容量不足时,将当前容量乘以一个扩容因子来进行扩容。默认情况下,ArrayList 的扩容因子是 1.5 倍。
注意:ArrayList 的扩容因子是可调的,可以通过构造函数来指定。我们可以使用 ArrayList(int initialCapacity, float loadFactor) 构造函数来同时指定初始容量和扩容因子。
三:模拟实现一个ArrayList
3.1方法框架
public class SeqList {private int[] array;private int size;// 默认构造方法SeqList(){ }// 将顺序表的底层容量设置为initcapacitySeqList(int initcapacity){ }// 新增元素,默认在数组最后新增public void add(int data) { }// 在 pos 位置新增元素public void add(int pos, int data) { }// 判定是否包含某个元素public boolean contains(int toFind) { return true; }// 查找某个元素对应的位置public int indexOf(int toFind) { return -1; }// 获取 pos 位置的元素public int get(int pos) { return -1; }// 给 pos 位置的元素设为 valuepublic void set(int pos, int value) { }//删除第一次出现的关键字keypublic void remove(int toRemove) { }// 获取顺序表长度public int size() { return 0; }// 清空顺序表public void clear() { }// 打印顺序表,注意:该方法并不是顺序表中的方法,为了方便看测试结果给出的public void display() { }
}
3.2 模拟实现ArrayList
class MyArrayList {private int[] array;private int size;// 默认构造方法public MyArrayList() {// 初始化底层数组,初始容量为10array = new int[10];// 初始大小为0size = 0;}// 将顺序表的底层容量设置为initCapacitypublic MyArrayList(int initCapacity) {if (initCapacity < 0) {throw new IllegalArgumentException("容量不能小于0");}// 初始化底层数组,初始容量为initCapacityarray = new int[initCapacity];// 初始大小为0size = 0;}// 在数组最后新增元素public void add(int data) {// 如果数组已满,则扩容if (size == array.length) {resize();}// 在数组末尾新增元素array[size] = data;// 更新大小size++;}// 在指定位置新增元素public void add(int pos, int data) {// 检查位置是否合法if (pos < 0 || pos > size) {throw new IndexOutOfBoundsException("索引超出范围");}// 如果数组已满,则扩容if (size == array.length) {resize();}// 将指定位置及其后面的元素后移一位for (int i = size - 1; i >= pos; i--) {array[i + 1] = array[i];}// 在指定位置插入元素array[pos] = data;// 更新大小size++;}// 判定是否包含某个元素public boolean contains(int toFind) {// 遍历数组查找元素for (int i = 0; i < size; i++) {if (array[i] == toFind) {return true;}}return false;}// 查找某个元素对应的位置public int indexOf(int toFind) {// 遍历数组查找元素for (int i = 0; i < size; i++) {if (array[i] == toFind) {return i;}}// 未找到元素,返回-1return -1;}// 获取指定位置的元素public int get(int pos) {// 检查位置是否合法if (pos < 0 || pos >= size) {throw new IndexOutOfBoundsException("索引超出范围");}// 返回指定位置的元素return array[pos];}// 设置指定位置的元素public void set(int pos, int value) {// 检查位置是否合法if (pos < 0 || pos >= size) {throw new IndexOutOfBoundsException("索引超出范围");}// 更新指定位置的元素array[pos] = value;}// 删除第一次出现的指定元素public void remove(int toRemove) {// 遍历数组查找要删除的元素for (int i = 0; i < size; i++) {if (array[i] == toRemove) {// 将要删除元素后面的元素前移一位for (int j = i + 1; j < size; j++) {array[j - 1] = array[j];}// 更新大小size--;return;}}}// 获取顺序表长度public int size() {return size;}// 清空顺序表public void clear() {// 将数组清空for (int i = 0; i < size; i++) {array[i] = 0;}// 大小置为0size = 0;}// 扩容数组private void resize() {// 创建新的数组,长度为当前容量的两倍int[] newArray = new int[array.length * 2];// 将原数组中的元素复制到新数组中for (int i = 0; i < size; i++) {newArray[i] = array[i];}// 更新底层数组array = newArray;}// 打印顺序表public void display() {// 遍历数组打印元素for (int i = 0; i < size; i++) {System.out.print(array[i] + " ");}System.out.println();}
}
这是一个自定义的MyArrayList类,模拟实现了一个动态数组。以下是每个功能的解释:
- 构造方法:使用默认构造方法创建一个初始容量为10的数组,并将大小初始化为0。使用带有参数的构造方法可以设置初始容量。
add方法:在数组最后新增元素,如果数组已满,则扩容。add方法(重载):在指定位置新增元素,如果数组已满,则扩容。为了将指定位置的元素后移,我们需要从后往前遍历数组。contains方法:遍历数组查找是否包含某个元素,如果找到则返回true,否则返回false。indexOf方法:遍历数组查找某个元素对应的位置,如果找到则返回元素的索引,否则返回-1。get方法:获取指定位置的元素,如果位置合法则返回元素,否则抛出IndexOutOfBoundsException异常。set方法:设置指定位置的元素,如果位置合法则更新元素值,否则抛出IndexOutOfBoundsException异常。remove方法:删除第一次出现的指定元素,将后面的元素前移一位,并更新大小。size方法:获取顺序表的长度,即元素的个数。clear方法:清空顺序表,将数组
3.3 测试功能
接着我们再写一个测试类,用于测试功能:
public class Main {public static void main(String[] args) {MyArrayList list = new MyArrayList();// 测试默认构造方法System.out.println("测试默认构造方法:");System.out.println("顺序表是否为空:" + (list.size() == 0));System.out.println("顺序表的大小:" + list.size());list.display();// 测试 add 方法System.out.println("\n测试 add 方法:");list.add(1);list.add(2);list.add(3);list.display();// 测试 add(pos, data) 方法System.out.println("\n测试 add(pos, data) 方法:");list.add(1, 5);list.display();// 测试 contains 方法System.out.println("\n测试 contains 方法:");System.out.println("顺序表中是否包含元素 2:" + list.contains(2));System.out.println("顺序表中是否包含元素 4:" + list.contains(4));// 测试 indexOf 方法System.out.println("\n测试 indexOf 方法:");System.out.println("元素 2 在顺序表中的位置:" + list.indexOf(2));System.out.println("元素 4 在顺序表中的位置:" + list.indexOf(4));// 测试 get 方法System.out.println("\n测试 get 方法:");System.out.println("位置 2 上的元素:" + list.get(2));// 测试 set 方法System.out.println("\n测试 set 方法:");list.set(1, 4);list.display();// 测试 remove 方法System.out.println("\n测试 remove 方法:");list.remove(2);list.display();// 测试 size 方法System.out.println("\n测试 size 方法:");System.out.println("顺序表的大小:" + list.size());// 测试 clear 方法System.out.println("\n测试 clear 方法:");list.clear();list.display();System.out.println("顺序表是否为空:" + (list.size() == 0));}
}
-
运行结果如下:
测试默认构造方法: 顺序表是否为空:true 顺序表的大小:0测试 add 方法: 1 2 3 测试 add(pos, data) 方法: 1 5 2 3 测试 contains 方法: 顺序表中是否包含元素 2:true 顺序表中是否包含元素 4:false测试 indexOf 方法: 元素 2 在顺序表中的位置:2 元素 4 在顺序表中的位置:-1测试 get 方法: 位置 2 上的元素:2测试 set 方法: 1 4 2 3 测试 remove 方法: 1 4 3 测试 size 方法: 顺序表的大小:3测试 clear 方法:顺序表是否为空:true
可见输出都符合我们的预期,说明我们模拟实现的ArrayList在功能上是完好的,并且没有什么缺陷。
四:ArrayList的问题及思考
- ArrayList底层使用连续的空间,任意位置插入或删除元素时,需要将该位置后序元素整体往前或者往后搬移,故时间复杂度为O(N)
- 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
- 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继
续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。
所以应该使用 ArrayList 的场景包括:
- 需要频繁进行随机访问的场景。
不应该使用 ArrayList 的场景包括:
-
需要频繁进行插入和删除操作,并对性能要求较高的场景。
-
列表中的元素数量比较少,可能造成内存浪费的场景。
相关文章:
数据结构 - 2(顺序表10000字详解)
一:List 1.1 什么是List 在集合框架中,List是一个接口,继承自Collection。 Collection也是一个接口,该接口中规范了后序容器中常用的一些方法,具体如下所示: Iterable也是一个接口,Iterabl…...
05在IDEA中配置Maven的基本信息
配置Maven信息 配置Maven家目录 每次创建Project工程后都需要设置Maven家目录位置,否则IDEA将使用内置的Maven核心程序和使用默认的本地仓库位置 一般我们配置了Maven家目录后IDEA就会自动识别到conf/settings.xml配置文件和配置文件指定的本地仓库位置创建新的P…...
基于IDEA 配置Maven环境和JDK版本(全局)
1.首先启动IDEA,进去初始界面 选择 Customize 之后,选择 All settings 2. 选择下图中的列表配置 3. 找到Maven下的Runner, 配置JRE的版本,选择自己下载使用的jdk的版本即可 4.最后配置Compiler 下的 Java Compiler 选择自己的jdk版本号&am…...
mysql数据库 windows迁移至linux
1.打开navicat,选择一个数据库进行操作: 之后文件会保存为一个xxx.sql文件,之后打开xftp,把生成的sql放进一个文件夹中(/home/dell/linuxmysql): 之后登录mysql数据库,并创建一个新的数据库,然后…...
P4491 [HAOI2018] 染色
传送门:洛谷 解题思路: 写本题需要知道一个前置知识: 假设恰好选 k k k个条件的方案数为 f ( k ) f(k) f(k);先钦定选 k k k个条件,其他条件无所谓的方案数为 g ( k ) g(k) g(k) 那么存在这样的一个关系: g ( k ) ∑ i k n C i k f ( i ) g(k)\sum_{ik}^nC_{i}^kf(i) g(k)…...
12096 - The SetStack Computer (UVA)
题目链接如下: Online Judge 这道题我一开始的思路大方向其实是对的,但细节怎么实现set到int的哈希没能想清楚(没想到这都能用map)。用set<string>的做法来做,测试数据小的话答案是对的,但大数据时…...
Pygame中将鼠标形状设置为图片2-1
在Pygame中利用Sprite类的派生类将鼠标形状设置为图片,其原理就是将Sprite类的派生类对应图片的位置设置为鼠标的当前位置即可。其效果如图1所示。 图1 将鼠标设置为图片 从图1可以看出,鼠标的形状变为红色的,该红色的随着鼠标的移动而移动&…...
Vue3 + Nodejs 实战 ,文件上传项目--实现图片上传
目录 技术栈 1. 项目搭建前期工作(不算太详细) 前端 后端 2.配置基本的路由和静态页面 3.完成图片上传的页面(imageUp) 静态页面搭建 上传图片的接口 js逻辑 4.编写上传图片的接口 5.测试效果 结语 博客主页:専心_前端,javascript,mys…...
linux C++ vscode连接mysql
1.linux使用Ubuntu 2.Ubuntu安装vscode 2.1 安装的是snap版本,直接打开命令行执行 sudo snap install --classic code 3.vscode配置C 3.1 直接在扩展中搜索C安装即可 我安装了C, Chinese, code runner, 安装都是同理 4.安装mysql sudo apt update sudo apt install mysql-…...
[资源推荐]langchain、LLM相关
之前很多次逛github或者去B站看东西或者说各种浏览资讯的情况,都会先看两眼然后收藏然后就吃灰的情况,那既然这样,不如多看几眼,看看是否真的能用得上,能用在哪,然后用几句话总结出来,分享出来&…...
hdfs笔记
1.HDFS shell 1.0查看帮助 hadoop fs -help <cmd> 1.1上传 hadoop fs -put <linux上文件> <hdfs上的路径> 1.2查看文件内容 hadoop fs -cat <hdfs上的路径> 1.3查看文件列表 hadoop fs -ls / 1.4…...
java_方法引用和构造器引用
文章目录 一、方法引用1.1、方法引用的理解1.2、格式1.3、举例 二、构造器引用2.1、格式2.2、例子2.3、数组引用 一、方法引用 1.1、方法引用的理解 方法引用,可以看做是基于lambda表达式的进一步刻画当需要提供一个函数式接口的实例时,可以使用lambda…...
Flink Log4j 2.x使用Filter过滤日志类型
Flink Log4j 2.x使用Filter过滤日志类型(区别INFO、ERROR) 文章目录 Flink Log4j 2.x使用Filter过滤日志类型(区别INFO、ERROR)ThresholdFilterLevelMatchFilter 日志级别: ALL < TRACE < DEBUG < INFO < …...
Ubuntu下怎么配置vsftpd
2023年10月12日,周四中午 目录 首先要添加一个系统用户然后设置这个系统用户的密码给新创建的系统用户创建主目录启动vsftpd服务查看vsftpd服务的状态打开外界访问vsftpd服务所需的端口获取服务器的IP地址大功告成 首先要添加一个系统用户 useradd 用户名然后设置…...
链表(7.27)
3.3 链表的实现 3.3.1头插 原理图: newnode为新创建的节点 实现: //头插 //让新节点指向原来的头指针(节点),即新节点位于开头 newnode->next plist; //再让头指针(节点)指向新节点&#…...
在 Elasticsearch 中实现自动完成功能 1:Prefix queries
自动完成与搜索功能不同 - 我们应该在用户键入下一个字符后立即更新自动完成选项,每秒都会访问数据库,过滤数百万条记录,而不会导致任何性能下降! Elasticsearch 是一种可以轻松实现此类功能的技术,它是一种基于 Apac…...
『PyQt5-Qt Designer篇』| 13 Qt Designer中如何给工具添加菜单和工具栏?
13 Qt Designer中如何给工具添加菜单和工具栏? 1 创建默认窗口2 添加菜单栏3 查看和调用1 创建默认窗口 当新创建一个窗口的时候,默认会显示有:菜单栏和状态栏,如下: 可以在菜单栏上右键-移除菜单栏: 可以在菜单栏上右键-移除状态栏: 2 添加菜单栏 在窗口上,右键-创建…...
Android Studio新建项目教程
Android Studio新建项目教程 一、创建新项目 二、选择空白页项目类型 配置然后finish 等待项目完成初试化 等待初始化结束,创建完成...
前端页面布局之【响应式布局】
目录 🌟前言🌟优点🌟缺点🌟media兼容性🌟利用CSS3-Media Query实现响应式布局🌟常见的媒体类型🌟常见的操作符🌟属性值🌟设备检测🌟响应式阈值选取dz…...
定制排序小案例
案例:自定义 Book 类,里面包含 name 和 price,按 price 排序(从大到小)。 要求使用两种方式排序 , 有一个 Book[] books 4 本书对象. 使用前面学习过的传递 实现 Comparator 接口匿名内部类,也称为定制排序。 可以按照 price …...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
