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

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.xdnf.cn/news/1538170.html

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

相关文章

C++STL~~priority_queue

文章目录 容器适配器一、priority_queue的概念二、priority_queue的使用三、priority_queue的练习四、仿函数五、总结 容器适配器 什么是适配器 适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结)&#xff0c;该种模式是将…

交流电力控制电路之交流调功电路、交流电力电子开关

目录 一、交流调功电路 二、交流电力电子开关 交流调压电路可看&#xff1a;交流调压电路 交流调压电路、交流调功电路和交流电力开关的异同点&#xff1a; 一、交流调功电路 交流调功电路用于调节电力设备的功率输出&#xff0c;通过改变电路中电压、电流的有效值&#xff…

STL,智能指针和线程安全,线程安全的单例模式和懒汉饿汉的实现,以及读者写者问题

&#x1f351;个人主页&#xff1a;Jupiter. &#x1f680; 所属专栏&#xff1a;Linux从入门到进阶 欢迎大家点赞收藏评论&#x1f60a; 目录 &#x1f4da;STL&#xff0c;智能指针和线程安全 &#x1f4d5;STL中的容器是否是线程安全的?&#x1f4a1;智能指针是否是线程安全…

Threejs之看房案例(下)

本文目录 前言最终效果1、点精灵1.1 添加点精灵1.2 点精灵效果2、添加事件2.1 鼠标移动事件2.1.1 效果2.2 鼠标点击事件2.2.1 效果2.3 切换互通3. 完整代码前言 在Threejs之看房案例(上)这篇博客中我们已经完成了大厅的3d观看效果,但是我们会发现如果想去其他房间观看,没有…

使用SQL递归查询树状结构,又可以跟同事吹牛了!

前言 在关系型数据库中&#xff0c;数据通常存储为二维表格&#xff08;rows 和 columns&#xff09;。然而&#xff0c;在实际业务中&#xff0c;很多场景下我们需要处理树状结构的数据&#xff0c;例如&#xff1a; 公司组织架构&#xff1a;从某个部门开始&#xff0c;查询…

Python异常处理:自定义异常②

文章目录 1. 什么是自定义异常&#xff1f;2. 为什么需要自定义异常&#xff1f;3. 如何定义自定义异常&#xff1f;3.1 基本自定义异常3.2 带详细信息的自定义异常3.3 自定义异常的继承层次 4. 使用自定义异常4.1 抛出自定义异常4.2 捕获自定义异常 5. 自定义异常的应用场景5.…

二叉树——数据结构

这次我们来学习一下数据结构中的二叉树 1. 二叉树的概念及结构 1.1 二叉树的定义 定义&#xff1a;所有结点的度小于等于2的树。 上图中可以看出 二叉树不存在度大于2的结点二叉树的子树有左右之分&#xff0c;次序不能颠倒&#xff0c;因此二叉树是有序树。 任意二叉树都…

2024年适合培训服务企业的7款CRM盘点

培训服务行业在线索管理、客户管理、数据分析、项目管理、师资管理和课程管理等方面&#xff0c;使用CRM可以事半功倍&#xff0c;最重要的是&#xff0c;可以用数据说话&#xff0c;找到降本增效的方向。 下面对培训服务行业常用测CRM做个盘点&#xff0c;包括国内比较头部的…

米壳AI:跨境电商必备:不损失原图的图片翻译工具!

嘿&#xff0c;跨境电商的小伙伴们&#xff01; 今天来聊聊如何突破语言壁垒&#xff0c;让你的商品在国际市场上大放异彩。 随着 “一带一路” 战略的不断推进&#xff0c;跨境电商的发展势头愈发强劲。然而&#xff0c;语言障碍却成为了跨境交易中的一大难题。别担心&#x…

ppt组织结构图怎么增加分支?

在使用ppt里边的SmartArt来制作组织结构图的时候&#xff0c;我们发现里边的图形不够用&#xff0c;需要增加分支&#xff0c;这也就是大家近期问的ppt组织结构图怎么增加分支。今天设计学徒自学网小编就把具体的操作步骤分享给大家了&#xff0c;希望能帮助你们&#xff01; …

RFID技术实现消防物资消防车无感化智能管理设计方案

在消防工作中&#xff0c;物资管理的高效性与准确性直接关系到救援行动的成败&#xff0c;传统的消防物资管理方式主要依赖人工记录和定期盘点&#xff0c;这种方式存在着诸多弊端。首先&#xff0c;人工记录容易出现错误&#xff0c;数据的准确性难以保证。例如&#xff0c;在…

制作U盘安装操作系统(启动盘、系统盘、Windows、Linux)

第一种&#xff08;Windows&#xff09; 官网windows制作启动盘 1. 打开Win11下载官网 下载 Windows 11https://www.microsoft.com/zh-cn/software-download/windows11 2. 下载制作操作系统工具 这里不要下载错了 3. 启动工具 选择U盘&#xff0c;选择你的U盘即可&#xf…

TASK-CUSTOMIZEDMASKED AUTOENCODERVIA MIXTURE OF CLUSTER-CONDITIONAL EXPERTS

发表于&#xff1a;ICLR 2023 notable top 25%&#xff08;相当于spotlight) 推荐指数: #paper/⭐⭐⭐ 论文链接: Task-customized Masked Autoencoder via Mixture of Cluster-conditional Experts | OpenReview poster链接&#xff1a;ICLR 2023 Task-customized Masked Auto…

人类行为识别系统源码分享

人类行为识别检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

使用streaming-json-py插件处理JSON数据流:详细指南

目录 一、streaming-json-py简介 二、安装与配置 三、基本使用 示例1:处理不完整的JSON对象 示例2:处理不完整的JSON数组 四、高级用法 实时数据流分析 日志处理 五、性能优化与错误处理 六、总结与展望 在数据驱动的现代社会,实时处理数据流已成为许多应用和服务…

Linux·权限与工具-git与gdb

1. git工具 git是一款软件&#xff0c;发明它的人同时发明了Linux操作系统&#xff0c;也就是大名鼎鼎的Linus Torvalds 林纳斯托瓦兹。后来人们把git软件包装&#xff0c;产生了github、gitee等平台。 git产生的初衷就是便于进行多人协同管理&#xff0c;同时它还可以用来将本…

GB/T28181-2022相对老版本有哪些变动?

GB/T28181-2022新版概述 GB/T28181-2022是《公共安全视频监控联网系统信息传输、交换、控制技术要求》的国家标准&#xff0c;该标准在2022年12月30日发布&#xff0c;并于2023年7月1日正式实施。以下是关于GB/T28181-2022的详细解析&#xff1a; 一、标准概述 GB/T28181-20…

2024/9/18 模型的存储与读取

一、模型的存储与读取 主要涉及到torch.save和torch.load函数 新建两个python文件&#xff1a; 1.在model_save文件中保存模型(方式一)和模型参数(方式二) 2.在model_load文件中读取模型(方式一)和模型参数并装载模型(方式二)

海外绿色农业果蔬投资系统可以二开多语言

食品安全已经是全球非常重视&#xff0c;关于农业方面的基础建设投资都在大力推进&#xff0c;做一个绿色农业果蔬投资是一个非常不错的。希望这个系统能对你有很大的帮助&#xff01;

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

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