当前位置: 首页 > news >正文

ArrayList与顺序表(带完整实例)

【本节目标】
1. 线性表
2. 顺序表
3. ArrayList的简介
4. ArrayList使用
5. ArrayList的扩容机制
6. 扑克牌

1.线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列...
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储

2. 顺序表

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

2.1 接口的实现

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() ;public boolean isFull();
}

3. ArrayList 简介

在集合框架中,ArrayList是一个普通的类,实现了List接口,具体框架图如下:

[说明]

1.ArrayList是以泛型方式 实现的,使用时必须先实例化

2.ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问

3.ArrayList实现了Cloneable接口,表明ArrayList是可以clone的

4.ArrayList实现了Serializable接口,表明ArratList是支持序列化的

5.和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者CopyOnWriteArrayList

6.6. ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表

4.  ArrayList使用

4.1 ArrayList的构造

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

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);
}

4.2 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);
比特就业课
4.3 ArrayList的遍历
ArrayList 可以使用三方方式遍历:for循环+下标、foreach、使用迭代器
注意:
1. ArrayList最长使用的遍历方式是:for循环+下标 以及 foreach
2. 迭代器是设计模式的一种,后序容器接触多了再给大家铺垫// 检测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());
}

4.3 ArrayList的遍历

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();
}

注意:
1. ArrayList最长使用的遍历方式是:for循环+下标 以及 foreach
2. 迭代器是设计模式的一种,后序容器接触多了再给大家铺垫

5. ArrayList的扩容机制

ArrayList是一个动态类型的顺序表,即:在插入元素的过程中会自动扩容。以下是ArrayList源码中扩容方式:

