【数据结构】顺序表与ArrayList

集合

java中的集合像一个容器,是用来存放对象的容器,按照其存储结构分为两大类:单例集合Collection和双列集合Map,其特点如下:

  1. Collection:单例集合的根接口,存放一系列的符合某种规则的元素,其有两个子接口,List和Set;其中,List接口的特点为:元素有序,可重复;Set集合的特点为:元素无序,不可重复
  2. Map:双列集合的根接口,存储具有键(key),值(value)映射关系的元素。

HashMap:底层为哈希桶,查询时间复杂度为O(1)
TreeSet:底层为红黑树,查询的时间复杂度为O( ㏒₂N),关于key有序的

  1. Stack: 栈,实现了一个后进先出的数据结构。
  2. Queue:队列。
  3. Deque:接口
  4. SortedMap:使 Key 保持在升序排列。
  5. Set:集合,是一个接口,里面放置的是K模型

HashSet:底层为哈希桶,查询的时间复杂度为O(1);
TreeSet:底层为红黑树,查询的时间复杂度为O(㏒₂N ),关于key有序的
在这里插入图片描述

List接口

我们按照顺序来介绍下面的接口和类
在这里插入图片描述

Iterable接口

实现该接口的类是可以逐个元素遍历的,具体方法如下:
在这里插入图片描述

Collection接口

该接口为其规定了单列集合的通用 方法:
在这里插入图片描述

List接口

List接口提供专属于List特有的方法
在这里插入图片描述
我们介绍一下List的常用方法

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        /**
         * boolean add(E e) 尾插e
         */
        list.add(5);
        list.add(4);
        list.add(4);
        list.add(3);
        list.add(2);
        list.add(1);
        /**
         * void add(int index, E element) 把元素e插入index位置
         */
        list.add(0,1);
        /**
         *  boolean addAll(Collection<? extends E> c) 尾插c中属于元素
         */
        List<Integer> list1 = new ArrayList<>();
        list1.add(6);
        list.addAll(list1);
        /**
         * boolean removeAll(int index) 删除index位置的元素
         */
        list.remove(1);
        /**
         * boolean remove(Object o) 删除遇到的第一个o
         */
        list.remove(new Integer(3));
        /**
         * E get(int index) 获取下标 index 位置元素
         */
        int elem = list.get(2);
        System.out.println(elem);
        /**
         * E set(int index, E element) 将下标 index 位置元素设置为 element
         */
        list.set(2,13);
        System.out.println(list.get(2));
        /**
         * boolean contains(Object o) 判断 o 是否在线性表中
         */
        System.out.println(list.contains(new Integer(13)));
        /**
         *int indexOf(Object o) 返回第一个 o 所在下标
         */
        System.out.println(list.indexOf(new Integer(13)));
        //list.indexOf(13) 这样也可以,会自动装箱
        /**
         * int lastIndexOf(Object o) 返回最后一个 o 的下标
         */
        System.out.println(list.lastIndexOf(1));
        /**
         * List<E> subList(int fromIndex, int toIndex) 截取部分 list
         */
        list1 = list.subList(0,4);//左闭右开[0,4)
        list1.set(0,13);
        //修改截取部分的元素,原本的元素也会发生改变
        System.out.println(list.get(0));
        /**
         * void clear() 清空
         */
        System.out.println(list.toString());
        list.clear();
        System.out.println(list.toString());
    }

ArrayList与顺序表

线性表

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

在这里插入图片描述

顺序表

顺序表在物理地址上是连续的,在其存储单元是依次存储数据元素的线性结构,一般是用数组来存储

ArrayList介绍

在这里插入图片描述

解释:
接口说明:

  1. RandomAccess接口:标识实现该接口的类支持快速随机访问。
  2. Cloneable接口 : 作用是使一个类的实例能够将自身拷贝到另一个新的实例中.
  3. Serializable接口: 实现java.io.Serializable 接口的类是可序列化的
    ArrayList类拥有上面接口的特性
  • 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者
    CopyOnWriteArrayList
  • ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表

ArrayList使用

ArrayList构造器

方法说明
public ArrayList(int initialCapacity)根据参数值创建该大小的ArrayList
public ArrayList()无参构造
ArrayList(Collection<? extends E> c)接受Collection接口的容器构建ArrayList

一般情况下。我们都是用无参构造方法;但提供观察源代码,我们发现最开始是一个空数组
在这里插入图片描述
现在我们add一些元素
在这里插入图片描述

结论:利用无参构造时,默认为空数组;只有在第一次add时,大小才变为10;扩容为1.5倍扩容

ArrayList操作方法

package Package1;

import java.util.ArrayList;
import java.util.List;

