数据结构青铜到王者第三话---ArrayList与顺序表(1)

目录

一、线性表

二、顺序表

1、接口的实现

三、ArrayList的简介

四、ArrayList的使用

1、ArrayList的构造

2、ArrayList常见操作

3、ArrayList的遍历

4、ArrayList的扩容机制


一、线性表

线性表 ( linear list ) 是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列...

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。

二、顺序表

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

1、接口的实现

java 复制代码
public class SeqList {
     private int[] array;
     private int size;
 
    // 默认构造方法
     SeqList(){
     }
 
     // 将顺序表的底层容量设置为initcapacity
     SeqList(int initcapacity){
     }
 
     // 新增元素,默认在数组最后新增
    public void add(int data) {
        if(isFull()) {
            grow();
        }
        this.array[this.usedSize] = data;
        this.usedSize++;
    }

    private void grow() {
        this.array = Arrays.copyOf(this.array,
                2*this.array.length);
    }

    public boolean isFull() {
        return this.usedSize == array.length;
    }


    private void checkPos(int pos) throws PosIllegal{
        if(pos < 0 || pos > usedSize) {
            throw new PosIllegal("Pos位置不合法!!");
        }
    }
 
     // 在 pos 位置新增元素
    public void add(int pos, int data) {
        try {
            checkPos(pos);
            if(isFull()) {
                grow();
            }
            //挪动元素
            for(int i = usedSize-1;i >= pos; i--) {
                array[i+1] = array[i];
            }

            array[pos] = data;

            usedSize++;
        }catch (PosIllegal e) {
            System.out.println("插入元素pos位置不合法..");
            e.printStackTrace();
        }
    }
 
     // 判定是否包含某个元素
    public boolean contains(int toFind) {
        //array   usedSize
        for (int i = 0; i < usedSize; i++) {
            if(array[i] == toFind) {
                return true;
            }
        }
        return false;
    }
 
     // 查找某个元素对应的位置
     //否则返回-1
    public int indexOf(int toFind) {
        for (int i = 0; i < usedSize; i++) {
            if(array[i] == toFind) {
                return i;
            }
        }
        return -1;
    }
 
     // 获取 pos 位置的元素
     //否则返回-1
    public int get(int pos) {
        try {
            checkEmpty();
            checkPos2(pos);
            return array[pos];
        }catch (PosIllegal e) {
            e.printStackTrace();
        }catch (EmptyException e) {
            e.printStackTrace();
        }
        return -1;
    }
 
    private void checkEmpty() {
        if(isEmpty()) {
            throw new EmptyException("顺序表为空!");
        }
    }

    public boolean isEmpty() {
        return usedSize == 0;
    }

     // 给 pos 位置的元素设为 value
    public void set(int pos, int value) {
        try {
            checkEmpty();
            checkPos2(pos);
            array[pos] = value;
        }catch (PosIllegal e) {
            e.printStackTrace();
        }catch (EmptyException e) {
            e.printStackTrace();
        }
    }
 
     //删除第一次出现的关键字key
    public void remove(int toRemove) {
        try {
            checkEmpty();
            int pos = indexOf(toRemove);
            if(pos == -1) {
                return;
            }
            for (int i = pos; i < usedSize-1; i++) {
                array[i] = array[i+1];
            }
            usedSize--;
        }catch (EmptyException e) {
            e.printStackTrace();
        }
    }
 
     // 获取顺序表长度
    public int size() {
        return this.usedSize;
    }
 
     // 清空顺序表
    public void clear() {
       /* for (int i = 0; i < usedSize; i++) {
            array[i] = null;
        }*/
        usedSize = 0;
    }
 
     // 打印顺序表,注意:该方法并不是顺序表中的方法,为了方便看测试结果给出的
    public void display() {
        for (int i = 0; i < this.usedSize; i++) {
            System.out.print(array[i]+" ");
        }
       /*
       这里面所有都是 0
       for (int x : array) {
            System.out.print(x+" ");
        }*/
    }
 }

要注意的是,数据结构看起来感觉很简单,但是逻辑非常的严谨,因此代码可能会较多!!!

三、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的构造

java 复制代码
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虽然提供的方法比较多,但是常用方法如下所示

java 复制代码
 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);
    // 检测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循环+下标、foreach、使用迭代器

java 复制代码
 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();
 }

#注:ArrayList最长使用的遍历方式是:for循环+下标 以及 foreach

(迭代器是设计模式的一种,后序容器接触多了再给大家铺垫)

4、ArrayList的扩容机制

请问:下面代码有缺陷吗?为什么?

java 复制代码
 public static void main(String[] args) {
     List<Integer> list = new ArrayList<>();
     for (int i = 0; i < 100; i++) {
         list.add(i);
     }
 }

由于内容较多,会分为多篇讲解,预知后续内容,请看后续博客!!!

相关推荐
小xin过拟合3 小时前
day20 二叉树part7
开发语言·数据结构·c++·笔记·算法
刘 大 望3 小时前
网络编程--TCP/UDP Socket套接字
java·运维·服务器·网络·数据结构·java-ee·intellij-idea
今后1234 小时前
【数据结构】顺序表详解
数据结构·顺序表
啟明起鸣4 小时前
【数据结构】B 树——高度近似可”独木成林“的榕树——详细解说与其 C 代码实现
c语言·开发语言·数据结构
这周也會开心4 小时前
数据结构-ArrayList
数据结构
nonono4 小时前
数据结构——线性表(链表,力扣中等篇,技巧型)
数据结构·leetcode·链表
hrrrrb4 小时前
【数据结构】栈和队列——队列
数据结构
XMZH030424 小时前
数据结构:单向链表的逆置;双向循环链表;栈,输出栈,销毁栈;顺序表和链表的区别和优缺点;0825
数据结构·链表·
KarrySmile5 小时前
Day8--HOT100--160. 相交链表,206. 反转链表,234. 回文链表,876. 链表的中间结点
数据结构·算法·链表·双指针·快慢指针·hot100·灵艾山茶府