📜  如何在Java实现我们自己的动态数组类?(1)

📅  最后修改于: 2023-12-03 15:24:33.002000             🧑  作者: Mango

如何在Java实现我们自己的动态数组类?

当我们需要一个可变长度的数组时,Java提供了ArrayList类来满足我们的需求。但是,如果我们想了解ArrayList的实现原理,并能够自己编写一个动态数组类,就需要了解Java中的数组和泛型的使用,以及动态增加数组长度的原理。

数组和泛型

Java中的数组是一种有序的集合,其中所有元素必须具有相同的数据类型。数组中的元素可以通过索引来访问,索引从0开始,到数组长度减1结束。数组可以在声明时指定长度,也可以后期改变长度。

泛型是Java中的一种机制,用于定义许多常见的数据集合类型。我们可以使用泛型定义一个容器类,这个容器类可以存储任何类型的元素,并提供操作这些元素的方法。Java中的ArrayList类就是一个泛型容器类的例子,它可以像数组一样存储数据,并且可以自动调整大小。

动态增加数组长度的原理

在Java中,动态增加数组长度的实现并不是通过对原始数组进行增加或删除元素来实现的,而是通过创建一个新的数组来代替原数组,并将原数组中的内容复制到新数组中来实现的。这个过程通常是发生在原数组满了之后,需要添加一个新的元素时。

实现一个动态数组类

下面是一个简单的动态数组类的实现示例。在这个示例中,我们使用了泛型来定义这个类,这个类有一个成员变量“capacity”,表示当前数组的长度;还有一个成员变量“size”,表示当前数组中实际存储的元素个数。在这个类中,我们定义了一些常用的操作,例如添加元素、删除元素、获取元素等。如果当前数组的长度不够,我们就创建一个新数组来代替原数组,并将原数组中的内容复制到新数组中。

public class ArrayList<E> {

    private static final int DEFAULT_CAPACITY = 10;

    private int capacity;
    private int size;
    private Object[] elements;

    public ArrayList() {
        capacity = DEFAULT_CAPACITY;
        size = 0;
        elements = new Object[capacity];
    }

    public ArrayList(int capacity) {
        this.capacity = capacity;
        size = 0;
        elements = new Object[capacity];
    }

    public int size() {
        return size;
    }

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

    public void add(E element) {
        if (size == capacity) {
            increaseCapacity();
        }
        elements[size++] = element;
    }

    @SuppressWarnings("unchecked")
    public E remove(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("Index is out of bounds: " + index);
        }
        E element = (E) elements[index];
        for (int i = index; i < size - 1; i++) {
            elements[i] = elements[i + 1];
        }
        elements[--size] = null;
        return element;
    }

    @SuppressWarnings("unchecked")
    public E get(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("Index is out of bounds: " + index);
        }
        return (E) elements[index];
    }

    private void increaseCapacity() {
        capacity *= 2;
        Object[] newElements = new Object[capacity];
        System.arraycopy(elements, 0, newElements, 0, size);
        elements = newElements;
    }
}

在这个示例中,我们使用了两个构造函数,一个是使用默认容量的构造函数,一个是使用指定容量的构造函数。在add方法中,如果当前数组的长度不够,我们就调用increaseCapacity方法来增加数组长度。

在remove方法中,我们首先检查索引是否越界,然后返回要删除的元素,并将数组中元素向左移动一个位置,最后将数组长度减1。在get方法中,我们也首先检查索引是否越界,然后返回要获取的元素。

在increaseCapacity方法中,我们使用了Java中的System类的arraycopy方法,这个方法可以将一个数组中的一部分内容复制到另一个数组中。我们首先将原数组中的内容复制到新数组中,然后将新数组赋值给原数组即可。

总结

在Java中,我们可以通过自己实现一个动态数组类来深入了解Java中的数组和泛型的使用,以及动态增加数组长度的原理。当我们需要一个可变长度的数组时,可以使用Java提供的ArrayList类,并且,如果我们需要一个更加个性化的数组类时,我们也可以自己实现一个。