顺序表 ArrayList

简介: 顺序表 ArrayList

1. 概念

       ArrayList实现了List接口,它是在一个连续的储存块中储存元素,与数组不同的是,通过在序列尾部添加新的元素,ArrayList能进行动态的增长。顺序表一般情况下采用数组存储,在数组上完成数据的增删查改,并且访问其元素可以直接通过元素的索引直接访问和更新。

       注意:

  • ArrayList是一种动态数组。
  • ArrayList类是一种元素为Object引用的泛型集合。


2. ArrayList集合框架图

a344b4b28d124a609632db1a7d38c0ce.png

则:

  • ArrayList是泛型实现的,使用时必须进行实例化;
  • ArrayList实现了RandomAccess接口,则ArrayList支持随机访问;
  • ArrayList实现了Cloneabel接口,则ArrayList支持clone;

ArrayList实现了Serialzable接口,则ArrayList支持序列化;

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


3.ArrayList常见的方法

方法         解释
add(E e) 尾插一个元素e
add(int index,E e) 在index位置插入e
remove(int index)

删除index位置的元素

remove(Object o)

删除第一个遇到的o

get(int index) 获得index位置的元素
set(int index,E e) 将index位置的元素更新为e
clear() 清空ArrayList
indexOf(Object o) 返回第一个的o的下标
lastIndexOf(Object o) 返回最后一个o的下标
subList(int fromIndex,int toIndex) 截取[fromIndex,toIndex)的元素
contains(Object o) 判断是否包含o


4. 自己实现ArrayList(Integer)

4.1 ArrayList构造

public class MyArrayList {
    int[] elem;//储存元素
    public int usedSize = 0;//元素个数,ArrayList集合大小默认为0
    private static final int DEFAULT_SIZE = 10;//ArrayList集合容量默认为10
    //构造方法
    public MyArrayList(){
        this.elem = new int[DEFAULT_SIZE];
    }
    ...
}


4.2 ArrayList容量的扩容

       当ArrayList中的元素个数不小于容量时,要对容量进行扩容,就是将ArrayList中的元素克隆到更大的数组中。

    private void ensureCapacity() {
        //将原数组克隆在更大的数组中
        elem = Arrays.copyOf(elem,2*elem.length);
    }


4.3 判断空满

       空:元素为0,即usedSize为0;

       满:元素个数等于容量

    //空
    private boolean isEmpty() {
        return usedSize == 0;
    }
    //满
    public boolean isFull() {
        return usedSize == this.elem.length;
    }


4.4 pos坐标是否合法(含有)

       即pos>=0 && pos < usedSize;

    //是否合法
    public boolean checkPosInAdd(int pos) {
        return pos >= 0 && pos < usedSize;//合法
    }


4.5 ArrayList的增删元素

       在尾插元素的时候,要判断是否具有足够的容量,如果不具有,要进行扩容,即调用4.2中ensureCapacity()方法。

在具体位置插入元素的时候,要判断坐标是否合法,不能大于数组大小,若大于,抛出异常。

       在删除元素的时候,要判断坐标是否合法,不能大于数组大小,若大于,抛出异常,也要判断是否存在这个元素,若不存在,返回 -1。

   // 新增元素,默认在数组最后新增
    public void add(int data) {
        if(isFull()){
            ensureCapacity();
        }
        this.elem[usedSize] = data;
        usedSize++;
    }
    // 在 pos 位置新增元素
    public void add(int pos, int data) {
        if(!checkPosInAdd(pos)){
            throw new ArrayIndexOutOfBoundsException("数组越界");
        }else{
            this.elem[pos] = data;
            usedSize++;
        }
    }
    //删除第一次遇到的key
    public void remove(int key) {
        if(isEmpty()){
            return;
        }
        int index = indexOf(key);
        if(index == -1){
            return;
        }
        for (int i = index; i < usedSize - 1; i++) {
            elem[i] = elem[i + 1];
        }
        usedSize--;
    }
    //删除index坐标的元素
    public void removeIndex(int index){
        if(!checkPosInAdd(index)){
            throw new ArrayIndexOutOfBoundsException("不合法");
        }else{
            for (int i = index; i < usedSize; i++) {
                elem[i] = elem[i + 1];
            }
            usedSize--;
        }
    }


4.6 包含元素

       即遍历整个数组,是否含有这个元素;

    // 判定是否包含某个元素
    public boolean contains(int toFind) {
        for (int i :
                this.elem) {
            if (i == toFind){
                return true;
            }
        }
        return false;
    }