Object[] elementData;  // 存放元素的空间
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};  // 默认空间
private static final int DEFAULT_CAPACITY = 10;  // 默认容量大小
public boolean add(E e) {ensureCapacityInternal(size + 1);  // Increments modCount!!elementData[size++] = e;return true;
}
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {return Math.max(DEFAULT_CAPACITY, minCapacity);}return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {modCount++;// overflow-conscious codeif (minCapacity - elementData.length > 0)grow(minCapacity);
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private void grow(int minCapacity) {// 获取旧空间大小int oldCapacity = elementData.length;// 预计按照1.5倍方式扩容int newCapacity = oldCapacity + (oldCapacity >> 1);// 如果用户需要扩容大小 超过 原空间1.5倍,按照用户所需大小扩容if (newCapacity - minCapacity < 0)
比特就业课
【总结】
1. 检测是否真正需要扩容,如果是调用grow准备扩容
2. 预估需要库容的大小
初步预估按照1.5倍大小扩容
如果用户所需大小超过预估1.5倍大小,则按照用户所需大小扩容
真正扩容之前检测是否能扩容成功,防止太大导致扩容失败
3. 使用copyOf进行扩容
5. ArrayList的具体使用
5.1 简单的洗牌算法newCapacity = minCapacity;// 如果需要扩容大小超过MAX_ARRAY_SIZE,重新计算容量大小if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);// 调用copyOf扩容elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {// 如果minCapacity小于0,抛出OutOfMemoryError异常if (minCapacity < 0)throw new OutOfMemoryError();return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;

比较复杂,都是源码,cv过来的

【总结】
1. 检测是否真正需要扩容,如果是调用grow准备扩容
2. 预估需要库容的大小
初步预估按照1.5倍大小扩容
如果用户所需大小超过预估1.5倍大小,则按照用户所需大小扩容
真正扩容之前检测是否能扩容成功,防止太大导致扩容失败
3. 使用copyOf进行扩容

5.一个帮助大家掌握ArrayList的实例

刚开始接触有点难,可以多试几次

简单的洗牌算法,因为没有大小王,所以是52张牌

public class Card {public int rank;public String suit;public Card(int rank, String suit) {this.rank = rank;this.suit = suit;}
@Overridepublic String toString(){return this.rank+this.suit+" ";
}
}
import java.util.ArrayList;
import java.util.List;
import java.util.Random;public class CardDemo {public static final String[] Suits = {"♦", "♣", "♥", "♠"};public static List<Card> buydesk() {List<Card> desk = new ArrayList<>(52);for (int i = 0; i < 4; i++) {for (int j = 1; j <= 13; j++) {String suit = Suits[i];Card card = new Card(j, suit);desk.add(card);}}return desk;}public static void brush(List<Card> desk) {Random random = new Random();for (int i = 0; i < desk.size() - 1; i++) {int a = random.nextInt(52);swap(desk, i, a);}}private static void swap(List<Card> desk, int i, int a) {Card card = desk.get(i);desk.set(i, desk.get(a));desk.set(a, card);}public static void getCard(List<Card> desk) {List<List<Card>> hands = new ArrayList<>();hands.add(new ArrayList<>());hands.add(new ArrayList<>());hands.add(new ArrayList<>());for (int i = 0; i < 5; i++) {for (int j = 0; j < 3; j++) {hands.get(j).add(desk.remove(0));}}System.out.println("hand1"+hands.get(0));System.out.println("hand1"+hands.get(1));System.out.println("hand1"+hands.get(2));}public static void main(String[] args) {List<Card> desk = buydesk();System.out.println("刚买回来的");System.out.println(desk);System.out.println("洗牌");brush(desk);System.out.println("洗牌之后");System.out.println(desk);System.out.println("抓牌");getCard(desk);System.out.println("剩余的牌"+desk);}
}

大家多多尝试,有不理解的也可以私信.....

相关文章:

ArrayList与顺序表(带完整实例)

【本节目标】 1. 线性表 2. 顺序表 3. ArrayList的简介 4. ArrayList使用 5. ArrayList的扩容机制 6. 扑克牌 1.线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表…...

智能冶钢厂环境监控与设备控制系统(边缘物联网网关)

目录 1、项目背景 2、项目功能介绍 3、模块框架 3.1 架构框图 3.2 架构介绍 4、系统组成与工作原理 4.1 数据采集 4.2 指令控制 4.3 其他模块 4.3.1 网页、qt视频流 4.3.2 qt搜索进程 5、成果呈现 6、问题解决 7、项目总结 1、项目背景 这个项目的背景是钢铁行业的…...

【Python】conda镜像配置,.condarc文件详解,channel镜像

1. conda 环境 安装miniconda即可&#xff0c;Miniconda 安装包可以到 http://mirrors.aliyun.com/anaconda/miniconda/ 下载。 .condarc是conda 应用程序的配置文件&#xff0c;在用户家目录&#xff08;windows&#xff1a;C:\users\username\&#xff09;&#xff0c;用于…...

实战章节:在Linux上部署各类软件

详细资料见文章的资源绑定 一、前言 1.1 为什么学习各类软件在Linux上的部署 在前面&#xff0c;我们学习了许多的Linux命令和高级技巧&#xff0c;这些知识点比较零散&#xff0c;同学们跟随着课程的内容进行练习虽然可以基础掌握这些命令和技巧的使用&#xff0c;但是并没…...

铭飞CMS list 接口 SQL注入漏洞复现

0x01 产品简介 铭飞CMS是一款基于java开发的一套轻量级开源内容管理系统,铭飞CMS简洁、安全、开源、免费,可运行在Linux、Windows、MacOSX、Solaris等各种平台上,专注为公司企业、个人站长快速建站提供解决方案 0x02 漏洞概述 铭飞CMS在5.2.10版本以前list 接口处存在sql注入…...

Linux指令初始

1.ls指令 语法 &#xff1a; ls [ 选项 ][ 目录或文件 ] 功能 &#xff1a;对于目录&#xff0c;该命令列出该目录下的所有子目录与文件。对于文件&#xff0c;将列出文件名以及其他信息。 ls 常用&#xff1a;-a 列出目录下的所有文件&#xff0c;包括以 . 开头的隐含文件。 …...

Nginx命令---启动nginx

介绍 使用命令启动nginx。 命令 nginx目录/bin/nginx...

【UE5】监控摄像头效果(下)

目录 效果 步骤 一、多摄像机视角切换 二、摄像头自动旋转巡视 三、摄像头跟踪拍摄 效果 步骤 一、多摄像机视角切换 1. 打开玩家控制器“MyPlayerController”&#xff0c;添加一个变量&#xff0c;命名为“BP_SecurityCameraArray”&#xff0c;类型为“BP_SecurityCa…...

binkw32.dll丢失怎么办?这5个方法都可以解决binkw32.dll丢失问题

binkw32.dll文件是什么&#xff1f; binkw32.dll是一个动态链接库文件&#xff0c;它是Windows操作系统中的一个重要组件。它包含了许多用于处理多媒体文件的函数和资源&#xff0c;如视频、音频等。当我们在电脑上打开或播放某些多媒体文件时&#xff0c;系统会调用binkw32.d…...

C语言-每日刷题练习

[蓝桥杯 2013 省 B] 翻硬币 题目背景 小明正在玩一个“翻硬币”的游戏。 题目描述 桌上放着排成一排的若干硬币。我们用 * 表示正面&#xff0c;用 o 表示反面&#xff08;是小写字母&#xff0c;不是零&#xff09;&#xff0c;比如可能情形是 **oo***oooo&#xff0c;如果…...

Qt设置类似于qq登录页面(ikun)

头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QWindow> #include <QIcon> #include <QLabel> #include <QMovie> #include <QLineEdit> #include <QPushButton>QT_BEGIN_NAMESPACE namespace Ui { class…...

Qt 如何使用VTK显示点云

开发环境 ubuntu 20.04 VTK 8.2 编译VTK 下载源码 git clone --recursive https://gitlab.kitware.com/vtk/vtk.git 使用版本管理工具&#xff0c;切换版本到8.2 更改编译选项&#xff0c;这里使用cmake-gui进行配置 1、编译类型修改为Release 2、安装路径可以设置&#xf…...

Ganache结合内网穿透实现远程或不同局域网进行连接访问

文章目录 前言1. 安装Ganache2. 安装cpolar3. 创建公网地址4. 公网访问连接5. 固定公网地址 前言 Ganache 是DApp的测试网络&#xff0c;提供图形化界面&#xff0c;log日志等&#xff1b;智能合约部署时需要连接测试网络。 Ganache 是一个运行在本地测试的网络,通过结合cpol…...

Qt槽函数不响应不执行的一种原因:ui提升导致重名

背景&#xff1a; 一个包含了组件提升的ui&#xff0c;有个按钮的槽函数就是不响应&#xff0c;于是找原因。 分析&#xff1a; 槽函数的对应一是通过connect函数绑定信号&#xff0c;二是on_XXX_signal的命名方式。界面上部件的槽函数通常是第二种。 我反复确认细节&#…...

vuepress路径问题,导致图片不显示

图片不显示&#xff0c;报 Uncaught SyntaxError: Unexpected token <错误 很可能就是&#xff1a;路径配置原因 1.当设置为 / 时&#xff0c;VuePress 会假设你的站点将部署到服务器的根路径&#xff0c; 例如 https://yourdomain.com/。 2.生成的页面链接和资源引用将以…...

QT 重定向qdebug输出到自绘界面

因为在嵌入式中调试qt需要查看输出信息,特意写了一个类用户便捷查看qdebug信息 界面如下: 提供了开始,停止,保存,清空,退出功能,具体代码下文给出 文件如下 #ifndef QDEBUGREDIRECT_H #define QDEBUGREDIRECT_H /**qdebug 重定向类 定向到界面控件*李吉磊 2023.12.7* */#in…...

前端(一):HTML+CSS

参考课程&#xff1a;23最新版web前端开发_哔哩哔哩_bilibili 文档&#xff1a;GitHub - codeNiuMa/HTML-md-file: 学习HTML课程时的资料 目录 1 HTML 1.1 骨架 DOCTYPE html标签 head标签 body标签 title标签 meta标签 1.2 标签标题h1 1.3 段落p 1.4 水平线 1.5 图片img 1.6 …...

如何使用Matlab完成窗口与子窗口

目录 一、前言 二、主窗口与主窗口按钮 三、子窗口 四、调用函数并显示在子窗口中的文本框中 五、关闭子窗口 一、前言 有时候需要借用Matlab完成一个图窗功能&#xff0c;但是我们的程序不仅拥有功能&#xff0c;还拥有一些子功能&#xff0c;那么我们该如何借助Matlab完…...

Threejs之相机基础

参考资料 正投影相机…相机控件MapControls 知识点 注&#xff1a;基于Three.jsv0.155.0 正投影相机正投影相机-Canvas尺寸变化包围盒Box3地图案例(包围盒、正投影)相机动画(.position和.lookAt())不同方向的投影视图旋转渲染结果(.up相机上方向)管道漫游案例OrbitControls…...

2024SIA上海国际轴承工业展览会 ▎参行业盛会 展轴研风采

2024SIA上海国际轴承工业展览会 内容&#xff1a;1、轴承制品展区&#xff1a;2、轴承设备展区&#xff1a;3、轴承零件展区&#xff1a; 国际轴承展丨轴承工业展丨轴承装备展丨上海轴承展丨上海轴承工业展丨上海轴承装备展 2024上海国际轴承工业展览会将会于2024年7月24-26日…...

SQLMap介绍

预计更新SQL注入概述 1.1 SQL注入攻击概述 1.2 SQL注入漏洞分类 1.3 SQL注入攻击的危害 SQLMap介绍 2.1 SQLMap简介 2.2 SQLMap安装与配置 2.3 SQLMap基本用法 SQLMap进阶使用 3.1 SQLMap高级用法 3.2 SQLMap配置文件详解 3.3 SQLMap插件的使用 SQL注入漏洞检测 4.1 SQL注入…...

平头哥玄铁系列 RISC-V 芯片及开发板

1、玄铁 9 系列概述 玄铁 8 系列 基于C-SKY架构&#xff0c;玄铁 9 系列基于 RISC-V 架构。E 系列为 RISC-V 32 位&#xff0c;C 系列为 RISC-V 64 位。 E902&#xff1a;超低功耗 RSIC-V 架构处理器 E902 采用 2 级极简流水线兼容 RISC-V 架构且对执行效率等方面进行了增强&a…...

Android 删除浏览器导航页面修改默认主页

Android 删除浏览器导航页面修改默认主页 近来收到客户需求反馈&#xff0c;需要删除浏览器导航页面并将百度设置为默认主页&#xff0c;具体修改参照如下&#xff1a; 删除浏览器导航页面&#xff1a; /vendor/mediatek/proprietary/packages/apps/Browser/src/com/android…...

【Stm32-F407】Keil uVision5 下新建工程

①双击鼠标左键打开Keil uVision5&#xff0c;选择 Project 下的 New uVision Project &#xff1b; ②在期望的文件夹下创建一个工程&#xff0c;并按如下要求操作&#xff1b; ③添加文件类型&#xff0c;按如下要求操作 ④如有需要可添加相关启动文件在工程文件夹下并添加到…...

linux中文件服务器NFS和FTP服务

文件服务器 NFSNFS介绍配置nfs文件共享服务端客户端 FTPftp介绍FTP基础ftp主动模式ftp被动模式 Vsftp 服务器简介vsftpd配置安装vsftpd[ftp的服务端]编辑配置文件匿名用户设置创建本地用户使用ftp服务 客户端操作匿名用户登录本地用户登录lftp服务 NFS NFS介绍 文件系统级别共…...

茶室茶楼计时计费软件,软件中的商品管理计时操作教程

一、前言 茶室在营业的时候&#xff0c;不但需要计时间&#xff0c;同时还需要管理商品入库出库库存等管理。这就需要一款实用的操作简单的管理软件。 下面以 佳易王茶社计时计费软件V18.0为例说明&#xff0c;其他版本可以参考本教程。 软件下载或技术支持可以点击最下方官…...

从入门到精通:掌握Spring IOC/DI配置管理第三方bean的技巧

IOC/DI配置管理第三方bean 1.1 案例:数据源对象管理1.1.1 环境准备1.1.2 思路分析1.1.3 实现Druid管理步骤1:导入druid的依赖步骤2:配置第三方bean步骤3:从IOC容器中获取对应的bean对象步骤4:运行程序 1.1.4 实现C3P0管理步骤1:导入C3P0的依赖步骤2:配置第三方bean步骤3:运行程…...

Flink的容错机制

容错机制 容错&#xff1a;指出错后不影响数据的继续处理&#xff0c;并且恢复到出错前的状态。 检查点&#xff1a;用存档读档的方式&#xff0c;将之前的某个时间点的所有状态保存下来&#xff0c;故障恢复继续处理的结果应该和发送故障前完全一致&#xff0c;这就是所谓的检…...

GO设计模式——11、装饰器模式(结构型)

目录 装饰器模式&#xff08;Decorator Pattern&#xff09; 装饰器模式的核心角色&#xff1a; 优缺点 使用场景 代码实现 装饰器模式&#xff08;Decorator Pattern&#xff09; 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功…...

全志V3s之U-Boot

1、安装交叉编译器&#xff1a; ARM交叉编译器的官网&#xff1a;交叉编译器 a、使用wget下载&#xff1a; wget https://releases.linaro.org/components/toolchain/binaries/latest/arm-linux-gnueabihf/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf.tar.xzb、解…...