跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
Java集合遍历
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
{{Note|本教程适用于Java 8及以上版本。部分示例可能需要调整以适应更早的版本。}} = Java集合遍历 = '''Java集合遍历'''是指按特定顺序访问[[Java集合框架]]中元素的过程。作为数据处理的核心操作,遍历方式的选择直接影响代码的性能和可读性。本章将系统讲解5种主流遍历方法及其最佳实践。 == 核心概念 == Java集合框架提供了三种主要的遍历范式: * '''显式迭代器模式''':通过{{code|Iterator}}或{{code|ListIterator}}实现 * '''隐式迭代语法''':增强for循环(for-each)语法糖 * '''函数式遍历''':Java 8引入的Stream API <mermaid> graph TD A[遍历方式] --> B[Iterator] A --> C[For-Each] A --> D[Stream API] B --> E[允许删除元素] C --> F[语法简洁] D --> G[函数式操作] </mermaid> == 遍历方法详解 == === 1. 迭代器(Iterator) === 最基础的遍历方式,适用于所有{{code|Collection}}实现类: <syntaxhighlight lang="java"> List<String> fruits = Arrays.asList("Apple", "Banana", "Cherry"); Iterator<String> iterator = fruits.iterator(); while (iterator.hasNext()) { String fruit = iterator.next(); System.out.println(fruit); // 安全删除当前元素 if (fruit.startsWith("A")) { iterator.remove(); } } </syntaxhighlight> '''输出:''' <pre> Apple Banana Cherry </pre> {{Warning|直接调用集合的{{code|remove()}}方法而非迭代器的{{code|remove()}}会导致{{code|ConcurrentModificationException}}}} === 2. 增强for循环 === 语法最简洁的遍历方式,编译后实际转换为迭代器模式: <syntaxhighlight lang="java"> Set<Integer> primes = new HashSet<>(Set.of(2, 3, 5, 7)); for (Integer prime : primes) { System.out.println(prime * 2); } </syntaxhighlight> '''特点:''' * 代码可读性高 * 不支持修改集合结构 * 线程不安全 === 3. forEach()方法 === Java 8引入的默认方法,支持Lambda表达式: <syntaxhighlight lang="java"> Map<String, Integer> inventory = Map.of("Laptop", 5, "Phone", 10); inventory.forEach((item, quantity) -> System.out.printf("%s: %d in stock%n", item, quantity) ); </syntaxhighlight> === 4. 列表迭代器(ListIterator) === {{code|List}}特有的双向迭代器: <syntaxhighlight lang="java"> List<String> colors = new ArrayList<>(List.of("Red", "Green", "Blue")); ListIterator<String> listIterator = colors.listIterator(colors.size()); // 逆向遍历 while (listIterator.hasPrevious()) { System.out.println(listIterator.previous()); } </syntaxhighlight> === 5. Stream API === 函数式编程风格的遍历: <syntaxhighlight lang="java"> List<Product> products = getProducts(); products.stream() .filter(p -> p.getPrice() > 100) .map(Product::getName) .forEach(System.out::println); </syntaxhighlight> == 性能比较 == 下表比较不同集合类型的遍历性能(时间复杂度): {| class="wikitable" |- ! 集合类型 !! Iterator !! For-Each !! forEach() !! Stream |- | {{code|ArrayList}} | O(n) | O(n) | O(n) | O(n) |- | {{code|LinkedList}} | O(n) | O(n) | O(n) | O(n) |- | {{code|HashSet}} | O(n) | O(n) | O(n) | O(n) |- | {{code|TreeSet}} | O(n) | O(n) | O(n) | O(n log n) |} <math>T(n)_{TreeSet} = O(n \log n)</math> 因为Stream的排序操作 == 并发修改异常处理 == 当遍历时修改集合会抛出{{code|ConcurrentModificationException}},解决方案: * 使用迭代器的{{code|remove()}}方法 * 使用{{code|CopyOnWriteArrayList}}等并发集合 * 先收集要修改的元素,遍历结束后再处理 <syntaxhighlight lang="java"> List<String> data = new ArrayList<>(List.of("A", "B", "C")); List<String> toRemove = new ArrayList<>(); for (String item : data) { if (item.equals("B")) { toRemove.add(item); } } data.removeAll(toRemove); </syntaxhighlight> == 最佳实践 == 1. '''读操作''':优先使用for-each循环 2. '''修改操作''':必须使用{{code|Iterator}} 3. '''复杂处理''':考虑Stream API 4. '''并行处理''':使用{{code|parallelStream()}} == 实际案例 == '''电商平台购物车结算''': <syntaxhighlight lang="java"> public BigDecimal calculateTotal(Cart cart) { return cart.getItems().stream() .map(item -> item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity()))) .reduce(BigDecimal.ZERO, BigDecimal::add); } </syntaxhighlight> '''数据库查询结果处理''': <syntaxhighlight lang="java"> try (ResultSet rs = statement.executeQuery("SELECT * FROM users")) { List<User> users = new ArrayList<>(); while (rs.next()) { users.add(new User(rs.getInt("id"), rs.getString("name"))); } users.forEach(user -> sendWelcomeEmail(user)); } </syntaxhighlight> == 常见问题 == {{QA |question = 为什么不能在foreach循环中直接删除元素? |answer = 因为foreach实际使用迭代器实现,直接删除会破坏迭代器状态,导致下次调用{{code|next()}}时抛出异常。 }} {{QA |question = Stream遍历比传统方式慢吗? |answer = 对于简单操作和小数据集,Stream可能有轻微性能开销。但对于复杂操作和大数据集,Stream的并行能力能显著提升性能。 }} == 进阶主题 == * 自定义迭代器实现{{code|Iterable}}接口 * 使用Spliterator进行并行遍历 * 深度比较不同JDK版本的遍历性能差异 {{Tip|在Java 21+中,考虑使用SequencedCollection的新遍历方法如{{code|reversed()}}} [[Category:编程语言]] [[Category:Java]] [[Category:Java集合框架]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)
该页面使用的模板:
模板:Code
(
编辑
)
模板:Mbox
(
编辑
)
模板:Note
(
编辑
)
模板:QA
(
编辑
)
模板:Warning
(
编辑
)
模块:Arguments
(
编辑
)
模块:Message box
(
编辑
)
模块:Message box/ambox.css
(
编辑
)
模块:Message box/configuration
(
编辑
)
模块:Yesno
(
编辑
)