4.7 get 和 set

       可以根据索引直接返回和更新值,但是需要注意合法;不合法,抛出异常;

    // 获取 pos 位置的元素
    public int get(int pos) {
        if(!checkPosInAdd(pos)){
            throw new ArrayIndexOutOfBoundsException("数组越界");
        }else{
            return elem[pos];
        }
    }
    // 给 pos 位置的元素设为【更新为】 value
    public void set(int pos, int value) {
        if(!checkPosInAdd(pos)){
            throw new ArrayIndexOutOfBoundsException("越界");
        }else {
            elem[usedSize] = value;
            usedSize++;
        }
    }


4.8 获得第一个元素坐标

       直接遍历数组,第一次碰到的这个元素,返回坐标,没有返回-1;

    // 查找某个元素对应的位置
    public int indexOf(int toFind) {
        for(int i = 0; i < usedSize; i++){
            if(elem[i] == toFind){
                return i;
            }
        }
        return -1;
    }


4.9 打印ArrayList

       可以直接遍历整个数组,进行打印;

    public void display() {
        for (int i = 0; i < usedSize; i++) {
            System.out.print(elem[i] + " ");
        }
        System.out.println();
    }


4.10 清空ArrayList

       直接将usedSize大小变为0即可;

1. // 清空顺序表
2. public void clear() {
3.         usedSize = 0;
4.     }


目录
相关文章
|
存储 NoSQL Redis
【Redis】利用Redis List实现数据库分页快速查询
【Redis】利用Redis List实现数据库分页快速查询
873 0
HH
|
物联网
阿里云物联网平台基于MQTT.fx完成OTA升级
物联网平台提供OTA升级与管理服务。下面介绍OTA升级消息的Topic和Alink数据格式,包括设备上报OTA模块版本、物联网平台推送升级包信息、设备上报升级进度和设备请求获取最新升级包信息。
HH
4653 0
阿里云物联网平台基于MQTT.fx完成OTA升级
|
机器学习/深度学习 算法 关系型数据库
强化学习:动态规划求解最优状态价值函数——手把手教你入门强化学习(四)
本文介绍了基于模型的强化学习算法,重点讲解动态规划(DP)。动态规划通过分解问题为子问题求解状态价值函数,利用贝尔曼期望方程迭代更新。其核心性质包括最优子结构和重叠子问题,适用于已知转移概率和奖励的MDP场景。文章回顾了前期强化学习基础,并展望了后续内容如蒙特卡罗法。适合初学者系统了解强化学习算法原理与应用。
532 7
|
存储 运维 资源调度
阿里云服务器经济型e实例解析:性能、稳定性与兼顾成本
阿里云经济型e云服务器以其高性价比、稳定可靠的性能以及灵活多样的配置选项,成为了众多企业在搭建官网时的首选。那么,阿里云经济型e云服务器究竟怎么样?它是否能够满足企业官网的搭建需求?本文将从性能表现、稳定性与可靠性、成本考虑等多个方面对阿里云经济型e云服务器进行深入剖析,以供大家参考选择。
759 37
|
JSON API 开发者
1688店铺所有商品API接口(1688API系列)
1688店铺所有商品API接口允许开发者通过输入店铺ID,获取指定店铺内的全部商品信息,包括名称、价格、库存、图片和销售数据等。该接口支持排序和分页参数,返回JSON格式数据,便于解析和应用。Python示例展示了如何使用requests库发送GET请求并处理响应,助力电商数据分析与业务拓展。
|
存储 监控 安全
服务器维护是确保服务器稳定运行、数据安全和性能优化的重要过程
【10月更文挑战第4天】服务器维护是确保服务器稳定运行、数据安全和性能优化的重要过程
433 65
|
人工智能 搜索推荐 机器人
[AI Mem0] 概览,智能自我改进记忆层
[AI Mem0] 概览,智能自我改进记忆层
|
存储 算法 C++
C++一分钟之-容器概览:vector, list, deque
【6月更文挑战第21天】STL中的`vector`是动态数组,适合随机访问,但插入删除非末尾元素较慢;`list`是双向链表,插入删除快但随机访问效率低;`deque`结合两者优点,支持快速双端操作。选择容器要考虑操作频率、内存占用和性能需求。注意预分配容量以减少`vector`的内存重分配,使用迭代器而非索引操作`list`,并利用`deque`的两端优势。理解容器内部机制和应用场景是优化C++程序的关键。
469 5
|
存储 算法 数据格式
一篇文章讲明白Mipmap与纹理过滤
一篇文章讲明白Mipmap与纹理过滤
598 1
|
应用服务中间件 数据库 nginx
nginx 第三方模块 与变量
nginx 第三方模块 与变量

热门文章

最新文章