数据结构入门到入土——ArrayList与顺序表

目录

一,线性表

二,顺序表

1.接口实现

三,ArrayList简介

四,ArrayList使用

1.ArrayList的构造

2.ArrayList常见操作

3.ArrayList的遍历

4.ArrayList的扩容机制

五,ArrayLisit的具体使用

杨辉三角


一,线性表

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

二,顺序表

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

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();//判断顺序表是否为空public boolean isEmpty();
}

接口实现:

import java.util.Arrays;public class MyArrayList implements IList{public int[] elem;public int usedSize;public static final int DEFINE_SIZE = 10;public MyArrayList() {this.elem = new int[DEFINE_SIZE];}public MyArrayList(int capacity) {this.usedSize = capacity;}@Override//新增元素,默认在数组最后新增//1.检查数组是否已满//2.满了扩容,未满新增//usedSize++public void add(int data) {if (isFull()) {elem = Arrays.copyOf(elem,2 * elem.length);}this.elem[this.usedSize] = data;this.usedSize++;}public boolean isFull() {return this.usedSize ==elem.length;}@Override//在 pos 位置新增元素//1.检查数组是否已满//2.满了扩容//3.未满:在指定位置新增,原位置有元素就向后挪//4.usedSize++public void add(int pos, int data) {if (isFull()) {elem = Arrays.copyOf(elem,2 * elem.length);}//新增int i = this.usedSize;while (i > pos) {elem[i] = elem[i-1];i--;}this.elem[pos] = data;usedSize++;}@Override// 判定是否包含某个元素//1.顺序表是否为空//2.查找元素public boolean contains(int toFind) {if (isEmpty()) {return false;}//查找元素if (findVal(toFind) != 0) {return true;}return false;}public int findVal(int val) {for (int i = 0; i < elem.length; i++) {if (elem[i] == val) {return i;}}return 0;}public boolean isEmpty() {return usedSize == 0;}@Override// 查找某个元素对应的位置// 1.判断是否为空// 2.为空抛空List异常// 3.查找元素// 4.获取下标public int indexOf(int toFind) throws EmptyListException{if (isEmpty()) {throw new EmptyListException("空List异常");}//查找if (findVal(toFind) == 0) {//查询不到异常throw new NotFindException("NotFindException");}return findVal(toFind);}@Override// 获取 pos 位置的元素// 1.判断是否为空// 2.判断pos位置是否合法// 3.获取public int get(int pos) {if (isEmpty()) {throw new EmptyListException("空List异常");}if (checkPos(pos)) {//pos位置不合法throw new PosException("pos位置不合法");}return this.elem[pos];}private boolean checkPos(int pos) {if (pos < 0 || pos >= this.usedSize) {return true;}return false;}@Override// 给 pos 位置的元素设为 value// 1.判断是否为空// 2.判断pos位置是否合法// 3.设置public void set(int pos, int value) {if (isEmpty()) {throw new EmptyListException("空List异常");}if (checkPos(pos)) {//pos位置不合法throw new PosException("pos位置不合法");}this.elem[pos] = value;}@Override// 删除第一次出现的关键字key// 是否为空?// 查找关键字public void remove(int toRemove) {if (isEmpty()) {throw new EmptyListException("空List异常");}for (int i = indexOf(toRemove);i < this.usedSize - 1;i++) {elem[i] = elem[i+1];}usedSize--;}@Override// 获取顺序表长度public int size() {return this.usedSize;}@Override// 清空顺序表public void clear() {this.usedSize = 0;}@Overridepublic void display() {System.out.print("[");if (this.usedSize == 0) {System.out.println("]");}for (int i = 0; i < this.usedSize; i++) {if (i == this.usedSize - 1) {System.out.println(this.elem[i] + "]");} else {System.out.print(this.elem[i] + ",");}}}
}

三,ArrayList简介

