Java_简单模拟实现ArrayList_学习ArrayList
文章目录
- 一、 了解线性表和顺序表区别
- 1.线性表
- 2.顺序表
- 二、模拟实现
- 1.定义接口
- 2.定义MyArrayList
- 3.成员变量以及构造方法
- 4.实现打印数组
- 5.实现add方法
- 6.实现查找某个数是否存在contains或者某个数的下标indexOf
- 7.获取或更改pos位置的值 get和set
- 8.获取数组大小 size
- 9.删除某个值 remove
- 10.清空 clear
- 三、ArrayList源码如何做的
- 1.成员变量
- 2.构造方法
- 1、有参数的构造
- 2、无参数的构造
- 3、数组构造
- 4.add
- 5.addAll
- 6.remove
- 7.subList
- 8.迭代器 iterator
一、 了解线性表和顺序表区别
1.线性表
线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列…
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。


2.顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
二、模拟实现
1.定义接口
package mylist;public interface IList {// 新增元素,默认在数组最后新增public void add(int data);// 在 pos 位置新增元素public void add(int pos,int data);//判断是否包含某个元素public boolean contains(int toFind);//查找某一元素的位置public int indexOf(int toFind);//获取pos位置的元素public int get (int pos);//给pos位置元素设为valuepublic void set (int pos,int value);//删除第一次出现的关键字keypublic void remove(int toRemove);//获取顺序表的长豆public int size();//清空顺序表public void clear();//打印顺序表,注意:该方法不是顺序表的方法,为了方便测试结果给出的public void display();}
2.定义MyArrayList
MyArrayList要继承上面的接口并实现,现在是框架。
package mylist;public class MyArrayList implements IList{@Overridepublic void add(int data) {}@Overridepublic void add(int pos, int data) {}@Overridepublic boolean contains(int toFind) {return false;}@Overridepublic int indexOf(int toFind) {return 0;}@Overridepublic int get(int pos) {return 0;}@Overridepublic void set(int pos, int value) {}@Overridepublic void remove(int toRemove) {}@Overridepublic int size() {return 0;}@Overridepublic void clear() {}@Overridepublic void display() {}
}
3.成员变量以及构造方法
//储存元素的数组public int [] elem;//当前顺序表有多少个元素public int usedSize;//默认数组大小public static final int DEFAULT_SIZE = 10;public MyArrayList() {this.elem = new int [DEFAULT_SIZE];}public MyArrayList(int capacity ) {this.elem = new int[capacity];}
4.实现打印数组
public void display() {for(int i = 0;i<usedSize;i++){System.out.print(this.elem[i]+" ");}System.out.print("\n");}
5.实现add方法
在添加之前需要判断是否满(单独将判断是否满方法实现方法名为isFull),如果满了对数组扩容(所以我可以实现检查容量方法,如果满了就扩容,没满就什么都不做),没满添加。
重复上面操作,对于在pos位置添加,要判断pos如果合法就把后面向后挪一位,再对于pos位置添加数据。
不合法抛出异常。
public class PosIllegality extends RuntimeException{public PosIllegality(String msg){super(msg);}
}
---------------------------------------------------------------------------------------public boolean isFull(){if(usedSize>=elem.length){return true;}return false;}private void checkCapacity(){if(isFull()) {//扩容elem = Arrays.copyOf(elem,elem.length*2);}}@Overridepublic void add(int data) {checkCapacity();elem[usedSize++] = data;}private void checkPosOnAdd(int pos){if(pos>usedSize||pos<0){System.out.println("不合法!");throw new PosIllegality("插入元素下标异常"+pos);}}@Overridepublic void add(int pos, int data) {try{checkPosOnAdd(pos);}catch (PosIllegality e){e.printStackTrace();return ;}checkCapacity();for(int i = usedSize++;i>pos;i--){elem[i] = elem[i-1];}elem[pos] = data;}
测试:
public static void main(String[] args) {MyArrayList myArrayList = new MyArrayList();myArrayList.add(1);myArrayList.add(2);myArrayList.add(3);myArrayList.add(4);myArrayList.add(5);myArrayList.add(6);myArrayList.add(7);myArrayList.add(8);myArrayList.add(9);myArrayList.add(10);myArrayList.add(11);myArrayList.add(0,0);myArrayList.add(1,-1);myArrayList.display();}

6.实现查找某个数是否存在contains或者某个数的下标indexOf
首先得判断数组是否为空(可以单独实现是否为空的方法isEmpty),其次再寻找目标数。
注意如果是引用类型,要重写这个方法,比较不能直接比较要调用比较的方法
public boolean isEmpty(){if(usedSize==0){return true;}return false;}@Overridepublic boolean contains(int toFind) {if(isEmpty()){return false;}for(int i = 0;i<usedSize;i++){if(elem[i]==toFind){return true;}}return true;}@Overridepublic int indexOf(int toFind) {if(isEmpty()){return -1;}for(int i = 0;i<usedSize;i++){if(elem[i]==toFind){return i;}}return -1;}
7.获取或更改pos位置的值 get和set
首先检查pos的合法性(单独写个检查pos的方法,如果不合法抛出异常),返回或修改pos位置的值。
private void checkPosOnGet(int pos){if(pos<0||pos>=usedSize){System.out.println("不合法!");throw new PosIllegality("获取元素下标异常"+pos);}}@Overridepublic int get(int pos) {try {checkPosOnGet(pos);}catch (PosIllegality e){e.printStackTrace();return -1;}return elem[pos];}
private void checkPosOnSet(int pos){if(pos<0||pos>=usedSize){throw new PosIllegality("获取元素下标异常"+pos);}}@Overridepublic void set(int pos, int value) {
// try {
// checkPosOnSet(pos);
// }catch (PosIllegality e)
// {
// e.printStackTrace();
// return ;
// }checkPosOnSet(pos);elem[pos] = value;}
8.获取数组大小 size
@Overridepublic int size() {return usedSize;}
9.删除某个值 remove
@Overridepublic void remove(int toRemove) {int index = indexOf(toRemove);if(index==-1){System.out.println("没有这数字");return;}for(int i = index;i<usedSize-1;i++){elem[i] = elem[i+1];}usedSize--;}
10.清空 clear
@Overridepublic void clear() {usedSize = 0;}
思考如果存的是引用数据能不能直接将usedSize=0?
不能如果,数组里面装的是引用数据类型,就会造成内存泄漏。
JVM当中回收算法有很多
当前对象没有人引用的时候(1.elem=null 2.将每一个下标的值 elem[i]=null)
三、ArrayList源码如何做的
1.成员变量

elementData为存储元素的数组,是物理空间连续的内存地址。
size为数组存储元素的个数。
2.构造方法
1、有参数的构造


2、无参数的构造


发现无参数构造不给任何空间,那么add时数据放哪里?
3、数组构造

Collection是什么?
请看下图

? extends E表示:通配符的上级,?是E的子类或本身
举例:
ArrayList list = new ArrayList<>();
ArrayListlist2 = new ArrayList<>(list);
?就表示list的类型Interger,而E就是list2的类型是Number,符合子类。
4.add

这里可以看见add调用了ensureCapacityInternal,size为当前存储的个数当前还是没有任何插入,size为0

minCapacity为1

看上面无参数构造可以知道,if成立,此时返回了默认大小(DEFAULT_CAPACITY)也就是10,返回10。


看下面代码不难发现,grow就是扩容代码,oldCapacity>>1就是除2,ArraryList是1.5倍扩容。

总结:
1、 如果没有分配内存,第一次add会分配大小为10的内存
2、 ArrayList是1 .5倍扩容
5.addAll

public static void main(String[] args) {ArrayList<Integer> arrayList1 =new ArrayList<>();arrayList1.add(1);arrayList1.add(2);arrayList1.add(3);ArrayList<Integer> arrayList2 =new ArrayList<>();arrayList2.add(4);arrayList2.add(5);arrayList2.add(6);arrayList1 .addAll(arrayList2);arrayList2.addAll(1,arrayList1);System.out.println(arrayList1);System.out.println(arrayList2);}

6.remove

注意:传数字,只会删除对应下标的值,而传对象才会删对应的对象。
public static void main(String[] args) {ArrayList<Integer> arrayList1 =new ArrayList<>();arrayList1.add(1);arrayList1.add(2);arrayList1.add(3);arrayList1.remove(2);System.out.println(arrayList1);arrayList1.remove(new Integer(1));System.out.println(arrayList1);}

7.subList

public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);System.out.println(list);List<Integer> list1 = list.subList(1,3);System.out.println(list1);}
注意:
1.为左闭右开
2.返回的位List类型
3.截取不会产生新的对象(对返回的修改,被截取的也会修改)
8.迭代器 iterator
public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);Iterator<Integer> it = list.iterator();while(it.hasNext()){System.out.print(it.next()+" ");}}

