Java List 使用详解:从入门到精通

一、List 基础概念

1.1 什么是 List?

List 就像是一个智能书架

  • 可以按顺序存放书籍(元素)
  • 每本书都有固定位置(索引)
  • 可以随时添加、取出或重新排列书籍
// 创建一个书架(List)
List<String> bookshelf = new ArrayList<>();

1.2 List 的核心特性

特性说明生活类比
有序性元素按添加顺序存储书架上的书按放入顺序排列
可重复允许相同元素多次出现同一本书可以有多个副本
索引访问通过位置编号快速获取元素通过书架编号找书
动态扩容自动调整存储空间智能书架自动扩展

1.3 List 家族成员

二、List 基本操作 

2.1 创建 List 的三种方式

// 方式1:标准创建(推荐)
List<String> fruits = new ArrayList<>();// 方式2:快速初始化
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);// 方式3:不可变列表(Java 9+)
List<String> colors = List.of("红", "绿", "蓝");

2.2 添加元素 - 丰富你的书架

fruits.add("苹果");     // 末尾添加
fruits.add(0, "香蕉");  // 指定位置插入
fruits.addAll(Arrays.asList("橙子", "葡萄")); // 批量添加System.out.println(fruits); 
// 输出: [香蕉, 苹果, 橙子, 葡萄]

2.3 访问元素 - 查找书籍

// 获取单个元素
String firstFruit = fruits.get(0); // "香蕉"// 检查元素是否存在
boolean hasApple = fruits.contains("苹果"); // true// 查找元素位置
int appleIndex = fruits.indexOf("苹果"); // 1

2.4 修改元素 - 替换书籍

// 替换指定位置的元素
String oldFruit = fruits.set(1, "青苹果");
System.out.println("被替换的水果: " + oldFruit); // "苹果"

2.5 删除元素 - 清理书架

// 按索引删除
String removed = fruits.remove(0); // 删除"香蕉"// 按元素值删除
boolean isRemoved = fruits.remove("葡萄"); // true// 批量删除
fruits.removeAll(Arrays.asList("橙子", "青苹果"));// 清空书架
fruits.clear();

三、遍历 List 的多种方式 

3.1 基础遍历方法

// 1. for循环(索引访问)
for (int i = 0; i < fruits.size(); i++) {System.out.println((i+1) + ". " + fruits.get(i));
}// 2. 增强for循环
for (String fruit : fruits) {System.out.println(fruit);
}

3.2 使用迭代器

// 3. Iterator遍历
Iterator<String> iterator = fruits.iterator();
while (iterator.hasNext()) {String fruit = iterator.next();if (fruit.equals("葡萄")) {iterator.remove(); // 安全删除}
}

3.3 Java 8+ 高级遍历

// 4. forEach方法
fruits.forEach(fruit -> System.out.println(fruit));// 5. 方法引用
fruits.forEach(System.out::println);// 6. 并行流遍历(大数据量)
fruits.parallelStream().forEach(fruit -> {// 并行处理逻辑
});

3.4 遍历性能对比

遍历方式10万元素耗时适用场景
for循环5ms需要索引时
增强for7ms简单遍历
Iterator8ms需要删除元素时
forEach10ms函数式编程
并行流3ms大数据量处理

四、List 高级操作 

4.1 排序操作

List<Integer> numbers = Arrays.asList(5, 2, 9, 1, 3);// 自然排序(升序)
Collections.sort(numbers);
// 输出: [1, 2, 3, 5, 9]// 自定义排序(降序)
numbers.sort((a, b) -> b - a);
// 输出: [9, 5, 3, 2, 1]// 对象排序
List<Book> books = new ArrayList<>();
books.add(new Book("Java编程", 99));
books.add(new Book("Python入门", 69));books.sort(Comparator.comparing(Book::getPrice));

4.2 过滤与转换

// 过滤高价水果
List<String> expensiveFruits = fruits.stream().filter(fruit -> fruit.length() > 2).collect(Collectors.toList());// 水果名称转大写
List<String> upperCaseFruits = fruits.stream().map(String::toUpperCase).collect(Collectors.toList());

4.3 数学统计

IntSummaryStatistics stats = numbers.stream().mapToInt(Integer::intValue).summaryStatistics();System.out.println("最大值: " + stats.getMax());
System.out.println("最小值: " + stats.getMin());
System.out.println("平均值: " + stats.getAverage());
System.out.println("总数: " + stats.getSum());

4.4 列表转换

// List转数组
String[] fruitArray = fruits.toArray(new String[0]);// 数组转List(不可修改)
List<String> fixedList = Arrays.asList(fruitArray);// 数组转List(可修改)
List<String> modifiableList = new ArrayList<>(Arrays.asList(fruitArray));

五、ArrayList 深度解析 

5.1 内部结构

ArrayList 就像是一个智能伸缩书架

// 简化版ArrayList实现
public class SimpleArrayList<E> {private Object[] elements; // 存储元素的数组private int size;          // 当前元素数量public SimpleArrayList() {this.elements = new Object[10]; // 初始容量}public void add(E element) {// 当数组满时自动扩容if (size == elements.length) {Object[] newArray = new Object[elements.length * 2];System.arraycopy(elements, 0, newArray, 0, size);elements = newArray;}elements[size++] = element;}
}

5.2 扩容机制

5.3 性能特点

操作时间复杂度说明
get(index)O(1)直接通过索引访问
add(element)O(1)平均时间复杂度
add(index, element)O(n)需要移动后续元素
remove(index)O(n)需要移动后续元素
contains(element)O(n)需要遍历查找

六、LinkedList 深度解析

6.1 内部结构

LinkedList 就像是一个带前后指针的书本链

// 简化版链表节点
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;}
}

