顺序表 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.     }


目录
相关文章
|
3月前
LinkedList的使用
LinkedList的使用
26 2
|
6月前
|
算法 安全
【顺序表ArrayList】
【顺序表ArrayList】
43 0
|
机器学习/深度学习 Java
泛型使用 && 包装类 && 顺序表与ArrayList &&顺序表和链表
泛型使用 && 包装类 && 顺序表与ArrayList &&顺序表和链表
55 0
|
存储 设计模式 算法
【数据结构】ArrayList和顺序表
【数据结构】ArrayList和顺序表
56 0
|
存储 Java
ArrayList与顺序表
ArrayList与顺序表
138 1
|
Java
ArrayList与LinkedList的遍历删除元素方法
ArrayList与LinkedList的遍历删除元素方法
302 0
|
存储 Java C语言
【Java数据结构】ArrayList顺序表
我们平时很喜欢使用的数组,就是顺序表! 下面我们将以 “模拟ArrayList” 的视角来盘一盘顺序表吧!
74 0
|
测试技术 索引
链表LinkedList介绍
链表LinkedList介绍
75 0
|
存储 Java 容器
LinkedList与链表
这篇文章我们来了解LinkedList,该部分涵盖内容较多,分多篇文章来完成,在下边的内容中有跳转链接。
96 0
LinkedList与链表