相关文章:
Java_简单模拟实现ArrayList_学习ArrayList
文章目录 一、 了解线性表和顺序表区别1.线性表2.顺序表 二、模拟实现1.定义接口2.定义MyArrayList3.成员变量以及构造方法4.实现打印数组5.实现add方法6.实现查找某个数是否存在contains或者某个数的下标indexOf7.获取或更改pos位置的值 get和set8.获取数组大小 size9.删除某个…...
动手学深度学习(一)深度学习介绍2
目录 二、起源 三、深度学习的成功案例: 四、特点: 五、小结: 二、起源 为了解决各种各样的机器学习问题,深度学习提供了强大的工具。 虽然许多深度学习方法都是最近才有重大突破,但使用数据和神经网络编程的核心思…...
vmware网络配置,VMware的三种网络模式详解与配置
vmware为我们提供了三种网络工作模式 vmware为我们提供了三种网络工作模式, 它们分别是: Bridged(桥接模式)、NAT(网络地址转换模式)、Host-Only(仅主机模式)。 VMware虚拟机的三种网络类型的适用场景如下…...
【Ubuntu】安装hbase
前提 需要安装java 安装 HBase 下载并解压 HBase 安装包: wget https://dlcdn.apache.org/hbase/2.5.7/hbase-2.5.7-bin.tar.gz tar -zxvf hbase-2.5.7-bin.tar.gz配置 HBase 环境变量: export HBASE_HOME/path/to/hbase-2.5.7 export PATH$PATH:$H…...
ubuntu16.04环境轻松安装和应用opencv4.9.0(基于源码编译)
目录 一、环境准备 1、安装cmake 2、安装依赖 3、从github上下载opencv4.9.0.zip 二、安装opencv4.9.0 1、解压4.9.0.zip 2、进入build目录编译 3、安装编译好的相关库 4、修改opencv配置文件并使其生效 5、添加PKG_CONFIG路径,并使其生效 三、opencv环境…...
FastBee开源物联网平台2.0开源版发布啦!!!
一、项目介绍 物美智能(wumei-smart)更名为蜂信物联(FastBee)。 FastBee开源物联网平台,简单易用,更适合中小企业和个人学习使用。适用于智能家居、智慧办公、智慧社区、农业监测、水利监测、工业控制等。 系统后端采用Spring boot;前端采用…...
【NeRF和NLP】一些观察感悟,碎碎念
NeRF的paper,有几个感想: NeRF读的时候感觉和diffusion思路特别像,训练目标是一个很小很小的子步骤,大大简化了训练难度NeRF建模的是“真实”世界,其用模型隐含的存储了真实世界的体素(场)模型…...
Python程序设计 基础数据类型
1.1 编程规范 注释 python注释也有自己的规范,在文章中会介绍到。注释可以起到一个备注的作用,团队合作的时候,个人编写的代码经常会被多人调用,为了让别人能更容易理解代码的通途,使用注释是非常有效的。 在说规范…...
浅谈安科瑞智能照明系统在马来西亚国家石油公司项目的应用
摘要:随着社会经济的发展及网络技术、通信技术的提高,人们对照明设计提出了新的要求,它不仅要控制照明光源的发光时间、 亮度,而且与其它系统来配合不同的应用场合做出相应的灯光场景。本文介绍了马亚西亚石油公司智能照明项目的应…...
Java面对对象
Java面向对象 面对对象概述,类与对象,继承,重写与重载,多态,抽象,封装,包,泛型,异常 面对对象概述 什么是面向对象(OOP) 面向对象(Object Ori…...
代码随想录算法训练营|day24
第七章 回溯算法 77.组合代码随想录文章详解总结 77.组合 以n5,k3为例 (1)for循环遍历,递归选择符合要求的值加入path,len(path)k时,返回 statrtIndex保证每次递归取到的值不重复 剪枝:i<n-(k-len(path))1 后续需要k-len(pat…...
嵌入式学习日记 16
共用体 union 共用体名 { 成员列表; //各个变量 }; //表示定义一个共用体类型 注意: 1.共用体 初始化 --- 只能给一个值,默认是给到第一个成员变量的 2.共用体成员变量辅助 共用体用的数据最终存储的 --- 应该是最后一次给到的值。 但是只能…...
【Vue.js设计与实现】第一篇:框架设计概览-阅读笔记(完结)
从高层设计的角度去探讨框架需要关注的问题。 参考:速读《Vue.js 设计与实现》 - 掘金 (juejin.cn) 系列目录: 标题博客第一篇:框架设计概览【Vue.js设计与实现】第一篇:框架设计概览-阅读笔记第二篇:响应系统【Vue.…...
数据结构—动态查找表
动态查找介绍 1. 动态查找的引入:当查找表以线性表的形式组织时,若对查找表进行插入、删除或排序操作,就必须移动大量的记录,当记录数很多时,这种移动的代价很大。 2. 动态查找表的设计思想:表结构本身是…...
Hbase-2.4.11_hadoop-3.1.3集群_大数据集群_SSH修改默认端口22为其他端口---记录025_大数据工作笔记0185
其实修改起来非常简单,但是在大数据集群中,使用到了很多的脚步,也需要修改, 这里把,大数据集群,整体如何修改SSH端口,为22022,进行总结一下: 0.hbase-2.4.11的话,hbase集群修改默认SSH端口22,修改成22022,需要修改 需要修改/opt/module/hbase-2.4.11/conf/hbase-env.sh 这里…...
c++学习第十四讲---STL常用容器---vector容器
vector容器: 1.vector基本概念: vector功能与数组类似,与数组不同的是,vector可以动态扩展。 2.vector构造函数: vector<T> v; //默认构造函数,创建数据类型T的容器 ve…...
数据结构-内部排序
简介 排序(Sorting):将一个数据元素(或记录)的任意序列,重新排列成一个按关键字有序的序列 排序算法分为内部排序和外部排序 内部排序:在排序期间数据对象全部存放在内存的排序 外部排序&am…...
Qt加载网页崩溃 ASSERT:“m_adapterClient“ in file ...
1、软件启动后加载网页无异常,点击按钮,加载新网页时崩溃 崩溃代码: QWebEngineView *createWindow(QWebEnginePage::WebWindowType type) { Q_UNUSED(type); return this; } 2、原因 Qt只是调用谷歌的浏览器引擎ÿ…...
合约短线高胜率策略-扭转乾坤指标使用说明
扭转乾坤指标使用说明 行情判断 双绿线 多趋势双红线 空趋势大绿线 小红线 多震荡大红线 小绿线 空震荡 进场条件 趋势行情进场 多趋势 多信号 底金叉 做多空趋势 空信号 顶死叉 做空 震荡行情进场 多震荡 多信号 底金叉 做多多震荡 空信号 顶死叉 做空空…...
DAY37:贪心算法738
今天写了一道题目,顺便看了一个很好的总结,这篇博客可以跳过。 Leetcode:738 单调递增的数字 因为最大的数字是9,当出现后面位数的数字比前面位数的数字小的时候,就把后面的数字都变成9,前面那个数字--。…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
