图解ArrayList数据结构设计与应用案例

ArrayList 是 Java 中的一个动态数组实现,它继承自 AbstractList 并实现了 List 接口。ArrayList 提供了基于数组的实现,允许快速随机访问。由于它是动态数组,当数组容量不足以容纳更多元素时,它会进行自动扩容。ArrayList 是非线程安全的,意味着在单线程环境中它提供了较好的性能,但在多线程环境中需要额外的同步措施来保证线程安全。ArrayList 允许存储 null 元素,并且支持快速的元素插入和删除操作,尤其是在列表的末尾。它通常用于实现对元素顺序有要求的场景,如列表、堆栈等。

1、 ArrayList

ArrayList 是 Java 集合框架中的一个非常核心的类,实现了 List 接口。以下是 ArrayList 的设计:

设计思考:

  1. 需求场景
    • 在许多编程任务中,需要一个能够动态增长和收缩的数组。例如,在实现数据集合、缓冲区管理、实现其他数据结构(如栈、队列)等场景中,动态数组是非常有用的。
  2. 现有技术局限性
    • 传统的数组类型在 Java 中是固定长度的,一旦创建,其大小不能改变,这限制了其在需要动态大小管理时的使用。
  3. 技术融合
    • ArrayList 融合了动态数组的概念,提供了一个能够根据需要自动调整大小的数组。
  4. 设计理念
    • ArrayList 提供了一个能够根据添加元素的数量动态增长的数组,同时保持了随机访问的能力,使其在执行索引位置的查找时非常高效。
  5. 实现方式
    • ArrayList 内部使用一个可变大小的数组(默认为空,随着元素添加自动扩容)来存储元素,当数组容量不足以容纳更多元素时,会自动创建一个更大的新数组,并将旧数组中的元素复制到新数组中。

2、 数据结构

图说明:
  • ArrayList :
    • Java 集合框架中的一个类,实现了 List 接口。
  • Object[] elementData :
    • ArrayList 内部使用一个动态数组来存储元素,这个数组的类型是 Object[],可以存储任何类型的对象。
    • 当数组容量不足以存储更多元素时,ArrayList 会自动进行扩容,通常是将数组大小增加到原来的1.5倍。
  • int size :
    • 表示 ArrayList 中实际存储的元素数量。
    • sizeelementData 数组的 length 属性不同,length 表示数组的总容量,而 size 表示当前存储的元素个数。

3、 执行流程

图说明:
  • 初始化 ArrayList :
    • 创建一个空的 ArrayList 或指定初始容量的 ArrayList
  • 检查容量 :
    • 在添加元素前,检查当前数组容量是否足够。
  • 添加元素 :
    • 尝试将新元素添加到 ArrayList
  • 容量不足 :
    • 如果当前容量不足以容纳新元素,进入扩容流程。
  • 扩容 :
    • 创建一个新的数组,容量通常是原数组的1.5倍。
  • 复制旧数组到新数组 :
    • 将旧数组中的所有元素复制到新数组中。
  • 增加新元素 :
    • 在新数组中插入新元素。
  • 获取元素 :
    • 根据索引获取元素。
  • 索引检查 :
    • 检查索引是否在有效范围内。
  • 返回元素 :
    • 返回指定索引处的元素。
  • 删除元素 :
    • 删除 ArrayList 中的指定元素。
  • 移除指定索引元素 :
    • 将指定索引处的元素移除。
  • 数组元素向前移动 :
    • 将移除元素之后的元素向前移动一位,填补空位。

4、优点:

  1. 随机访问性能高
    • 提供了常数时间复杂度的随机访问能力。
  2. 动态数组
    • 可以根据需要动态增长和收缩,不需要预先指定大小。
  3. 实现了 List 接口
    • 提供了 List 接口定义的所有功能,包括列表操作、迭代器支持等。

5、缺点:

  1. 插入和删除性能问题
    • 在数组中间或开始插入或删除元素可能需要 O(n) 的时间,因为需要移动后续元素。
  2. 内存开销
    • 相比于固定大小的数组,ArrayList 在扩容和复制旧数组时可能会有额外的内存开销。
  3. 线程不安全
    • ArrayList 本身不是线程安全的,需要外部同步来保证线程安全。

6、使用场景:

  • 需要动态大小数组的场景,如实现数据集合、缓冲区管理等。
  • 需要快速随机访问元素的场景。

7、类设计

8、应用案例

ArrayList 通常用于实现动态数组,它允许快速随机访问。这是一个订单处理系统,用于管理订单项:

java 复制代码
import java.util.ArrayList;
import java.util.List;

// 订单项类
class OrderItem {
    private String productId;
    private int quantity;

    public OrderItem(String productId, int quantity) {
        this.productId = productId;
        this.quantity = quantity;
    }

    // 省略 getter 和 setter 方法
}

// 订单类
class Order {
    private String orderId;
    private List<OrderItem> items;

    public Order(String orderId) {
        this.orderId = orderId;
        this.items = new ArrayList<>();
    }

    public void addItem(OrderItem item) {
        items.add(item);
    }

    public List<OrderItem> getItems() {
        return items;
    }

    // 省略其他业务方法
}

// 订单管理系统类
class OrderManagementSystem {
    private List<Order> orders;

    public OrderManagementSystem() {
        orders = new ArrayList<>();
    }

    public void placeOrder(Order order) {
        orders.add(order);
    }

    public List<Order> getAllOrders() {
        return orders;
    }

    // 省略其他业务方法
}

public class Main {
    public static void main(String[] args) {
        OrderManagementSystem oms = new OrderManagementSystem();

        // 创建并添加订单
        Order order1 = new Order("ORD001");
        order1.addItem(new OrderItem("P001", 2));
        order1.addItem(new OrderItem("P002", 5));
        oms.placeOrder(order1);

        Order order2 = new Order("ORD002");
        order2.addItem(new OrderItem("P003", 8));
        oms.placeOrder(order2);

        // 获取所有订单
        List<Order> allOrders = oms.getAllOrders();
        for (Order order : allOrders) {
            System.out.println("Order ID: " + order.getOrderId());
            System.out.println("Items:");
            for (OrderItem item : order.getItems()) {
                System.out.println("Product ID: " + item.getProductId() + ", Quantity: " + item.getQuantity());
            }
        }
    }
}
相关推荐
李小白668 分钟前
Spring MVC(上)
java·spring·mvc
GoodStudyAndDayDayUp21 分钟前
IDEA能够从mapper跳转到xml的插件
xml·java·intellij-idea
装不满的克莱因瓶1 小时前
【Redis经典面试题六】Redis的持久化机制是怎样的?
java·数据库·redis·持久化·aof·rdb
n北斗1 小时前
常用类晨考day15
java
骇客野人1 小时前
【JAVA】JAVA接口公共返回体ResponseData封装
java·开发语言
AskHarries2 小时前
Spring Cloud OpenFeign快速入门demo
spring boot·后端
yuanbenshidiaos2 小时前
c++---------数据类型
java·jvm·c++
向宇it2 小时前
【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
java·开发语言·unity·c#·游戏引擎
Lojarro2 小时前
【Spring】Spring框架之-AOP
java·mysql·spring
莫名其妙小饼干2 小时前
网上球鞋竞拍系统|Java|SSM|VUE| 前后端分离
java·开发语言·maven·mssql