返回

深入剖析数组:从基础概念到自研 ArrayList

后端

数组是一种线性数据结构,用于存储相同类型的元素集合。每个元素的位置由索引标识,索引从0开始递增。数组的大小固定,在声明时需指定长度。

声明与初始化数组

在Java中,可以使用以下方式声明并初始化数组:

int[] numbers = new int[5];  // 创建一个包含5个整数元素的数组,默认值为0
String[] names = {"Alice", "Bob"};  // 使用数组字面量直接赋值

访问与修改

通过索引访问或修改数组中的元素:

numbers[2] = 10;   // 修改第3个位置的元素为10
System.out.println(names[0]);  // 输出 "Alice"

数组操作

数组常见的操作包括遍历、查找特定值、插入和删除。由于大小固定,增删操作通常需复制数组或使用其他数据结构。

遍历数组

for (int i = 0; i < numbers.length; i++) {
    System.out.println(numbers[i]);
}

数组与ArrayList比较

相比固定长度的数组,ArrayList提供动态大小调整功能,更加灵活。但这种灵活性伴随性能开销,如内存分配和复制。

ArrayList基础操作

import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);  // 添加元素
        int size = list.size();  // 获取大小
        boolean contains = list.contains(2);  // 查找元素是否存在
    }
}

自研ArrayList实现

自定义一个ArrayList,理解其内部机制。此过程涵盖动态数组扩容和性能优化。

核心功能:自动扩容与添加元素

public class MyArrayList {
    private int[] elements;
    private int size = 0;

    public MyArrayList() {
        this(10);
    }

    public MyArrayList(int capacity) {
        if (capacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: " + capacity);
        else
            elements = new int[capacity];
    }
    
    public void add(int element) {
        ensureCapacity();
        elements[size++] = element;
    }
    
    private void ensureCapacity() {
        // 当达到当前容量时扩容至1.5倍
        if (size == elements.length)
            grow();
    }

    private void grow() {
        int oldCapacity = elements.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1); // 新容量为原容量的1.5倍
        int[] newArray = new int[newCapacity];
        for (int i = 0; i < size; i++) {
            newArray[i] = elements[i]; // 复制元素到新数组中
        }
        elements = newArray;
    }
}

性能与内存优化建议

  1. 尽可能减少动态调整大小的次数,初始容量设为预计最大值。
  2. 重用对象而非频繁创建和销毁以降低垃圾回收频率。

通过深入理解数组及自研ArrayList的过程,开发者不仅能掌握基本数据结构操作,还学会如何在实际项目中灵活运用这些知识。这不仅增强了编程技能,也提升了软件的效率与性能。