在集合框架中,ArrayList是一个普通的类,实现了List接口,具体框架图如下:
【说明】
1. ArrayList 是以泛型方式实现的,使用时必须要先实例化
2. ArrayList 实现了 RandomAccess 接口,表明 ArrayList 支持随机访问
3. ArrayList 实现了 Cloneable 接口,表明 ArrayList 是可以 clone
4. ArrayList 实现了 Serializable 接口,表明 ArrayList 是支持序列化的
5. Vector 不同, ArrayList 不是线程安全的,在单线程下可以使用,在多线程中可以选择 Vector 或者CopyOnWriteArrayList
6. ArrayList 底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表

四,ArrayList使用

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

}

2.ArrayList常见操作

ArrayList虽然提供的方法比较多,但是常用方法如下所示,需要用到其他方法时,可行查阅使用。
方法解释
boolean add (E e)
尾插e
void add (int index, E element)
将e插入到index位置
boolean addAll (Collection<? extends E> c)
尾插e中的元素
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));

// listindex位置插入指定元素,index及后续的元素统一往后搬移一个位置

list.add(1, "Java数据结构");

System.out.println(list);

// 删除指定元素,找到了就删除,该元素之后的元素统一往前搬移一个位置

list.remove("JVM");

System.out.println(list);

// 删除listindex位置上的元素,注意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());

}

3.ArrayList的遍历

ArrayList的遍历有三种方式:for()+下标,for-each,使用迭代器

public static void main(String[] args) {
   
List<Integer> list1 = new ArrayList<>();
   
list1.add(1);
   
list1.add(2);
   
list1.add(3);
   
list1.add(4);
   
list1.add(5);
   
//使用for()+下标遍历
   
for (int i = 0; i < list1.size(); i++) {
       
System.out.print(list1.get(i) + " ");
    }
   
System.out.println(" ");
   
//使用for-each遍历
   
for (Integer integer:list1) {
       
System.out.print(integer + " ");
    }
   
System.out.println(" ");
   
//使用迭代器遍历
   
Iterator<Integer> it = list1.iterator();
   
while (it.hasNext()) {
       
System.out.print(it.next() + " ");
    }
   
System.out.println(" ");
}

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

4.ArrayList的扩容机制

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

Object[] elementData; // 存放元素的空间

private static fifinal Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; // 默认空间

private static fifinal 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++;

// overflflow-conscious code

if (minCapacity - elementData.length > 0)

grow(minCapacity);

}

private static fifinal 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)

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;

}

总结

1. 检测是否真正需要扩容,如果是调用grow准备扩容

2. 预估需要库容的大小

•   初步预估按照1.5倍大小扩容

•   如果用户所需大小超过预估1.5倍大小,则按照用户所需大小扩容

•   真正扩容之前检测是否能扩容成功,防止太大导致扩容失败

3. 使用copyOf进行扩容

五,ArrayLisit的具体使用

杨辉三角

class Solution {//求杨辉三角方法public List<List<Integer>> generate(int numRows) {List<List<Integer>> ret = new ArrayList<>();//二维数组List<Integer> list = new ArrayList<>();list.add(1);ret.add(list);for (int i = 1; i < numRows; i++) {List<Integer> curRow = new ArrayList<>();//当前行List<Integer> prevRow = ret.get(i-1);//上一行curRow.add(1);//当前行首个元素为1for (int j = 1; j < i; j++) {int val = prevRow.get(j-1) + prevRow.get(j);curRow.add(val);}curRow.add(1);//当前行最后一个元素为1ret.add(curRow);}return ret;}
}
public class Test {//方法使用public static void main(String[] args) {Solution solution = new Solution();List<List<Integer>> mylist = new ArrayList<>();mylist = solution.generate(3);for (int i = 0; i < 3; i++) {List<Integer> arr = mylist.get(i);System.out.println(arr);}}
}

完。

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

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

相关文章

【SpringMVC】常用注解

什么是MVC&#xff1f; MVC是一种程序分层开发模式&#xff0c;分别是Model&#xff08;模型&#xff09;&#xff0c;View&#xff08;视图&#xff09;以及Controller&#xff08;控制器&#xff09;。这样做可以将程序的用户界面和业务逻辑分离&#xff0c;使得代码具有良好…