public class Test1 {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        /**
         * boolean add(E e) 尾插e
         */
        list.add(1);
        list.add(12);
        list.add(123);
        list.add(1234);
        list.add(12345);
        /**
         * public int size() 获取容器有效元素个数
         */
        System.out.println(list.size());
        /**
         * void add(int index, E element) 把元素e插入index位置
         */
        list.add(0,12345);
        /**
         *  boolean addAll(Collection<? extends E> c) 尾插c中属于元素
         */
        List<Integer> list1 = new ArrayList<>();
        list1.add(123456);
        list.addAll(list1);
        /**
         * boolean removeAll(int index) 删除index位置的元素
         */
        list.remove(1);
        /**
         * boolean remove(Object o) 删除遇到的第一个o
         */
        list.remove(new Integer(123456));
        /**
         * E get(int index) 获取下标 index 位置元素
         */
        int elem = list.get(1);
        System.out.println(elem);
        /**
         * E set(int index, E element) 将下标 index 位置元素设置为 element
         */
        list.set(2,13);
        System.out.println(list.get(2));
        /**
         * boolean contains(Object o) 判断 o 是否在线性表中
         */
        System.out.println(list.contains(1234));
        /**
         *int indexOf(Object o) 返回第一个 o 所在下标
         */
        System.out.println(list.indexOf(12345));
        /**
         * int lastIndexOf(Object o) 返回最后一个 o 的下标
         */
        System.out.println(list.lastIndexOf(12345));
        /**
         * List<E> subList(int fromIndex, int toIndex) 截取部分 list
         */
        list1 = list.subList(0,2);//左闭右开[0,2)
        list1.set(0,13);
        //修改截取部分的元素,原本的元素也会发生改变
        System.out.println(list.get(0));
        /**
         * void clear() 清空
         */
        System.out.println(list.toString());
        list.clear();
        System.out.println(list.toString());

    }
}

ArrayList的遍历

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            list.add(i);
        }
        /**
         * for循环
         */
        //普通for循环
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i) + " ");
        }
        //For-each循环
        for (Integer x : list) {
            System.out.print(x + " ");
        }
        /**
         * 链表转数组
         */
        Integer[] intArray = new Integer[list.size()];
        list.toArray(intArray);
        for (int x :intArray) {
            System.out.print(x + " ");
        }
        for (int i = 0; i < intArray.length; i++) {
            System.out.print(intArray[i] + " ");
        }
        /**
         * 迭代器
         */
        Iterator<Integer> it = list.iterator();
        while (it.hasNext()) {
            System.out.print(it.next() + " ");
        }

迭代器

在这里插入图片描述

ListIterator 是 Collection中的接口, 它扩展了 Iterator 接口,新增了多个方法;

方法解释
E next()返回迭代器的下一个元素,并且更新迭代器的状态。
boolean hasNext()检测集合中是否还有元素
void remove()将迭代器返回的元素删除
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Hello");
        list.add("Wow");
        list.add("Hi");
        ListIterator<String> it = list.listIterator();
        it.add("qqq");
        while (it.hasNext()) {
            //返回迭代器当前指向的元素的下标
            System.out.print(it.nextIndex()+" ");
            //得到迭代器中的下一个元素,并且更新迭代器状态
            System.out.print(it.next() + " ");
        }
    }

ArrayListde的模拟实现

package Package1;

import java.lang.*;
import java.util.Arrays;



public class SeqList {
    private int[] MyArrayList = new int[5];
    private int usedSize;

    // 打印顺序表
    public void display() {
        for (int i = 0; i < usedSize ; i++) {
            System.out.print(MyArrayList[i] + " ");
        }
        System.out.println();
    }
    // 新增元素,默认在数组最后新增
    public void add(int data) {
        //判断是否满
        if (isFull()) {
            grow();
        }
        this.MyArrayList[usedSize++] = data;
    }
    //检查数组是否满
    public boolean isFull() {
//        if(usedSize == ArrayList.length) {
//            return true;
//        }
//        return false;
        //代码可以优化
        return this.usedSize == MyArrayList.length;
    }
    //扩容
    public void grow() {
        MyArrayList = Arrays.copyOf(MyArrayList,MyArrayList.length*2);
    }
    //判断pos是否合法
    private void check(int pos) {
        if (pos < 0 || pos > this.usedSize) {
            throw new MyArrayIndexOutOfBoundsException("pos下标越界");
        }
    }
    // 在 pos 位置新增元素
    public void add(int pos, int data) {
        check(pos);
        //是否需要扩容
        if (isFull()) {
            grow();
        }
        //插入元素
        //方法1:
        for (int i = usedSize - 1; i >= pos ; i--) {
            this.MyArrayList[i + 1] = this.MyArrayList[i];
        }
        //方法2:
        //System.arraycopy(MyArrayList,pos,MyArrayList,pos+ 1,usedSize - pos);
        this.MyArrayList[pos] = data;
        usedSize++;
    }
    // 判定是否包含某个元素
    public boolean contains(int toFind) {
        for (int i = 0; i < usedSize; i++) {
            if (MyArrayList[i] == toFind) {
                return true;
            }
        }
        return false;
    }
    // 查找第一次元素对应的位置
    public int indexOf(int toFind) {
        for (int i = 0; i < usedSize; i++) {
            if (MyArrayList[i] == toFind) {
                return i;
            }
        }
        return -1;
    }
    // 查找最后出现元素对应的位置
    public int lastIndexOf(int toFind) {
        int index = -1;
        for (int i = usedSize - 1; i >= 0; i--) {
            if (this.MyArrayList[i] == toFind) {
                index = i;
            }
        }
        return index;
    }
    // 获取 pos 位置的元素
    public int get(int pos) {
        check(pos);
        return this.MyArrayList[pos];
    }
    // 给 pos 位置的元素设为 value
    public void set(int pos, int value) {
        //判断pos是否合法
        check(pos);
        this.MyArrayList[pos] = value;
    }
    //判断顺序表是否为空
    public boolean isEmpty() {
        return this.MyArrayList.length == 0;
    }
    //删除第一次出现的关键字key
    public void remove(int toRemove) {
        //顺序表是否为空
        if (isEmpty()) {
            throw new MyArrayIsEmptyException("链表为空!");
        }
        //查找是否含有该元素
        if (!contains(toRemove)) {
            throw new MyArrayListNoSuchElementException("不存在该元素");
        }
        int index = indexOf(toRemove);
        for (int i = index; i < usedSize; i++) {
            this.MyArrayList[i] = this.MyArrayList[i + 1];
        }
        usedSize--;
    }
    // 获取顺序表长度
    public int size() {
        return this.usedSize;
    }
    // 清空顺序表
    public void clear() {
        for (int i = 0; i < usedSize; i++) {
            MyArrayList[i] = 0;
        }
        usedSize = 0;
    }
}

