Java 中 List 常用类和数据结构详解及案例示范

news2024/11/15 7:24:10

1. 引言

在 Java 开发中,List 是最常用的数据结构接口之一,它用于存储有序的元素集合,并允许通过索引进行随机访问。电商系统中,如购物车、订单列表和商品目录等功能都依赖 List 进行数据管理。选择适当的 List 实现类能够显著提高性能、代码可维护性和可扩展性。

本文将以电商交易系统为案例,详细讲解 Java 中 List 常用实现类的底层数据结构、应用场景以及如何选择合适的 List 实现类,必要时使用类图或时序图辅助说明。

2. 问题描述

在电商系统中,订单、商品列表、购物车等操作都需要使用 List 来存储数据。不同的场景下有不同的性能需求:

  • 订单列表通常需要支持频繁的增删改查操作。
  • 购物车需要高效地增加或移除商品,并需要支持并发修改。
  • 商品列表通常比较稳定,查找商品的效率比更新商品更为重要。

为此,开发人员需要根据不同的需求,选择合适的 List 实现类。

3. List 常用实现类

Java 中常见的 List 实现类包括:

  • ArrayList
  • LinkedList
  • CopyOnWriteArrayList

每个类都有不同的适用场景和底层实现。接下来,我们将详细介绍这些实现类,并通过电商系统中的具体问题展示它们的区别与应用场景。

3.1 ArrayList

3.1.1 问题场景

在电商系统中,商品展示页面通常需要快速加载商品数据,并允许用户分页查看。此时需要一个能快速随机访问元素的集合,且商品数据通常是稳定的,不会频繁更新。

3.1.2 解决方式:ArrayList 的底层结构

ArrayList 是基于动态数组实现的 List,它的优点是能够快速随机访问元素。ArrayList 的底层是一个数组,当数组容量不够时,会自动扩容。以下是 ArrayList 的核心特点:

  • 随机访问效率高:因为底层是数组,通过索引访问元素的时间复杂度是 O(1)。
  • 增删元素效率低:当从中间插入或删除元素时,需要移动数组中的部分元素,时间复杂度为 O(n)。
  • 动态扩容:当数组容量不足时,ArrayList 会自动扩容,一般扩容为原容量的 1.5 倍。
List<String> products = new ArrayList<>();
products.add("Laptop");
products.add("Smartphone");
products.add("Headphones");

// 随机访问商品
String product = products.get(1);  // 获取第二个商品,时间复杂度 O(1)
3.1.3 底层实现

ArrayList 的内部通过一个数组 elementData 实现,当我们向 ArrayList 添加元素时,如果数组容量不足,ArrayList 会调用 grow() 方法扩展数组的大小,典型的扩容因子为 1.5 倍。

private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);  // 扩容1.5倍
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    elementData = Arrays.copyOf(elementData, newCapacity);
}
3.1.4 适用场景

ArrayList 非常适合以下场景:

  • 需要频繁的随机访问(如分页查询、商品展示)。
  • 插入和删除操作较少。
3.1.5 类图辅助说明

在这里插入图片描述

3.2 LinkedList

3.2.1 问题场景

在购物车功能中,用户可能会频繁地添加和移除商品,特别是从列表的开头或中间移除。此时,ArrayList 并不适用,因为它在移除操作时需要移动大量元素。

3.2.2 解决方式:LinkedList 的底层结构

LinkedList 是基于双向链表实现的 List,它允许快速地在头部或尾部插入和删除元素,时间复杂度为 O(1)。它不需要像 ArrayList 那样移动元素,因此在需要频繁插入或删除元素的场景下非常高效。

List<String> cart = new LinkedList<>();
cart.add("Laptop");
cart.add("Smartphone");

// 在头部插入商品
cart.add(0, "Headphones");

// 删除第一个商品
cart.remove(0);
3.2.3 底层实现

LinkedList 底层是一个双向链表,每个节点包含前驱和后继节点的引用。与 ArrayList 不同的是,LinkedList 的插入和删除操作不需要移动元素,因此效率更高。

private static class Node<E> {
    E item;
    Node<E> next;
    Node<E> prev;
    
    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}
3.2.4 适用场景

LinkedList 适用于以下场景:

  • 需要频繁地在集合的头部或尾部插入和删除元素。
  • 插入和删除的效率比随机访问更重要。
3.2.5 类图辅助说明

在这里插入图片描述

3.3 CopyOnWriteArrayList

3.3.1 问题场景

在电商系统中,可能会有多用户同时操作购物车或订单列表。这种场景下,普通的 ArrayListLinkedList 无法保证线程安全,而手动加锁会影响性能。

3.3.2 解决方式:CopyOnWriteArrayList 的底层结构

CopyOnWriteArrayList 是一个线程安全的 List 实现,它的核心原理是“写时复制”(Copy-On-Write)。当写操作(如添加、修改、删除)发生时,CopyOnWriteArrayList 会创建数组的一个副本,在副本上进行修改,从而避免了并发冲突。由于每次写操作都会创建新的副本,因此它适用于读多写少的场景。