虚拟机快照

1.为什么使用快照 在学习阶段我们无法避免的可能损坏Linux操作系统。 如果损坏的话&#xff0c;重新安装一个Linux操作系统就会十分麻烦。 VMware虚拟机&#xff08;Workstation和Funsion&#xff09;支持为虚拟机制作快照。 通过快照将当前虚拟机的状态保存下来&#xff0c;在…

CentOS 7.6下的HTTP隧道代理配置详解

在CentOS 7.6操作系统中&#xff0c;配置HTTP隧道代理需要一定的技术知识和经验。下面我们将详细介绍如何配置HTTP隧道代理&#xff0c;以确保网络通信的安全性和稳定性。 首先&#xff0c;我们需要了解HTTP隧道代理的基本原理。HTTP隧道代理是一种通过HTTP协议传输其他协议数…

SSM农产品朔源管理系统----计算机毕业设计

项目介绍 本项目分为前后台&#xff0c;分为普通用户、管理员、企业用户三种角色&#xff1b; 普通用户无需登录&#xff0c;可在前台直接进行溯源查询&#xff0c;管理员、企业用户可登录后台进行管理&#xff1b; 超级管理员角色包含以下功能&#xff1a; 登录,管理企业,设…

用友U8 Cloud smartweb2.RPC.d XXE漏洞复现

0x01 产品简介 用友U8 Cloud 提供企业级云ERP整体解决方案,全面支持多组织业务协同,实现企业互联网资源连接。 U8 Cloud 亦是亚太地区成长型企业最广泛采用的云解决方案。 0x02 漏洞概述 用友U8 Cloud smartweb2.RPC.d接口处存在 XXE漏洞,攻击者可通过该漏洞获取敏感文件…

云卷云舒:【实战篇】Redis迁移

1. 简介 Remote Dictionary Server(Redis)是一个由Salvatore Sanfilippo写的key-value存储系统&#xff0c;是一个开源的使用ANSIC语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并提供多种语言的API。 2. 迁移原理 redis-sh…

性能优化-OpenMP基础教程(三)

本文主要介绍OpenMP并行编程的环境变量和实战、主要对比理解嵌套并行的效果。 &#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;高性能&#xff08;HPC&#xff09;开发基础教程 &#x1f380;CSDN主页 发狂的小花 &…

麒麟镜像下载

试用版下载链接 产品试用申请国产操作系统、银河麒麟、中标麒麟、开放麒麟、星光麒麟——麒麟软件官方网站 下载自己对应的操作系统 我下载的是 共享文件下载 - Kylin Distro 然后用迅雷下载就可以了

基于sumo实现交通灯控制算法的模板

基于sumo实现交通灯控制算法的模板 目录 在windows安装run hello world networkroutesviewsettings & configurationsimulation 交通灯控制系统 介绍文件生成器类&#xff08;FileGenerator&#xff09;道路网络&#xff08;Network&#xff09;辅助函数生成道路网络&am…

SOFA Framework源代码及插件Win11编译开发环境配置

这篇文章主要记录详细的SOFA Framework软件的源代码编译环境配置过程&#xff0c;开发环境基于Win系统&#xff0c;编译完成后&#xff0c;可以在插件或框架的源代码上进行开发集成。本文纯手写输入&#xff0c;言简意赅&#xff0c;以大方向和思路为准&#xff0c;具体需要注意…

什么是Alibaba Cloud Linux?完全兼容CentOS,详细介绍

Alibaba Cloud Linux是基于龙蜥社区OpenAnolis龙蜥操作系统Anolis OS的阿里云发行版&#xff0c;针对阿里云服务器ECS做了大量深度优化&#xff0c;Alibaba Cloud Linux由阿里云官方免费提供长期支持和维护LTS&#xff0c;Alibaba Cloud Linux完全兼容CentOS/RHEL生态和操作方式…