public class MyArrayIndexOutOfBoundsException extends RuntimeException{
    public MyArrayIndexOutOfBoundsException() {
        super();
    }

    public MyArrayIndexOutOfBoundsException(String message) {
        super(message);
    }
}
public class MyArrayIsEmptyException extends RuntimeException{
    public MyArrayIsEmptyException() {
        super();
    }

    public MyArrayIsEmptyException(String message) {
        super(message);
    }
}
public class MyArrayListNoSuchElementException extends RuntimeException{
    public MyArrayListNoSuchElementException() {
        super();
    }

    public MyArrayListNoSuchElementException(String message) {
        super(message);
    }
}

常用工具类

Collections工具类

Collections类提供大量的静态方法来对集合元素进行排序,查找,修改等操作,下面我们学习一些常用方法:

排序,添加操作

方法解释
public static void shuffle(List<?> list)对list中元素随机排序
public static boolean addAll(Collection<? super T> c, T… elements)把 T… elements中元素全部添加到list中
public static void reverse(List<?> list)对list所有元素逆序
public static void swap(List<?> list, int i, int j)交换list中指定元素
public static <T extends Comparable<? super T>> void sort(List list)对list按照自然属性排序
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 6; i++) {
            list.add(i);
        }
        Collections.shuffle(list);
        System.out.println(list);
        Collections.addAll(list,11,22,33);
        System.out.println(list);
        Collections.reverse(list);
        Collections.swap(list,0,2);
        Collections.sort(list);
        System.out.println(list);
    }

查找,替换操作

方法解释
int binarySearch(List T key)二分查找法,首先保证集合有序
public static T max(Collection coll)返回最大值
public static T min(Collection coll)返回最小值
public static boolean replaceAll(List list, T oldVal, T newVal)把所有oldVal替换为newVal
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        Collections.addAll(list,1,2,3,4,5,6,1,2,3,8,6);
        Collections.sort(list);
        System.out.println(Collections.binarySearch(list, 1));
        System.out.println(Collections.max(list));
        System.out.println(Collections.min(list));
        Collections.replaceAll(list,4,1);
        System.out.println(list);
    

Arrays工具类

听名字可以知道这个是针对数组的工具类,它提供大量处理数组的静态方法,如排序,操作,拷贝,替换等操作

方法解释
public static void sort(int[] a)按照自然顺序排序
public static String toString(int[] a)数组转为字符串
public static int[] copyOf(int[] original, int newLength)返回newLength长度的数组,通常用于扩容
public static int binarySearch(int[] a, int key)有序的前提下,二分查找
public static int[] copyOfRange(int[] original, int from, int to)把[form.to)的元素拷贝到新数组并返回
public static void fill(int[] a, int val)把数组中所有元素替换为val
    public static void main(String[] args) {
        int[] arr = {1,2,3,9,8,7,6,3,4};
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));
        arr = Arrays.copyOf(arr,arr.length*2);
        System.out.println(Arrays.binarySearch(arr, 4));
        int[] copyArray = Arrays.copyOfRange(arr,0,arr.length);
        System.out.println(Arrays.toString(copyArray));
        Arrays.fill(arr,1);
        System.out.println(Arrays.toString(arr));
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zzt.opkk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值