List<String> safeCart = new CopyOnWriteArrayList<>();
safeCart.add("Laptop");
safeCart.add("Smartphone");

// 并发读写
safeCart.forEach(item -> System.out.println(item));
3.3.3 底层实现

CopyOnWriteArrayList 的底层实现是基于数组的,但它通过在修改时创建新数组,确保了线程安全。读取操作可以不加锁,因为数组不会被修改。

public boolean add(E e) {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        Object[] elements = getArray();
        int len = elements.length;
        Object[] newElements = Arrays.copyOf(elements, len + 1);
        newElements[len] = e;
        setArray(newElements);
        return true;
    } finally {
        lock.unlock();
    }
}
3.3.4 适用场景

CopyOnWriteArrayList 适合以下场景:

  • 读多写少的高并发环境。
  • 对数据一致性要求高,但写操作较少的场景。
3.3.5 类图辅助说明

在这里插入图片描述

4. List 实现类的性能对比

实现类底层结构插入/删除效率随机访问效率线程安全性适用场景
ArrayList动态数组需要快速随机访问,且插入删除操作较少
LinkedList双向链表频繁插入或删除元素的场景
CopyOnWriteArrayList动态数组(写时复制)中等读多写少的并发场景,如订单列表或购物车的并发操作

5. 总结

在电商系统中,不同的场景对 List 的需求不同。ArrayList 适用于数据读取频繁但不经常修改的场景;LinkedList 适合需要频繁插入、删除操作的场景;CopyOnWriteArrayList 则在多线程高并发的场景中表现出色。开发人员应根据具体需求选择合适的 List 实现,以提高系统的性能和稳定性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2144529.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

三菱变频器变更电流最大输入(20mA 初始值)时的频率(60Hz初始值)

变更最高频率。变更示例 在4~ 20mA 输入频率设定器中&#xff0c;将 20mA 时的频率从 60Hz(初始值)变更为 50Hz。 输入 20mA 电流时调整为输出 50Hz。 将Pr.126 设定为“50Hz” NOTE 4mV 时的频率设定可通过校正参数 C5 设定。 其他的频率设定电流增益的调整方法&#xff0c;还…

计算机网络(七) —— https协议与网络安全证书

目录 一&#xff0c;关于https 二&#xff0c;关于加密 2.1 明文&#xff0c;密钥 2.2 对称和非对称加密 2.3 数据摘要&#xff0c;数据指纹&#xff0c;数字签名 三&#xff0c;https过程过程探究 四&#xff0c;证书 4.1 CA认证 4.2 证书大致内容和申请流程 4.3 签…

试用完几十款ETL工具后的经验总结,ETL工具用这三款就足够了

1.ETL选型前言 市面上ETL工具国内外加起来估计得有30种之多&#xff0c;其中近20款工具都花时间试用过&#xff0c;现在把试用后总结出来的经验分享一下&#xff0c;目前很多企业在选择ETL工具时不知道怎么选择适合自己的工具也不可能一款一款的去试用&#xff0c;试用成本非常…

3.postman脚本语言、接口关联(json引用(变量)、脚本用正则表达式)、断言封装、自动化构造接口请求(Postman工具)

一、Postman的脚本语言 1.使用js语言 2.pm变量 pm.sendRequest():发送HTTP请求 二、自动化实现接口关联 1.JSON引用 2.正则表达式&#xff08;在test下编写如下脚本&#xff09; //获取响应 console.log(responseBody) //re的方式获取token let token responseBody.match(&quo…

佰朔资本:股票中什么叫龙头?怎么找龙头股?

龙头&#xff0c;也便是龙头股&#xff0c;指的是某一工作中有必定影响力和号召力的股票&#xff0c;龙头股的涨跌一般对其他同工作板块股票的涨跌有必定演示和引导效果&#xff0c;是一种风向标一般的存在。龙头股的技能面表现和成交量都会比一同间的大盘和地块要强。 龙头股…

三菱变频器以模拟量电流进行频率设定(电流输入)

POINT 1、在 STF(STR)信号 ON 时&#xff0c;发出启动指令。2、请将 AU 信号置为 ON。 3、请设定 Pr.79 运行模式选择 “2”(外部运行模式)。 接线示例 重点&#xff1a;请将 AU 信号置为 ON。 操作示例&#xff1a;以 60Hz 运行。 1、接通电源时的画面&#xff0c;监视器显…

伪工厂模式制造敌人