6.2 操作原理

// 在指定位置插入元素
public void add(int index, E element) {// 1. 找到目标位置的节点Node<E> target = getNode(index);// 2. 创建新节点Node<E> newNode = new Node<>(target.prev, element, target);// 3. 调整前后节点指针target.prev.next = newNode;target.prev = newNode;
}

6.3 性能对比 ArrayList

操作ArrayListLinkedList适用场景
随机访问⚡️ 快 (O(1))🐢 慢 (O(n))需要频繁按索引访问
头部插入🐢 慢 (O(n))⚡️ 快 (O(1))需要频繁在开头添加
尾部插入⚡️ 快 (O(1))⚡️ 快 (O(1))在末尾添加
中间插入🐢 慢 (O(n))⚡️ 快 (O(1))需要频繁在中间插入
内存占用较少(仅需存储元素)较多(每个元素需要额外指针)内存敏感场景

七、实战应用案例

7.1 学生成绩管理系统

class Student {private String name;private int score;// 构造方法、getter/setter省略
}public class GradeSystem {private List<Student> students = new ArrayList<>();// 添加学生public void addStudent(Student student) {students.add(student);}// 按分数排序public void sortByScore() {students.sort(Comparator.comparingInt(Student::getScore).reversed());}// 查找前N名学生public List<Student> getTopStudents(int n) {return students.stream().sorted(Comparator.comparingInt(Student::getScore).reversed()).limit(n).collect(Collectors.toList());}// 统计分数分布public Map<String, Long> getScoreDistribution() {return students.stream().collect(Collectors.groupingBy(s -> {int score = s.getScore();if (score >= 90) return "优秀";if (score >= 80) return "良好";if (score >= 60) return "及格";return "不及格";},Collectors.counting()));}
}

7.2 购物车实现

class CartItem {private String productId;private String name;private double price;private int quantity;// 构造方法、getter/setter省略
}public class ShoppingCart {private List<CartItem> items = new LinkedList<>();// 添加商品public void addItem(CartItem newItem) {// 检查是否已存在for (CartItem item : items) {if (item.getProductId().equals(newItem.getProductId())) {item.setQuantity(item.getQuantity() + newItem.getQuantity());return;}}items.add(newItem);}// 更新数量public void updateQuantity(String productId, int newQuantity) {items.removeIf(item -> item.getProductId().equals(productId));if (newQuantity > 0) {items.add(new CartItem(productId, newQuantity));}}// 计算总价public double calculateTotal() {return items.stream().mapToDouble(item -> item.getPrice() * item.getQuantity()).sum();}// 生成订单public Order checkout() {Order order = new Order();order.setItems(new ArrayList<>(items));order.setTotal(calculateTotal());items.clear();return order;}
}

八、最佳实践与性能优化

8.1 选择正确的 List 实现

场景推荐实现理由
读多写少ArrayList随机访问快
频繁增删LinkedList插入删除快
多线程环境CopyOnWriteArrayList线程安全
固定大小列表Arrays.asList()内存优化
不可变列表List.of()安全简洁

8.2 性能优化技巧

   预分配容量(减少扩容开销)

// 预计存储1000个元素
List<String> largeList = new ArrayList<>(1000);

       批量操作(减少方法调用) 

// 差: 多次调用add
for (String item : items) {list.add(item);
}// 好: 批量添加
list.addAll(items);

   

避免在循环中调用size

// 差: 每次循环都调用size()
for (int i = 0; i < list.size(); i++) {// ...
}// 好: 缓存size值
int size = list.size();
for (int i = 0; i < size; i++) {// ...
}

使用subList视图

// 创建子列表视图(不复制数据)
List<String> sub = list.subList(0, 5);

九、常见问题与解决方案 (30分钟)

 ConcurrentModificationException

问题:遍历时修改集合

