Java Collections.replaceAll 方法
上次修改时间:2025 年 4 月 20 日
Collections.replaceAll
方法是 Java Collections 框架中的一个实用方法。 它将 List 中指定值的所有出现都替换为另一个值。 此方法提供了一种方便的方式来对列表进行批量替换。
该方法定义在 java.util.Collections
类中。 它适用于任何 List 实现,并在线性时间内执行替换。 如果至少进行了一次替换,该方法将返回 true。
Collections.replaceAll 概述
replaceAll
方法签名是:public static <T> boolean replaceAll(List<T> list, T oldVal, T newVal)
。 它接受三个参数:要修改的列表、要替换的值和新值。
该方法从头到尾扫描列表。 对于每个等于 oldVal(使用 equals
)的元素,它用 newVal 替换它。 替换是就地完成的,修改原始列表。
基本 replaceAll 示例
此示例演示了 Collections.replaceAll
的基本用法。 我们创建一个字符串列表,并将所有出现的 "Apple" 替换为 "Orange"。 该示例显示了替换前后的列表。
package com.zetcode; import java.util.Arrays; import java.util.Collections; import java.util.List; public class BasicReplaceAll { public static void main(String[] args) { List<String> fruits = Arrays.asList( "Apple", "Banana", "Apple", "Cherry", "Apple"); System.out.println("Original list: " + fruits); boolean changed = Collections.replaceAll(fruits, "Apple", "Orange"); System.out.println("Modified list: " + fruits); System.out.println("Replacements made: " + changed); } }
在此代码中,我们从一个包含三个 "Apple" 元素的列表开始。 在调用 replaceAll
之后,所有 "Apple" 元素都将替换为 "Orange"。 该方法返回 true,因为发生了替换。
输出显示了列表转换。 这是 replaceAll
最简单的用例,演示了其基本功能。
replaceAll 与 Integer 列表
此示例显示了 Collections.replaceAll
与 Integer 列表一起使用。 我们将所有数字 5 的出现替换为 50。 该示例还演示了未发生替换时的返回值。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class IntegerReplaceAll { public static void main(String[] args) { List<Integer> numbers = new ArrayList<>(); Collections.addAll(numbers, 1, 5, 3, 5, 7, 5); System.out.println("Original numbers: " + numbers); // Replace 5 with 50 boolean changed1 = Collections.replaceAll(numbers, 5, 50); System.out.println("After first replacement: " + numbers); System.out.println("Replacements made: " + changed1); // Try replacing 99 (not present) boolean changed2 = Collections.replaceAll(numbers, 99, 100); System.out.println("After second replacement: " + numbers); System.out.println("Replacements made: " + changed2); } }
此示例演示了 replaceAll
与数值的使用。 第一个调用成功地将所有 5 替换为 50。 第二个调用尝试替换 99,而列表中没有 99,因此没有发生更改。
输出显示了该方法在这两种情况下的行为。 返回值指示是否执行了任何替换。
replaceAll 与自定义对象
此示例演示了将 Collections.replaceAll
与自定义对象一起使用。 我们创建一个简单的 Person 类,并将一个 Person 的所有实例替换为另一个 Person。 该示例重点介绍了正确实现 equals
的重要性。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; Person person = (Person) obj; return age == person.age && name.equals(person.name); } @Override public String toString() { return name + "(" + age + ")"; } } public class CustomObjectReplaceAll { public static void main(String[] args) { List<Person> people = new ArrayList<>(); Collections.addAll(people, new Person("Alice", 25), new Person("Bob", 30), new Person("Alice", 25), new Person("Charlie", 35) ); System.out.println("Original list: " + people); Person oldPerson = new Person("Alice", 25); Person newPerson = new Person("Alex", 26); boolean changed = Collections.replaceAll(people, oldPerson, newPerson); System.out.println("Modified list: " + people); System.out.println("Replacements made: " + changed); } }
此示例显示了当自定义对象正确实现 equals
时,replaceAll
可以使用它们。 我们将所有 Alice (25) 实例替换为 Alex (26)。 equals
方法比较名称和年龄字段。
输出演示了 Person 对象的替换。 如果没有正确的 equals
实现,该方法将找不到要替换的匹配项。
replaceAll 与 Null 值
此示例探讨了 Collections.replaceAll
如何处理 null 值。 我们创建一个包含 null 元素的列表,并演示将它们替换为非 null 值,反之亦然。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class NullReplaceAll { public static void main(String[] args) { List<String> items = new ArrayList<>(); Collections.addAll(items, "A", null, "B", null, "C"); System.out.println("Original list: " + items); // Replace null with "X" boolean changed1 = Collections.replaceAll(items, null, "X"); System.out.println("After replacing null with X: " + items); System.out.println("Replacements made: " + changed1); // Replace "B" with null boolean changed2 = Collections.replaceAll(items, "B", null); System.out.println("After replacing B with null: " + items); System.out.println("Replacements made: " + changed2); } }
此示例显示了 replaceAll
可以将 null 值作为 oldVal 和 newVal 参数处理。 我们首先将所有 null 替换为 "X",然后将 "B" 替换为 null。
输出演示了 null 处理按预期工作。 该方法既可以通过替换它们来删除 null,也可以引入 null 作为替换。
不区分大小写的 replaceAll
此示例演示了使用 Collections.replaceAll
进行不区分大小写的替换。 由于该方法使用 equals
进行比较,因此我们需要一个针对不区分大小写匹配的解决方法。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class CaseInsensitiveReplaceAll { public static void main(String[] args) { List<String> words = new ArrayList<>(); Collections.addAll(words, "Apple", "apple", "APPLE", "banana"); System.out.println("Original list: " + words); // Traditional replaceAll is case-sensitive boolean changed1 = Collections.replaceAll(words, "apple", "orange"); System.out.println("After case-sensitive replacement: " + words); System.out.println("Replacements made: " + changed1); // Case-insensitive replacement String target = "apple"; String replacement = "orange"; words.replaceAll(s -> s.equalsIgnoreCase(target) ? replacement : s); System.out.println("After case-insensitive replacement: " + words); } }
此示例显示了两种方法。 首先,标准的 replaceAll
,区分大小写。 然后,我们使用 List.replaceAll
和一个 lambda 表达式进行不区分大小写的匹配。
输出演示了这两种方法之间的区别。 对于不区分大小写的操作,lambda 方法比 Collections.replaceAll
更灵活。
replaceAll vs List.replaceAll
此示例比较了 Collections.replaceAll
与 Java 8 的 List.replaceAll
。 尽管相似,但它们具有不同的功能。 该示例并排演示了这两种方法。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class ReplaceAllComparison { public static void main(String[] args) { List<Integer> numbers = new ArrayList<>(); Collections.addAll(numbers, 1, 2, 3, 4, 5); System.out.println("Original list: " + numbers); // Collections.replaceAll - replace specific value Collections.replaceAll(numbers, 3, 30); System.out.println("After Collections.replaceAll: " + numbers); // List.replaceAll - transform all elements numbers.replaceAll(n -> n * 10); System.out.println("After List.replaceAll: " + numbers); } }
此示例重点介绍了这两种方法之间的主要区别。 Collections.replaceAll
替换特定值,而 List.replaceAll
可以通过 UnaryOperator 转换所有元素。
输出显示了每种方法如何以不同的方式修改列表。 选择 Collections.replaceAll
进行简单的值替换,选择 List.replaceAll
进行更复杂的转换。
性能注意事项
此示例检查 Collections.replaceAll
的性能特征。 我们创建一个大型列表并测量替换所花费的时间。 该示例演示了它的线性时间复杂度。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class ReplaceAllPerformance { public static void main(String[] args) { final int SIZE = 1_000_000; List<Integer> numbers = new ArrayList<>(SIZE); // Fill the list with 1s, with a 5 at the end for (int i = 0; i < SIZE - 1; i++) { numbers.add(1); } numbers.add(5); long startTime = System.nanoTime(); Collections.replaceAll(numbers, 1, 10); long endTime = System.nanoTime(); System.out.println("Time taken: " + (endTime - startTime) / 1_000_000 + " ms"); System.out.println("Last element (unchanged): " + numbers.get(numbers.size() - 1)); } }
此示例创建一个大型列表并测量将所有 1 替换为 10 所需的时间。 尽管列表很大,但该操作很快完成,这表明了 replaceAll
的 O(n) 时间复杂度。
输出显示了操作时间和确认最后一个元素 (5) 保持不变。 此测试有助于理解该方法的性能特征。
来源
Java Collections.replaceAll 文档
在本文中,我们深入探讨了 Java Collections.replaceAll
方法。 我们涵盖了基本用法、自定义对象、null 处理和性能考虑。 理解此方法有助于高效的列表修改。
作者
列出所有Java教程。