Ubuntu22.04系统安装软件、显卡驱动、cuda、cudnn、pytorch

Ubuntu22.04系统安装软件、显卡驱动、cuda、cudnn、pytorch 安装 Nvidia 显卡驱动安装 CUDA安装 cuDNN安装 VSCode安装 Anaconda 并更换源在虚拟环境中安装 GPU 版本的 PyTorchReference 这篇博文主要介绍的是 Ubuntu22.04 系统中软件、显卡驱动、cuda、cudnn、pytorch 等软件和…

ubuntu 安装 anaconda

ubuntu 安装 anaconda 下载 wget https://repo.anaconda.com/archive/Anaconda3-2023.09-0-Linux-x86_64.sh安装 bash Anaconda3-2023.09-0-Linux-x86_64.sh2.1 回车继续 2.2 许可协议 输入 q 退出阅读许可协议 2.3 输入 yes 接受 许可协议 2.4 设置 anaconda 安装位置 如不需…

轻松获取CHATGPT API:免费、无验证、带实例

免费获取和使用ChatGPT API的方法 快速开始&#xff1a;视频教程 章节一&#xff1a;GPT-API-Free开源项目介绍 GPT-API-Free 是一个开源项目&#xff0c;它提供了一个中转API KEY&#xff0c;使用户能够调用多个GPT模型&#xff0c;包括gpt-3.5-turbo、embedding和gpt-4。这…

C#中的值和引用笔记

文章目录 1. 简单介绍2. 如何判断值类型和引用类型3. 语句块4. 变量的生命周期5. 结构体中的值和引用6. 数组中的存储规则7. 结构体继承接口 1. 简单介绍 2. 如何判断值类型和引用类型 在代码中直接转到内部F12 如string类型 值类型int 3. 语句块 4. 变量的生命周期 5. 结构…

实现网页跟随系统主题切换

如何实现网页跟随系统主题切换&#xff1f;想必大家都是用过媒体查询media (prefers-color-scheme: dark) 实现亮/暗主题的切换&#xff0c;那如何让其跟随系统自动切换呢&#xff1f;在window对象上&#xff0c;有matchMedia这个API可以帮助我们解决这个问题。它和css中的媒体…

聚类分析 | Matlab实现基于RIME-DBSCAN的数据聚类可视化

聚类分析 | Matlab实现基于RIME-DBSCAN的数据聚类可视化 目录 聚类分析 | Matlab实现基于RIME-DBSCAN的数据聚类可视化效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.聚类分析 | Matlab实现基于RIME-DBSCAN的数据聚类可视化&#xff08;完整源码和数据) 2.多特征输入&…

Ubuntu 本地部署 ChatGPT-Next-Web

Ubuntu 本地部署 ChatGPT-Next-Web 文章目录 Ubuntu 本地部署 ChatGPT-Next-Web ChatGPT-Next-Web 项目地址&#xff1a;https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web 本文主要演示如何在 Ubuntu 本地&#xff08;默认是端口 3000&#xff09;部署 ChatGPT-Next-Web&am…

【unity小技巧】FPS游戏实现相机的震动、后坐力和偏移

最终效果 文章目录 最终效果前言相机的震动实现后坐力和偏移相机震动相机震动脚本换弹节点震动 武器射击后退效果完结 前言 关于后坐力之前其实已经分享了一个&#xff1a;FPS游戏后坐力制作思路 但是实现起来比较复杂&#xff0c;如果你只是想要简单的实现&#xff0c;可以看…

tolist()读取Excel列数据,(Excel列数据去重后,重新保存到新的Excel里)

从Excel列数据去重后&#xff0c;重新保存到新的Excel里 import pandas as pd# 读取Excel文件 file r"D:\\pythonXangmu\\quchong\\quchong.xlsx" # 使用原始字符串以避免转义字符 df pd.read_excel(file, sheet_namenameSheet)# 删除重复值 df2 df.drop_duplica…