实现效果 1.敌人方实现 敌人代码 using UnityEngine; using UnityEngine.UI;public class EnemyBasics : MonoBehaviour {public int EnemySpeed { get; internal set; }public int EnemyAttackDistance { get; internal set; }public int EnemyChaseDistance { get; interna…

YOLOv8 OBB win10+ visual 2022移植部署

前言 想做一个目标旋转角度检测的工程&#xff0c;但是网上多少python的&#xff0c;或者linux的。在win10 visual 2022移植部署&#xff0c;记录一下。 参考 这篇文章没有C win10 环境下的部署教程&#xff0c;我相对于是对此做了补充。 1、下载工程 https://github.com/sh…

Matlab 的.m 文件批量转成py文件

在工作中碰到了一个问题&#xff0c;需要将原来用matlab gui做出来的程序改为python程序&#xff0c;因为涉及到很多文件&#xff0c;所以在网上搜了搜有没有直接能转化的库。参考了【Matlab】一键Matlab代码转python代码详细教程_matlab2python-CSDN博客 这位博主提到的matla…

Redis安装 ▎Redis详细知识点

前言: Redis是一个开源的内存数据结构存储&#xff0c;支持丰富的数据类型&#xff0c;如字符串、哈希、列表、集合和有序集合,作为一个键值对数据库&#xff0c;Redis能提供毫秒级的响应时间&#xff0c;适合高并发应用场景。它还支持持久化&#xff0c;将内存数据定期保存到…

路由器接口配置DHCP实验简述

一、路由器配置 [Huawei]undo info-center enable Info: Information center is disabled. [DHCP-SERVER]sysname DHCP-Server [DHCP-Server]dis this sysname DHCP-Server undo info-center enable return [DHCP-Server]dhcp enable Info: The operation may take a few secon…

【pytorch学习笔记,利用Anaconda安装pytorch和paddle深度学习环境+pycharm安装---免额外安装CUDA和cudnn】

作者链接: link 一、安装pytorch环境 1.打开打开anaconda的终端后 conda env list然后创建一个名字叫pytorch&#xff0c;python是3.8版本的环境 conda create -n pytorch python3.8再次看环境 conda env list# conda environments: #显示如下环境 base …

Rust GUI框架Tauri V1 入门

文章目录 Tauri介绍Vite开始创建 Rust 项目 调用指令window.__TAURI_INVOKE__.invoke is undefined 问题 参考资料JavaScript 模块Vue 框架Vue RouteviteNuxt gitignore文件上传到csdn gitcode网站端本地端 gitcode发布 Tauri介绍 Tauri是一款用Rust构建的开源框架&#xff0c…

私有化通讯工具:安全、高效、个性化,重塑企业沟通生态

在当今数字化时代&#xff0c;即时通讯已成为企业日常运营中不可或缺的一部分。随着数据安全和隐私保护意识的日益增强&#xff0c;越来越多的企业开始寻求更加安全、可控的沟通方式。私有化聊天工具应运而生&#xff0c;以其独特的核心优势&#xff0c;为企业构建了一个安全、…

选购到不好的宠物空气净化器会有什么危害?有哪几款推荐

前三个月真的是被我男朋友气到了&#xff0c;明明说好的一起养猫&#xff0c;他又嫌这嫌那的&#xff0c;真的是无语住。 在养猫前的一个月就说好了&#xff0c;谁下班早谁就先回家收拾&#xff0c;包括进门开窗通风、给猫喂食、还有铲猫砂盆。但是他现在抱怨说太麻烦了&#…

【PSINS工具箱】仅速度为观测量的SINS/GNSS组合导航,MATLAB源代码,无需下载,可直接复制

工具箱 本程序需要在安装工具箱后使用,工具箱是开源的,链接:http://www.psins.org.cn/kydm 程序简述 原文的153组合导航是SINS/GPS下的位置观测或位置+速度观测,本文所述的代码是仅三轴位置观测的,使用UKF来滤波。 最后输出速度对比、速度误差、姿态对比、姿态误差、位…

基于SpringBoot+Vue的房屋租赁平台

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的…

HT3163 免电感滤波25W AB/D类音频功放

特征 输出功率 15W (VDD12V, RL4Ω,THDN1%, Class D) 20W(VDD14V,RL4Ω,THDN1%, Class D) 25W(VDD14V,RL4Ω,THDN10%, Class D) 7.5W(VDD7.4V,RL4Ω,THDN10%, Class AB) 17W(VDD12V,RL4Ω,THDN10%, Class AB) 单电源系统&#xff0c;3V-16V宽电压输入范围 低静态电流: 7mA (VD…

制造业应用人工智能!成本与效益的博弈

制造业应用人工智能&#xff01;成本与效益的博弈 前言制造业应用人工智能 前言 制造业一直是国家经济的重要支柱&#xff0c;而现在&#xff0c;人工智能的出现正在给制造业带来一场前所未有的变革。就像是一场风暴&#xff0c;席卷了整个制造业的世界&#xff0c;让一切都变…

net await 、 Task、 Async 不用async异步方法

详细资料 lamda 变成异步方法 &#xff0c;只要在前面 加 async 修饰 即可 》》await 修饰的 &#xff0c;await 所在的方法&#xff0c;必须修饰 async ThreadPool.QueueUserWorkItem( async (obj)>{while(true){await File.WriteAllTextAsync("路径","…