java中arraylist去重推荐用linkedhashset保持插入顺序,或stream.distinct()函数式去重;需自定义字段去重时用collectors.tomap;所有方法均依赖equals()和hashcode()正确实现。

Java 中 ArrayList 去重有多种方式,核心思路是利用集合(如 HashSet、LinkedHashSet 或 TreeSet)的“自动去重”特性,或借助 Java 8 的 Stream API。选择哪种方法取决于你是否需要保持原始顺序、是否要求元素可排序、以及是否允许修改原列表。
用 LinkedHashSet 保持插入顺序去重(推荐)
LinkedHashSet 既去重,又保留元素首次出现的顺序,适合大多数场景。它比 HashSet 多一点点开销,但结果更可控。
操作步骤:
- 将原
ArrayList构造为LinkedHashSet(自动去重 + 保序) - 用该 Set 创建新的
ArrayList
示例代码:
List<string> list = new ArrayList(Arrays.asList("a", "b", "a", "c", "b"));
List<string> uniqueList = new ArrayList(new LinkedHashSet(list));
// 结果:["a", "b", "c"]
</string></string>
用 Stream.distinct()(Java 8+,简洁且函数式)
Stream.distinct() 内部基于 HashSet 实现去重,同样保持原始顺序(因为底层遍历是按源列表顺序进行的)。
注意:返回的是新列表,原列表不变;元素需正确实现 equals() 和 hashCode()。
示例代码:
List<string> list = Arrays.asList("x", "y", "x", "z");
List<string> uniqueList = list.stream()
.distinct()
.collect(Collectors.toList());
// 结果:["x", "y", "z"]
</string></string>
就地去重(不创建新列表,但需倒序遍历)
如果必须复用原列表对象且不能新建 List,可用倒序遍历 + remove(),避免因索引偏移导致漏删。
⚠️ 不推荐用于大数据量(remove() 在 ArrayList 中是 O(n) 操作,整体变 O(n²))。
示例代码:
List<string> list = new ArrayList(Arrays.asList("p", "q", "p", "r"));
for (int i = list.size() - 1; i >= 0; i--) {
String item = list.get(i);
if (list.indexOf(item) != i) { // 不是第一次出现的位置
list.remove(i);
}
}
// list 变为 ["p", "q", "r"]
</string>
按自定义规则去重(例如根据对象某个字段)
若 ArrayList 存的是自定义对象(如 User),默认 distinct() 或 HashSet 会调用 equals(),这时需重写 equals() 和 hashCode();或者用 Stream 配合 Collectors.toMap() 实现字段级去重。
示例(按 id 去重,保留第一个):
List<user> users = ...;
List<user> uniqueUsers = users.stream()
.collect(Collectors.collectingAndThen(
Collectors.toMap(User::getId, user -> user, (a, b) -> a),
map -> new ArrayList(map.values())
));
</user></user>
不复杂但容易忽略:所有方法都依赖元素的 equals() 和 hashCode() 行为。字符串、包装类等已正确实现,但自定义对象务必检查这两方法是否合理。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











