java数据结构基础-顺序表

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

顺序表接口的实现(手动实现,仅为方便初学理解,实际开发中都用java自带的不用手写):

public class SeqList { // 底层存储数组 private int[] array; // 顺序表中实际元素个数 private int size; // 默认初始容量 private static final int DEFAULT_CAPACITY = 10; // 默认构造方法:初始化默认容量的数组 SeqList() { this.array = new int[DEFAULT_CAPACITY]; this.size = 0; } // 将顺序表的底层容量设置为initcapacity SeqList(int initcapacity) { // 校验初始容量合法性 if (initcapacity <= 0) { throw new IllegalArgumentException("初始容量不能小于等于0: " + initcapacity); } this.array = new int[initcapacity]; this.size = 0; } // 新增元素,默认在数组最后新增 public void add(int data) { // 先检查容量,不足则扩容 ensureCapacity(size + 1); // 把元素放到size位置,然后size自增 array[size++] = data; } // 在 pos 位置新增元素 public void add(int pos, int data) { // 1. 校验pos的合法性:pos必须在[0, size]范围内 checkPositionForAdd(pos); // 2. 检查容量,不足则扩容 ensureCapacity(size + 1); // 3. 将pos及之后的元素向后移动一位(从后往前移,避免覆盖) // System.arraycopy(源数组, 源起始位置, 目标数组, 目标起始位置, 移动长度) System.arraycopy(array, pos, array, pos + 1, size - pos); // 4. 放入新元素 array[pos] = data; // 5. 实际元素个数+1 size++; } // 判定是否包含某个元素 public boolean contains(int toFind) { // 遍历数组,找到则返回true for (int i = 0; i < size; i++) { if (array[i] == toFind) { return true; } } return false; } // 查找某个元素对应的位置(返回第一个匹配的索引,找不到返回-1) public int indexOf(int toFind) { for (int i = 0; i < size; i++) { if (array[i] == toFind) { return i; } } return -1; } // 获取 pos 位置的元素 public int get(int pos) { // 校验pos合法性:pos必须在[0, size-1]范围内 checkPosition(pos); return array[pos]; } // 给 pos 位置的元素设为 value public void set(int pos, int value) { // 校验pos合法性 checkPosition(pos); array[pos] = value; } // 删除第一次出现的关键字key public void remove(int toRemove) { // 1. 找到要删除元素的索引 int index = indexOf(toRemove); // 2. 找不到则直接返回 if (index == -1) { return; } // 3. 找到则移动元素:将index+1到size-1的元素向前移动一位 int numMoved = size - index - 1; if (numMoved > 0) { System.arraycopy(array, index + 1, array, index, numMoved); } // 4. 最后一个元素置为0(可选,帮助理解,不影响逻辑),size-1 array[--size] = 0; } // 获取顺序表长度(实际元素个数) public int size() { return this.size; } // 清空顺序表 public void clear() { // 方式1:直接重置size,简单高效(底层数组保留,下次添加会覆盖) this.size = 0; // 方式2(可选):遍历置空,帮助GC(int是基本类型,无GC,此处仅演示) // for (int i = 0; i < size; i++) { // array[i] = 0; // } // this.size = 0; } // 打印顺序表 public void display() { if (size == 0) { System.out.println("顺序表为空"); return; } // 拼接元素,格式:[1, 2, 3] StringBuilder sb = new StringBuilder(); sb.append("["); for (int i = 0; i < size; i++) { sb.append(array[i]); if (i != size - 1) { sb.append(", "); } } sb.append("]"); System.out.println("顺序表内容:" + sb); } // -------------- 私有辅助方法 -------------- // 检查容量:如果当前容量不足,进行扩容(扩容为原容量的1.5倍) private void ensureCapacity(int minCapacity) { int oldCapacity = array.length; // 如果需要的最小容量 > 当前数组长度,触发扩容 if (minCapacity > oldCapacity) { // 新容量 = 旧容量 + 旧容量/2(右移1位等价于除以2) int newCapacity = oldCapacity + (oldCapacity >> 1); // 防止扩容后仍不足(比如minCapacity特别大) if (newCapacity < minCapacity) { newCapacity = minCapacity; } // 数组拷贝,生成新数组 int[] newArray = new int[newCapacity]; System.arraycopy(array, 0, newArray, 0, size); this.array = newArray; } } // 校验pos是否合法(用于添加操作:pos范围 [0, size]) private void checkPositionForAdd(int pos) { if (pos < 0 || pos > size) { throw new IndexOutOfBoundsException("添加位置非法: pos = " + pos + ", 合法范围: [0, " + size + "]"); } } // 校验pos是否合法(用于查询/修改/删除:pos范围 [0, size-1]) private void checkPosition(int pos) { if (pos < 0 || pos >= size) { throw new IndexOutOfBoundsException("位置非法: pos = " + pos + ", 合法范围: [0, " + (size - 1) + "]"); } } // 测试方法 public static void main(String[] args) { SeqList seqList = new SeqList(5); // 测试尾部添加 seqList.add(10); seqList.add(20); seqList.add(30); seqList.display(); // 输出:顺序表内容:[10, 20, 30] // 测试指定位置添加 seqList.add(1, 15); seqList.display(); // 输出:顺序表内容:[10, 15, 20, 30] // 测试包含、索引查找 System.out.println("是否包含20:" + seqList.contains(20)); // true System.out.println("20的索引:" + seqList.indexOf(20)); // 2 // 测试获取、修改 System.out.println("索引1的元素:" + seqList.get(1)); // 15 seqList.set(1, 16); seqList.display(); // 输出:顺序表内容:[10, 16, 20, 30] // 测试删除 seqList.remove(20); seqList.display(); // 输出:顺序表内容:[10, 16, 30] // 测试大小、清空 System.out.println("顺序表大小:" + seqList.size()); // 3 seqList.clear(); seqList.display(); // 输出:顺序表为空 } }

二.ArrayList简介

【说明】
1. ArrayList是以泛型方式实现的,使用时必须要先实例化
2. ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问

3. ArrayList实现了Cloneable接口,表明ArrayList是可以clone的
4. ArrayList实现了Serializable接口,表明ArrayList是支持序列化的
5. 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者CopyOnWriteArrayList
6. ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表

三.ArrayList使用

①ArrayList的构造

方法解释
ArrayList()无参构造
ArrayList(Collection<? extends E> c)利用其他 Collection 构建 ArrayList
ArrayList(int initialCapacity)指定顺序表初始容量

总结:上面一堆介绍不用管,记住一般用List<参数类型(包装类)/自定义类> arr=new ArrayList<>();

这个就类似于C++里的Vector动态数组

而且类型里需要填对象的包装类,比如int 就填Integer char就填Character

public static void main(String[] args) { // ArrayList创建,推荐写法 // 构造一个空的列表 List<Integer> list1 = new ArrayList<>(); // 构造一个具有10个容量的列表 List<Integer> list2 = new ArrayList<>(10); list2.add(1); list2.add(2); list2.add(3); // list2.add("hello"); // 编译失败,List<Integer>已经限定了,list2中只能存储整形元素 // list3构造好之后,与list中的元素一致 ArrayList<Integer> list3 = new ArrayList<>(list2); // 避免省略类型,否则:任意类型的元素都可以存放,使用时将是一场灾难 List list4 = new ArrayList(); list4.add("111"); list4.add(100); }

②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

这里的方法想调用都要用 实例化名字.方法名(...) 这种格式

最大的区别是获取元素的时候用 .get(i)

而且想删除元素有两个方法,按储存Integer举例,如果你直接 arr.remove(index) 这是按下标删除。如果你是arr.remove((Integer)key),就是找到最近的key元素删除而不是全部删除

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,否则返回false if(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()); }

③ArrayList的遍历

ArrayList 可以使用三种方法遍历:for循环、foreach、迭代器

(1)for循环

List<Integer> arr = new ArrayList<>(); arr.add(10); arr.add(20); arr.add(30); arr.add(40); arr.add(50); // 1. for 循环 + 下标遍历(适合支持随机访问的集合,如 ArrayList) System.out.println("=== 方式1:for循环 + 下标 ==="); for (int i = 0; i < arr.size(); i++) { System.out.println(arr.get(i)); }

(2)foreach

List<Integer> arr = new ArrayList<>(); arr.add(10); arr.add(20); arr.add(30); arr.add(40); arr.add(50); // 2. foreach 遍历(简化写法,底层也是迭代器) System.out.println("\n=== 方式2:foreach ==="); for (Integer num : arr) { System.out.println(num); }

(3)迭代器

List<Integer> arr = new ArrayList<>(); arr.add(10); arr.add(20); arr.add(30); arr.add(40); arr.add(50); // 3. 使用迭代器遍历(通用遍历方式,适合所有 List 实现类) System.out.println("\n=== 方式3:迭代器 ==="); Iterator<Integer> iterator = arr.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next());

④ArrayList的扩容机制:

ArrayList是一个动态类型的顺序表,即:在插入元素的过程中会自动扩容

⑤ArrayList储存自定义类:

ArrayList可以储存自定义类,就比如储存一个Car类,类里有private的成员变量brand,wheel等等,想单独输出或者比较/修改这几个成员变量,那就需要再Car类里写get方法和set方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1220513.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

技能操作不丢分?跟紧哪家模拟培训?

“为什么连最基础的操作都差点失误?” 深夜后台的一条考生留言,瞬间戳中了无数执医技能备考人的心声。 练得熟≠考得稳,缺的从来不是重复训练,而是能1:1还原考场压迫感的仿真模拟。作为深耕医考领域的小编,每天都…

医院智能柜类全国推荐?

在当今数字化医疗的大背景下,医院智能柜类产品对于提升医疗管理效率、保障医疗物资安全等方面发挥着至关重要的作用。今天就为大家全国范围内推荐医院智能柜类产品,其中术衣博士消毒科技股份有限公司(简称 “术衣博…

术衣博士智能管理系统靠谱吗?

在当今医疗行业不断发展的背景下,智能管理系统对于医疗机构的高效运营和安全保障起着至关重要的作用。术衣博士智能管理系统凭借其独特的优势,成为众多医疗机构的信赖之选。术衣博士智能管理系统助力医疗管理升级术衣…

2026执医技能模拟培训机构推荐,哪家最仿真?

“在模拟人身上练了十几次,为什么一进考场还是手抖心慌?”一位考生的深夜留言,戳中了技能备考最深的痛点——缺乏能真正还原考场压迫感的训练。 身为长期跟踪测评各类医考培训产品的教育博主,我听过太多这样的困惑…

行研 + AI 深度融合-生物医药行业分析:五度易链 AI 智能体的实现逻辑

‍生物医药产业是全球创新最活跃、发展最迅速的战略性新兴产业之一&#xff0c;核心特征是高投入、高风险、高回报、长周期。在生物医药这个知识密集、创新驱动的高精尖领域&#xff0c;我们正面临一个前所未有的矛盾&#xff1a;一边是海量数据与科研成果的指数级增长&#xf…

Hudi 客户端实现分析

08. Hudi 客户端实现分析 主题说明 Hudi 提供了三种客户端实现&#xff1a;Spark、Flink 和 Java。理解客户端实现有助于理解不同引擎下的写入机制。 客户端实现包括&#xff1a; BaseHoodieWriteClient&#xff1a;客户端基类SparkRDDWriteClient&#xff1a;Spark 客户端Hood…

被Trae IDE的solo编程模式震惊到了

AI从GPT出来就开始用&#xff0c;基本就是作为问答交互式的辅助编程工具。包括局部代码开发&#xff0c;代码优化&#xff0c;错误检擦&#xff0c;特别是在不熟悉轮子的语言上&#xff0c;会大大的减少工作量。已经经历过lua开发&#xff0c;py开发&#xff0c;本来对里边的轮…

数字员工如何依托熊猫智汇实现销售业绩的飞跃?

数字员工是一种新兴的AI销售工具&#xff0c;通过智能化的操作&#xff0c;能够有效优化企业的业务流程。借助于AI销冠系统&#xff0c;数字员工实现了自动化外呼和智能应答&#xff0c;使得企业能更加高效地与客户沟通。这种创新不仅降低了人工成本&#xff0c;还提高了工作效…

一起来揭秘阿虎医考的网课,到底好在哪?

执业医师资格考试,一场医学人职业生涯中决定性的战役。每年有近半数考生铩羽而归。 面对海量考点、复杂的临床思维考核和严格的实践技能测试,大多数考生陷入了“知识记不住、重点抓不准、自律靠不住”的典型困境。 在…

医疗消毒追溯系统全国?

在医疗行业,消毒追溯系统的重要性不言而喻,它关乎着每一位患者的健康与安全。那么在全国范围内,哪家的医疗消毒追溯系统能脱颖而出呢?今天就带大家来认识一下山东术衣博士消毒科技股份有限公司(简称 “术衣博士”…

phpmyadmin偶数删除文章

phpmyadmin偶数删除文章在 phpMyAdmin 里按“偶数”规则删除文章,本质上是用 SQL 条件删除。下面按 WordPress 场景(你前面一直在用 WP)给你几种可直接用的、安全到激进方案。一、最常见需求:删除“ID 为偶数”的文…

哪个执业医师培训机构的网课好?阿虎凭何“领跑”又“实操强”?

每年的执业医师考试都是一场知识与耐力的较量,许多医学生在面对执业医师考试这座大山时,往往陷入两难境地——医院实习已占满白天时间,夜晚还要挑灯夜读,而市面上五花八门的医考培训机构让人眼花缭乱。 从老牌机构…

2026年重庆钢绞线厂家推荐,全面分析可靠的1*7钢绞线销售厂家

当前市场中,*17钢绞线供应商**数量众多,品质良莠不齐。在这样一个竞争激烈的环境下,采购者如何选择值得信赖的厂家成了关键。可靠的供应商通常具备行业经验、合规的生产标准和良好的客户反馈。本文将对市场上几家具…

自然语言处理(NLP)—发展历程(背景、高效的技术、优缺点、未来方向)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

[Java EE] 多线程进阶 (1) - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

为什么我不允许 Service 层直接返回 Result?

沉默是金&#xff0c;总会发光大家好&#xff0c;我是沉默最近一次 Code Review&#xff0c;我和阿伟“打”了一架。事情的起因很简单。 我发现他在 Service 层直接 return 了 Result 对象。我提醒了一句&#xff1a;“这个不太合适。”阿伟一脸疑惑地反问我&#xff1a;「为啥…

智能风控实战:金融AI体系构建全流程

智能风控实战&#xff1a;金融AI体系构建全流程 关键词&#xff1a;智能风控、金融AI、体系构建、风险评估、机器学习、深度学习、大数据 摘要&#xff1a;本文深入探讨金融领域智能风控中AI体系构建的全流程。首先介绍智能风控在金融行业的重要背景&#xff0c;点明其对保障…

【建议收藏】网络安全:IT小白的“零门槛“高薪之路,327万缺口等你来填补!

中国信息通信研究院《网络安全产业人才发展报告&#xff08;2024年&#xff09;》显示&#xff0c;2024年我国网络安全人才缺口高达327万&#xff0c;而新增人才供给仅约20万人/年。与此同时&#xff0c;网络安全市场规模持续扩大&#xff0c;预计2025年将突破3000亿元。 在数…

“推三返一”的完整商业逻辑:从裂变算法到合规边界,一篇讲透

在流量成本高企的今天&#xff0c;每一个手握产品、寻求线上突破的老板&#xff0c;都在寻找能“四两拨千斤”的增长秘籍。“推三返一”这个词&#xff0c;随之频繁出现在项目圈、方案商的对话中。它被描绘成私域裂变的核武器&#xff0c;但也总与“是否合法”的质疑相伴。今天…

hcie笔试题库有多少道题?

备考HCIE考试&#xff0c;笔试是第一关&#xff0c;很多同学一上来就懵&#xff1a;笔试题库到底有多少道题&#xff1f;手里的题库能用到什么时候&#xff1f;会不会背完就过期了&#xff1f;今天就把这两个问题掰扯清楚&#xff0c;帮你高效备赛&#xff01; 01、HCIE笔试题库…