Java 数据结构深入理解ArrayList与顺序表

Java 数据结构深入理解ArrayList与顺序表攻略

1. 什么是ArrayList?

ArrayList是Java集合框架中的一个类,是一个基于动态数组实现的可变大小的容器。

与传统的静态数组相比,ArrayList可以动态地增加和减少元素的个数,而无需预先指定数组的大小,并且ArrayList是支持泛型的,能够存储任意类型的对象。

ArrayList的接口定义如下所示:

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {

    // 构造函数
    public ArrayList()

    ... // 其他方法

}

2. ArrayList的实现原理

ArrayList的底层是一个Object类型的数组,它动态地扩容和收缩。

ArrayList已经占满了当前数组的空间,再往其中添加元素时,会先创建一个新的底层数组,长度是旧数组的1.5倍,并将旧的数组中的元素复制到新的数组中,然后再将新的元素添加进去。如果插入或删除元素时,ArrayList的大小低于1/4,则会将底层数组的长度缩减到当前长度的1/2。

由于ArrayList底层是数组,因此它查询元素的速度非常快,但是插入和删除元素的操作速度相对较慢。如果涉及到大量的元素插入和删除操作,使用链表类的集合可能更加适合。

3. 顺序表的实现

顺序表是一种常见的线性数据结构,它由一组连续的存储空间构成,用来存储同类型的元素。顺序表中的每个元素都可以通过下标来访问,所以查询元素的时间复杂度为O(1)。但是插入和删除元素的操作速度相对较慢,需要移动其他元素的位置。

以下是一个简单的顺序表的实现:

public class MyArrayList<T> {

    private T[] array;
    private int size;

    public MyArrayList(int capacity) {
        this.array = (T[])new Object[capacity];
        this.size = 0;
    }

    ...
}

其中,array是用来存储元素的数组,size是当前元素的个数。可以通过在构造函数中传入参数capacity来指定数组的大小。

实现顺序表的基本操作,如插入元素、删除元素、查询元素等,可以参考以下代码:

public class MyArrayList<T> {

    ...

    // 在指定位置插入元素
    public void add(int index, T element) {
        if (index < 0 || index > size) {
            throw new ArrayIndexOutOfBoundsException();
        }

        // 判断容量,如果已经满了,需要进行扩容
        if (size == array.length) {
            int newCapacity = array.length * 2;
            T[] newArray = (T[])new Object[newCapacity];
            System.arraycopy(array, 0, newArray, 0, array.length);
            array = newArray;
        }

        // 将index之后的元素往后移一位
        for (int i = size; i > index; i--) {
            array[i] = array[i-1];
        }

        // 将元素插入到index处
        array[index] = element;
        size++;
    }

    // 删除指定位置的元素
    public void remove(int index) {
        if (index < 0 || index >= size) {
            throw new ArrayIndexOutOfBoundsException();
        }

        // 将index之后的元素往前移一位
        for (int i = index; i < size - 1; i++) {
            array[i] = array[i+1];
        }

        size--;
    }

    // 查询指定位置的元素
    public T get(int index) {
        if (index < 0 || index >= size) {
            throw new ArrayIndexOutOfBoundsException();
        }

        return array[index];
    }

    // 返回当前元素的数量
    public int size() {
        return size;
    }
}

4. 示例说明

示例1:使用ArrayList存储字符串

import java.util.ArrayList;

public class TestArrayList {

    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();

        list.add("apple");
        list.add("banana");
        list.add("orange");

        System.out.println(list); // 输出:[apple, banana, orange]
    }

}

在这个示例中,我们使用ArrayList存储了三种水果的名称,然后通过System.out.println输出了整个列表。

示例2:使用自定义的顺序表存储整数

public class TestMyArrayList {

    public static void main(String[] args) {
        MyArrayList<Integer> list = new MyArrayList<>(3);

        list.add(0, 1);
        list.add(1, 2);
        list.add(2, 3);
        list.add(1, 4);

        System.out.println(list.get(0)); // 输出:1
        System.out.println(list.get(1)); // 输出:4
        System.out.println(list.get(2)); // 输出:2
        System.out.println(list.get(3)); // 输出:3

        list.remove(1);

        System.out.println(list.get(0)); // 输出:1
        System.out.println(list.get(1)); // 输出:2
        System.out.println(list.get(2)); // 输出:3
    }

}

