JavaDS —— 顺序表ArrayList
顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。在物理和逻辑上都是连续的。
模拟实现
下面是我们要自己模拟实现的方法:
首先我们要创建一个顺序表,顺序表包含一个数组,一个由于计数的计数器,还有一个默认的初始容量,我这里定义初始容量为5,比较好判断扩容是否成功。这里以整型数组为例:
private int[] array;private int usedSize;//目前数据总数private static final int DEFAULT_CAPACITY = 5;//默认容量
默认构造方法
这里我们直接在构造方法里给数组进行初始化:
public MyArrayList() {array = new int[DEFAULT_CAPACITY];}
尾插
尾插是指直接在所有数据的后面插入新数据,这里我们要注意数组容量是否已满,所以我们先写一个isFull方法判断数组是否容量已满:
private boolean isFull() {if(usedSize == array.length) {return true;}return false;}
这个方法设置成private是因为这个方法只是给本类的方法提供的,不需要对外公开。
如果数组已满,那么我们就需要扩容,这里我扩容2倍:
private void grow() {array = Arrays.copyOf(array,array.length * 2);}
现在来写尾插代码:
public void add(int data) {//判满if(isFull()) {grow();}//插入数据array[usedSize++] = data;}
pos位置插入数据
首先我们要先检查pos位置是否合法,如果不合法的话就不用进行插入操作,直接抛出异常,我们先写异常代码:
public class PosException extends RuntimeException{public PosException(String message) {super(message);}
}
检查pos位置是否合法:
private void checkPosInAdd(int pos) throws PosException {if(pos < 0 || pos > usedSize) {throw new PosException("pos位置不合法");}}
现在写插入代码,首先判断pos是否合法,然后判断是否要扩容,最后我们进行插入操作即可,在插入代码中,我们使用try-catch来处理异常。
public void add(int pos,int data) {try{checkPosInAdd(pos);//检查位置是否合法if(isFull()) { //判满grow();}//移动数据for (int i = usedSize; i >= pos ; i--) {array[i+1] = array[i];}//插入数据array[pos] = data;usedSize++;}catch (PosException e) {System.out.println("pos位置不合法!");e.printStackTrace();}}
contains
是否包含某个元素,使用布尔值进行返回,这里直接遍历数组查找即可。
public boolean contains(int toFind) {for (int i = 0; i < usedSize; i++) {if(array[i] == toFind){return true;}}return false;}
indexOf
查找某个元素的下标,找到则返回该元素的下标,没有找到则返回 -1
public int indexOf(int toFind) {for (int i = 0; i < usedSize; i++) {if(array[i] == toFind) {return i;}}return -1;}
get
找到pos位置的元素,这里要注意先判断pos是否合法,但是这里的检查pos和上面我们写过的checkPosInAdd是不一样的,这里的pos必须是有元素的下标范围,也就是不包含usedSize这个下标,因为这个是没有有效数据的,是待插入的空位,所以我们要再写一个检查pos方法:
private void checkPosInFind(int pos) throws PosException {if(pos < 0 || pos >= usedSize) {throw new PosException("pos位置不合法");}}
public int get(int pos) {try{checkPosInFind(pos);return array[pos];}catch (PosException e) {System.out.println("pos位置不合法!");e.printStackTrace();}return -1;}
set
更新pos位置的数据,还是要判断pos位置是否合法,这里使用发判断方法应该为checkPosInFind
public void set(int pos, int data) {try{checkPosInFind(pos);array[pos] = data;}catch (PosException e) {System.out.println("pos位置不合法!");e.printStackTrace();}}
remove
删除第一次出现的关键字key
public void remove(int key) {for (int i = 0; i < usedSize; i++) {if(array[i] == key) {for (int j = i; j < usedSize - 1; j++) {array[j] = array[j+1];}usedSize--;return;}}}
size
获取顺序表的长度,这里直接返回usedSize即可
public int size() {return usedSize;}
display
打印顺序表,该方法是便于测试,真正的顺序表并没有这个方法
public void display() {for (int i = 0; i < usedSize; i++) {System.out.print(array[i] + " ");}System.out.println();}
clear
清空顺序表,直接将usedSize赋值为0即可,下次使用的时候,会直接覆盖之前的数据的。
public void clear() {usedSize = 0;}
完整代码
import java.util.Arrays;public class MyArrayList {private int[] array;private int usedSize;//目前数据总数private static final int DEFAULT_CAPACITY = 5;//默认容量public MyArrayList() {array = new int[DEFAULT_CAPACITY];}/*判满,满则返回true,否则返回false*/private boolean isFull() {if(usedSize == array.length) {return true;}return false;}//扩容 2倍扩容private void grow() {array = Arrays.copyOf(array,array.length * 2);}//尾插public void add(int data) {//判满if(isFull()) {grow();}//插入数据array[usedSize++] = data;}//判断pos是否合法/*不合法则抛出异常增加方法*/private void checkPosInAdd(int pos) throws PosException {if(pos < 0 || pos > usedSize) {throw new PosException("pos位置不合法");}}//指定pos位置插入数据public void add(int pos,int data) {try{checkPosInAdd(pos);//检查位置是否合法if(isFull()) { //判满grow();}//移动数据for (int i = usedSize; i >= pos ; i--) {array[i+1] = array[i];}//插入数据array[pos] = data;usedSize++;}catch (PosException e) {System.out.println("pos位置不合法!");e.printStackTrace();}}//是否包含某个元素public boolean contains(int toFind) {for (int i = 0; i < usedSize; i++) {if(array[i] == toFind){return true;}}return false;}//查找某个元素的下标public int indexOf(int toFind) {for (int i = 0; i < usedSize; i++) {if(array[i] == toFind) {return i;}}return -1;}//判断pos是否合法/*查找方法不合法则抛出异常*/private void checkPosInFind(int pos) throws PosException {if(pos < 0 || pos >= usedSize) {throw new PosException("pos位置不合法");}}//获取pos位置的元素public int get(int pos) {try{checkPosInFind(pos);return array[pos];}catch (PosException e) {System.out.println("pos位置不合法!");e.printStackTrace();}return -1;}//更新pos位置的数据public void set(int pos, int data) {try{checkPosInFind(pos);array[pos] = data;}catch (PosException e) {System.out.println("pos位置不合法!");e.printStackTrace();}}//删除第一次出现的关键字keypublic void remove(int key) {for (int i = 0; i < usedSize; i++) {if(array[i] == key) {for (int j = i; j < usedSize - 1; j++) {array[j] = array[j+1];}usedSize--;return;}}}//获取顺序表的长度public int size() {return usedSize;}//打印顺序表,该方法是便于测试,真正的顺序表并没有这个方法public void display() {for (int i = 0; i < usedSize; i++) {System.out.print(array[i] + " ");}System.out.println();}//清空顺序表public void clear() {usedSize = 0;}
}
ArrayList 的使用
Java已经封装好顺序表供我们使用,就是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 的下标 |
更多详细的方法可自行查阅官方文档
上面很多方法是我们自己模拟实现过的,这里就不一一举例演示。
ArrayList 的成员方法
ArrayList 构造方法
一共提供了三个构造方法:
方法 | 解释 |
---|---|
ArrayList() | 无参构造 |
ArrayList(Collection<? extends E> c) | 利用其他 Colletion 构建 ArrayList |
ArrayList(int initialCapacity) | 指定顺序表初始容量 |
ArrayList(int initialCapacity)指定顺序表初始容量看一下源码还是很好理解的,初始容量大于零就开辟一块连续的空间,等于零就给一个空数组,小于零则抛出异常。
首先要知道下面的关系图:
从上图我们可以得知ArrayList是包含Collection这个接口的,所以可以接收Colletion的参数,Colletion后面的<? extends E> 中的 ? 是通配符,后面的文章会提到。
我们重点是看无参的构造方法:
直接赋值一个空数组,大家来看一下下面的代码,明明是空数组,但是为什么可以直接add而不会报错呢?
public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>();list.add(10);list.add(20);System.out.println(list);}
我们点过去看看源码是什么:
到了这里大家应该明白了,在使用add的时候,我们看到源码里写了当 s == 数组长度的时候,Java底层会帮我们自动扩容。
ArrayList 实例化
我们经常使用List或者ArrayList来接收顺序表实例化的对象.
List<Integer> list = new ArrayList<>();ArrayList<Integer> list2 = new ArrayList<>();
由于List是ArrayList的接口,所以可以接收,但是注意List是接口意味着不能进行实例化,使用List接收的参数只能使用List有点方法,由于ArrayList有很多接口,一定是拓展了很多东西的,如果List接口没有包含的方法,使用List接收的参数不能调用其他方法,但是使用ArrayList接收的话,所有ArrayList实现的方法都是可以调用的,只要是公开访问即可.
ArrayList 遍历方法
ArrayList 可以使用三方方式遍历:for循环+下标、foreach、使用迭代器,还可以直接打印里面的内容。
int size = list.size();for (int i = 0; i < size; i++) {System.out.print(list.get(i) + " ");}System.out.println();
无论是Integer还是int接收元素,Java底层会帮我们自动拆箱的.
for (int x: list) {System.out.print(x + " ");}System.out.println();for (Integer y: list) {System.out.print(y + " ");}System.out.println();
ListIterator<Integer> it = list.listIterator(list.size());while (it.hasPrevious()) {System.out.print(it.previous()+" ");}System.out.println();
Java的ArrayList的父类是重写过toString方法的.
System.out.println(list);
实践
杨辉三角
这里要注意 List<List< Integer>> ,这个意思表示外面的list的元素是list,里面的list的元素是Integer,例如下图所示:类似二维数组~
代码:
class Solution {public List<List<Integer>> generate(int numRows) {List<List<Integer>> list = new ArrayList<>();List<Integer> list0 = new ArrayList<>();list0.add(1);list.add(list0);for(int i=1;i<numRows;i++) {List<Integer> list1 = new ArrayList<>();for(int j=0;j<=i;j++) {if(j==0 || j==i) {list1.add(1);} else {list1.add(list.get(i-1).get(j-1) + list.get(i-1).get(j));}}list.add(list1);}return list;}
}
洗牌功能实现
public class Card {private int number;private String cardColor;public Card(int number, String cardColor) {this.number = number;this.cardColor = cardColor;}@Overridepublic String toString() {return "Card{" +cardColor + '\'' +number +'}';}
}
import java.util.ArrayList;
import java.util.List;
import java.util.Random;public class PlayCard {private static final String[] cardColor = {"♦","♣","♥","♠"};//购买52张牌public List<Card> buyCards() {List<Card> list = new ArrayList<>();for (int i = 1; i <= 13; i++) {for (int j = 0; j < 4; j++) {Card card = new Card(i,cardColor[j]);list.add(card);}}return list;}//洗牌public void shuffle(List<Card> list) {Random random = new Random();int size = list.size();for (int i = 0; i < size; i++) {int index = random.nextInt(size);//生成 0 ~ i-1 的随机数Card card = list.get(index);list.set(index,list.get(i));list.set(i,card);}}//发牌public List<List<Card>> deal(List<Card> cards) {List<List<Card>> list = new ArrayList<>();//创建三个人List<Card> list0 = new ArrayList<>();List<Card> list1 = new ArrayList<>();List<Card> list2 = new ArrayList<>();list.add(list0);list.add(list1);list.add(list2);int size = cards.size();int size2 = list.size();int count = 0;boolean flag = true;while(flag) {for (int j = 0; j < size2; j++) {list.get(j).add(cards.remove(0));count++;if(count == size){flag = false;break;}}}return list;}
}
这里要注意随机数的建立,首先先实例化Ramdom对象,然后使用nextInt方法,nextInt(int bound),生成的随机数范围是0~bound-1.
相关文章:

JavaDS —— 顺序表ArrayList
顺序表 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。在物理和逻辑上都是连续的。 模拟实现 下面是我们要自己模拟实现的方法: 首先我们要创建一个顺序表,顺序表…...
Sphinx 搜索配置
官方文档 http://sphinxsearch.com/docs/sphinx3.html 支持中文,英文,日文,韩文,俄罗斯语搜索 版本是 官网3.6.1版本 文件 sphinx.conf.dist 的windows 配置,官网下载下来后微微配置即可。 # Minimal Sphinx confi…...

如何在不关闭防火墙的情况下,让两台设备ping通
问题现象 如题,做虚拟机实验的时候,有一台linux系统的虚拟机配置的ip地址是192.168.172.181 物理主机的ip地址是192.168.172.1 此时物理主机可以ping通虚拟机 但是虚拟机不能ping通物理主机 此时我们可以想到,有可能是物理主机防火墙的原因。…...

windows USB 设备驱动开发-USB 等时传输
客户端驱动程序可以生成 USB 请求块 (URB) 以在 USB 设备中向/从常时等量端点传输数据。虽然USB设备一向以非等时传输出名,USB提供的是一种串行数据,而非等时,但是USB仍然设计了等时传输的机制,但根据笔者的经验,等时传…...
【文件共享 windows和linux】Windows Server 2016上开启文件夹共享,并在CentOS 7.4上访问和下载文件
要在Windows Server 2016上开启文件夹共享,并在CentOS 7.4上访问和下载文件,请按照以下步骤操作: 在Windows Server 2016上开启文件夹共享: 启用SMB服务: 打开“服务器管理器”。选择“文件和存储服务” > “共享…...

【知网CNKI-注册安全分析报告】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞…...

【Python_GUI】tkinter常用组件——文本类组件
文本时窗口中必不可少的一部分,tkinter模块中,有3种常用的文本类组件,通过这3种组件,可以在窗口中显示以及输入单行文本、多行文本、图片等。 Label标签组件 Label组件的基本使用 Label组件是窗口中比较常用的组件,…...

zdppy+onlyoffice+vue3解决文档加载和文档强制保存时弹出警告的问题
解决过程 第一次排查 最开始排查的是官方文档说的 https://api.onlyoffice.com/editors/troubleshooting#key 解决方案。参考的是官方的 https://github.com/ONLYOFFICE/document-server-integration/releases/latest/download/Python.Example.zip 基于Django的Python代码。 …...
C语言从头学31——与字符串变量相关的几个函数
strlen、strcpy、strcat、strcmp、sprintf这些函数都是与字符串相关的,除了sprintf是定义在stdio.h中外,其余几个都定义在string.h中,比较新的编译器版本stdio.h中已经含有string.h的内容,所以编程时不需要再包含string.h这个头文…...
Laravel批量插入数据:提升数据库操作效率的秘诀
Laravel批量插入数据:提升数据库操作效率的秘诀 Laravel作为PHP的现代Web应用框架,提供了优雅而简洁的方法来处理数据库操作。批量插入数据是数据库操作中常见的需求,尤其是在处理大量数据时,批量插入可以显著提高性能。本文将详…...
OpenCV:解锁计算机视觉的魔法钥匙
OpenCV:解锁计算机视觉的魔法钥匙 在人工智能与图像处理的世界里,OpenCV是一个响当当的名字。作为计算机视觉领域的瑞士军刀,OpenCV以其丰富的功能库、跨平台的特性以及开源的便利性,成为了开发者手中不可或缺的工具。本文将深入…...

手写简单模拟mvc
目录结构: 两个注解类: Controller: package com.heaboy.annotation;import java.lang.annotation.*;/*** 注解没有功能只是简单标记* .RUNTIME 运行时还能看到* .CLASS 类里面还有,构建对象久没来了,这个说明…...

【FreeRTOS】同步互斥与通信 FreeRTOS提供的方法
目录 各类方法的对比队列事件组信号量互斥量任务通知 各类方法的本质 使用全局变量可以实现通信,但是使用全局变量会有一些缺陷。 那我们怎么保证通信的正确性呢??? 我们需要引入很多互斥的方法。除了互斥之外,还需要高…...
Kafka 面试题指南
Kafka 面试题指南 本文档提供了一份详细的 Kafka 面试题指南,涵盖了 Kafka 的核心概念、架构、配置、操作和实际应用场景等方面的内容。希望通过这份指南能够帮助你在 Kafka 面试中取得成功。 目录 Kafka 基础知识 什么是 Kafka?Kafka 的主要特点是什…...

2024年7月5日 (周五) 叶子游戏新闻
老板键工具来唤去: 它可以为常用程序自定义快捷键,实现一键唤起、一键隐藏的 Windows 工具,并且支持窗口动态绑定快捷键(无需设置自动实现)。 卸载工具 HiBitUninstaller: Windows上的软件卸载工具 《乐高地平线大冒险》为何不登陆…...
热门开源项目推荐:探索开源世界的精彩
热门开源项目推荐 随着开源程序的发展,越来越多的程序员开始关注并加入开源大模型的行列。开源不仅为个人学习和成长提供了绝佳的平台,也为整个技术社区带来了创新和进步。无论你是初学者还是经验丰富的开发者,参与开源项目都能让你受益匪浅…...

Codeforces Round #956 (Div. 2) and ByteRace 2024(A~D题解)
这次比赛也是比较吃亏的,做题顺序出错了,先做的第三个,错在第三个数据点之后,才做的第二个(因为当时有个地方没检查出来)所以这次比赛还是一如既往地打拉了 那么就来发一下题解吧 A. Array Divisibility …...

基于YOLOv9的脑肿瘤区域检测
数据集 脑肿瘤区域检测,我们直接采用kaggle公开数据集,Br35H 数据中已对医学图像中脑肿瘤位置进行标注 数据集我已经按照YOLO格式配置好,数据内容如下 数据集中共包含700张图像,其中训练集500张,验证集200张 模型训…...

阿里云 ECS 服务器的安全组设置
阿里云 ECS 服务器的安全组设置 缘由安全组多个安全组各司其职一些常见的IP段百度 IP 段华为云 IP 段搜狗蜘蛛 IP 段阿里云 IP 段 。。。 缘由 最近公司规模缩减,原有的托管在 IDC 机房的服务器,都被处理掉了,所有代码都迁移到了阿里云的云服…...

昇思25天学习打卡营第15天|应用实践之ShuffleNet图像分类
基本介绍 今天的应用实践的领域是计算机视觉领域,更确切的说是图像分类任务,不过,与昨日不同的是,今天所使用的模型是ShuffleNet模型。ShuffleNetV1是旷视科技提出的一种计算高效的CNN模型,和MobileNet, SqueezeNet等一…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...