List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
for (String s : list) {if ("B".equals(s)) {list.remove(s); // 抛出异常}
}

解决方案

// 1. 使用Iterator的remove方法
Iterator<String> it = list.iterator();
while (it.hasNext()) {String s = it.next();if ("B".equals(s)) {it.remove(); // 安全删除}
}// 2. 使用Java 8+ removeIf
list.removeIf("B"::equals);// 3. 创建副本遍历
new ArrayList<>(list).forEach(s -> {if ("B".equals(s)) {list.remove(s);}
});

性能陷阱:LinkedList的随机访问

问题

LinkedList<Integer> list = new LinkedList<>();
// 填充数据...// 随机访问性能差
for (int i = 0; i < list.size(); i++) {Integer value = list.get(i); // O(n)操作
}

解决方案

// 1. 使用迭代器
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {Integer value = it.next();
}// 2. 使用增强for循环
for (Integer value : list) {// ...
}// 3. 转换为ArrayList(只读场景)
List<Integer> arrayList = new ArrayList<>(list);

 对象相等性判断

问题:自定义对象在List中的行为

解决方案

class Person {String name;@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return Objects.equals(name, person.name);}@Overridepublic int hashCode() {return Objects.hash(name);}
}

十、总结与进阶学习 

 List 知识体系总结

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

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

相关文章

Java零基础笔记06(数组:一维数组、二维数组)

明确: 程序是用来处理数据的, 因此要掌握数据处理的数据结构数组是编程中常用的数据结构之一&#xff0c;用于存储一系列相同类型的元素。在Java中&#xff0c;数组是一种对象&#xff0c;可以存储固定大小的相同类型元素的集合。1.一维数组数组是一个数据容器,可用来存储一批同…

10倍处理效率提升!阿里云大数据AI平台发布智能驾驶数据预处理解决方案

阿里云大数据AI平台重磅发布智能驾驶数据预处理解决方案&#xff0c;可帮助汽车行业客户实现构建高效、稳定的数据预处理产线流程&#xff0c;数据包处理效率相比自建可提升10倍以上&#xff0c;数据处理推理任务优化提速1倍以上&#xff0c;相同资源产能提升1倍[1]&#xff0c…

SAP HANA内存数据库解析:特性、优势与应用场景 | 技术指南

SAP HANA 是一款列式内存关系数据库&#xff0c;集 OLAP 和 OLTP 操作于一体。相较于同类产品&#xff0c;SAP HANA 需要的磁盘空间更少&#xff0c;并且可扩展性高。SAP HANA 可以部署在本地、公有云或私有云以及混合场景中。该数据库适用于各种数据类型的高级分析和事务处理。…

Openharmony4.0 rk3566上面rknn的完美调用

一 背景&#xff1a; 我们都知道如果要在android上面使用rknn推理模型需要按照如下的步骤&#xff1a; 详细请参考笔者的文章&#xff1a;Android11-rk3566平台上采用NCNN&#xff0c;RKNN框架推理yolo11官方模型的具体步骤以及性能比较-CSDN博客 简而言之就是 模型转换&#…

Java多线程知识小结:Synchronized

在Java中&#xff0c;synchronized 关键字是实现线程同步的核心工具&#xff0c;用于保证同一时刻只有一个线程可以执行被修饰的代码块或方法。以下从基本原理、锁升级过程、应用场景及优化建议四个维度详细解析&#xff1a; 一、基本原理 1. 同步的对象 synchronized 锁的是对…

MTK项目wifi.cfg文件如何配置的Tput和功耗参数

下面的MTK参数主要与无线网络(Wi-Fi)配置相关,特别是与WMM(Wi-Fi Multimedia)和功率控制相关的设置 WMM相关参数: WmmParamCwMax/WmmParamCwMin:定义竞争窗口的最大/最小值,这里设置为10/4,用于控制信道访问的退避机制13 WmmParamAifsN:仲裁帧间间隔数,设置为3影响不同…

分水岭算法:图像分割的浸水原理

分水岭算法&#xff1a;基于拓扑地貌的边界提取核心原理 分水岭算法将图像视为拓扑地貌&#xff0c;灰度值代表海拔高度。通过模拟浸水过程&#xff1a;局部极小值&#xff1a;对应集水盆&#xff08;区域内部&#xff09;。分水岭线&#xff1a;集水盆之间的山脊&#xff08;区…

汽车功能安全系统阶段开发【技术安全方案TSC以及安全分析】5

文章目录1 技术安全方案 (Technical Safety Concept - TSC)2 系统安全架构设计 (System Safety Architecture Design)3 如何进行安全分析 (Safety Analysis)4 技术安全需求 (TSR) 如何分配到系统架构1 技术安全方案 (Technical Safety Concept - TSC) 技术安全方案 (Technical…

学习软件测试的第十二天(接口测试)

一.如果一个接口请求不通&#xff0c;那么你会考虑那些方面的问题&#xff1f;如果一个接口请求不通&#xff0c;我会像“排查水管漏水”一样一步步定位问题发生在哪一段&#xff0c;主要从这几个方向去思考&#xff1a;当一个接口请求不通时&#xff0c;我会从以下几个方面进行…

Linux下的C/C++开发之操作Zookeeper

ZooKeeper C 客户端简介与安装ZooKeeper C API 简介ZooKeeper 官方提供了多语言客户端&#xff0c;C 语言客户端是最底层的实现之一&#xff0c;功能全面且稳定&#xff0c;适合嵌入式开发、系统级组件、C 项目集成等场景。zookeeper.h 是 ZooKeeper 提供的 C 语言客户端头文件…

【openp2p】学习3:【专利分析】一种基于混合网络的自适应切换方法、装 置、设备及介质

本专利与开源项目无关,但可能是实际商用的一种专利。专利地址从此专利,可见p2p的重要性。透传服务可能是实时转发服务,提供中继能力 透传服务可以是指一种通过公网服务器将数据从第一客户端传递到另一个设备 或客户端的服务。这种服务通常用于克服网络中的障碍,如防火墙、…

OpenCV中DPM(Deformable Part Model)目标检测类cv::dpm::DPMDetector

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 OpenCV 中用于基于可变形部件模型&#xff08;DPM&#xff09; 的目标检测器&#xff0c;主要用于行人、人脸等目标的检测。它是一种传统的基于特…

macOS 26快捷指令更新,融入AI打造智能操作体验

快捷指令作为Mac系统中提升用户操作效率的得力助手&#xff0c;在macOS 26中迎来了一次具有突破性的重大更新。此次更新融入了先进的AI技术&#xff0c;推出“智能操作”&#xff08;Intelligent Actions&#xff09;功能&#xff0c;让快捷指令从简单的自动化工具升级为真正的…

InstructBLIP:迈向具备指令微调能力的通用视觉语言模型

温馨提示&#xff1a; 本篇文章已同步至"AI专题精讲" InstructBLIP&#xff1a;迈向具备指令微调能力的通用视觉语言模型 摘要 大规模的预训练与instruction tuning在构建通用语言模型方面已取得显著成效。然而&#xff0c;构建通用的视觉-语言模型仍然具有挑战性&…

基于dropbear实现嵌入式系统ssh服务端与客户端完整交互

以下基于 Dropbear 实现 SSH 服务端与客户端交互的完整步骤&#xff0c;涵盖服务端部署、客户端连接、认证配置及消息传输&#xff0c;结合了多篇权威资料的核心实践&#xff1a;环境准备与安装 服务端安装 • Linux 系统&#xff08;以 Ubuntu/CentOS 为例&#xff09; Ubuntu…

深圳安锐科技发布国内首款4G 索力仪!让斜拉桥索力自动化监测更精准高效

近日&#xff0c;深圳安锐科技正式发布国内首款无线自供电、一体化的斜拉索实时监测设备 “4G索力监测仪”&#xff0c;成功攻克了传统桥梁索体监测领域长期存在的实时性差、布设困难和成本高昂的行业难题&#xff0c;为斜拉桥、系杆拱桥提供全无线、自动化、云端实时同步的索力…

Pipeline 引用外部数据源最佳实践

场景解析在企业网络安全日志处理场景中&#xff0c;防火墙、入侵检测系统&#xff08;IDS&#xff09;等设备会持续产生大量日志&#xff0c;记录网络流量、访问请求、异常事件等基础信息&#xff0c;但这些原始日志仅能呈现表面现象&#xff0c;难以全面剖析安全威胁&#xff…

UI + MCP Client + MCP Server(并且链接多个Server)

项目结构前端项目--------->MCP Client----------->MCP Serverserver就不过多赘述了&#xff0c;他只是相当于添加了多个的tools 链接前后端 http.createServer创建一个服务器// ---------------------------------------------------------------- // server.js import …

香港站群服务器与普通香港服务器对比

在选择香港服务器时&#xff0c;用户常常会遇到"站群服务器"和"普通服务器"两种选项&#xff0c;虽然它们都基于香港数据中心的基础设施&#xff0c;但在 IP 地址配置、功能定位和管理复杂度、成本上存在显著差异&#xff0c;理解这些差异有助于用户根据实…

4.B树和B+树的区别?为什么MySQL选择B+树作为索引?

区别&#xff1a;1.数据存储位置B树每个节点都存储了索引和数据B树只有叶子节点存储数据&#xff0c;非叶子节点仅存储索引2.叶子节点的链接B树的所有叶子节点通过指针连接成一个双向链表&#xff0c;可以高效地进行范围查询或者顺序遍历B树则没有这样的连接关系&#xff0c;查…