在这个示例中,我们使用自定义的MyArrayList存储了四个整数,然后通过System.out.println输出了指定位置的元素。接着,我们删除了第二个位置的元素,并再次输出了所有元素。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java 数据结构深入理解ArrayList与顺序表 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • Java IO及BufferedReader.readline()出现的Bug

    关于“Java IO及BufferedReader.readline()出现的Bug”,我们需要注意以下两点: 1. Java IO 中的缓存问题 Java的IO操作是基于缓存进行的,而很多读取函数如BufferedReader. readline()是以换行符作为结束标记的,但是我们在编写代码时常常忽略了特殊情况的处理,导致出现了缓存问题,例如一次读取操作…

    Java 2023年5月27日
    00
  • J2SE中的序列化的认识

    J2SE(Java 2 Standard Edition)中的序列化是指将Java对象转换为可以存储或传输的字节序列的过程,反之亦然。序列化是Java编程语言中非常重要的一种机制,使用Java序列化可以让开发者在不同的机器上传递对象,并在需要的时候读取或写入对象数据。以下是对J2SE中的序列化的认识的完整攻略: 什么是J2SE中的序列化? J2SE中的序列化…

    Java 2023年6月15日
    00
  • SpringBoot实现项目健康检查与监控

    实现项目健康检查与监控是一个较为常见的需求,可以通过Spring Boot Actuator提供的功能来轻松实现,下面是使用Spring Boot Actuator实现项目健康检查与监控的攻略: 1. 添加依赖 首先需要在项目中引入Spring Boot Actuator的相关依赖,在项目的pom.xml文件中添加以下依赖: <dependency&g…

    Java 2023年5月20日
    00
  • 实例详解Java中如何对方法进行调用

    下面我将为您详细讲解“实例详解Java中如何对方法进行调用”的完整攻略。 什么是Java方法? 在Java中,方法指的是一段可重复使用的代码块,它可以接收零个、一个或多个参数,并在执行完毕后返回一个值。Java中的方法如同其他编程语言中的函数或子程序一样,它们担任着封装和抽象的重要角色。 方法的调用 在Java中调用方法需要两个要素:方法名和参数。方法名是方…

    Java 2023年5月26日
    00
  • 多模字符串匹配算法原理及Java实现代码

    多模字符串匹配算法原理及Java实现代码攻略 多模字符串匹配算法是在一个文本串中同时匹配多个模式串的算法。常见的多模匹配算法有Trie树、AC自动机等,本文介绍的是KMP算法。 KMP算法原理 KMP算法的核心思想是利用已知信息,避免不必要的匹配。即:对于模式串中的每一个位置,找到该位置之前的子串的最长公共前后缀,并记录在next[]数组中。当匹配过程中发生…

    Java 2023年5月19日
    00
  • SpringMvc定制化深入探究原理

    以下是关于“SpringMVC定制化深入探究原理”的完整攻略,其中包含两个示例。 SpringMVC定制化深入探究原理 SpringMVC是一个基于MVC架构的Web框架,它提供了一种灵活、高效的方式来开发Web应用程序。在SpringMVC中,我们可以通过定制化来满足特定的需求。本攻略将深入探究SpringMVC定制化的原理,并提供两个示例。 定制化原理 …

    Java 2023年5月16日
    00
  • Java中数据库常用的两把锁之乐观锁和悲观锁

    Java中数据库常用的两把锁是乐观锁和悲观锁。 什么是乐观锁和悲观锁? 悲观锁 悲观锁假定在执行操作时会产生并发冲突,因此在操作数据前先加锁,确保操作数据时不会被其他人修改。悲观锁的典型实现就是数据库中的行锁、表锁。 在Java中,悲观锁常用的实现就是synchronized关键字和ReentrantLock类。 乐观锁 乐观锁假定在执行操作时不会产生并发冲…

    Java 2023年5月19日
    00
  • Java如何调用C++ DLL库

    Java与C++是不同语言,Java的运行环境JVM不能直接调用C++库。但是Java有一个机制可以通过Java Native Interfaces (JNI)来调用C++的动态链接库(DLL)文件。 下面是详细的步骤: 编写C++代码 首先,需要编写C++代码实现相应的函数。为了保证函数可以被调用,需要在函数前面加上__declspec(dllexport…

    Java 2023年5月24日
    00
合作推广
合作推广
分享本页
返回顶部