ArrayList去重需借助外部工具:推荐LinkedHashSet(保持顺序)、Stream.distinct(语义清晰)、toMap(按字段去重)或手动遍历(仅适用于小数据)。

Java 中的 ArrayList 本身不提供去重方法,需要借助其他工具或逻辑实现。最常用、简洁且保留原顺序的方式是用 LinkedHashSet;若需更灵活控制(如按对象字段去重),则可用 Stream 或手动遍历。
用 LinkedHashSet 去重(推荐,保持插入顺序)
LinkedHashSet 能自动去重,同时保留元素首次出现的顺序,适合大多数基础场景。
示例代码:
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "a", "c", "b"));
List<String> uniqueList = new ArrayList<>(new LinkedHashSet<>(list));
// 结果:["a", "b", "c"]
- 适用于
String、基本类型包装类、重写了equals()和hashCode()的自定义对象 - 注意:原
list不变,返回的是新列表 - 如果想复用原引用,可写成
list.clear(); list.addAll(uniqueList);
用 Stream.distinct()(Java 8+,语义清晰)
利用 Stream 的 distinct() 方法,底层也依赖元素的 equals() 和 hashCode()。
立即学习“Java免费学习笔记(深入)”;
List<String> list = Arrays.asList("x", "y", "x", "z");
List<String> uniqueList = list.stream()
.distinct()
.collect(Collectors.toList());
- 链式调用,适合配合过滤、映射等操作一起使用
- 同样不修改原列表,返回新列表
- 对自定义对象有效,前提是正确重写
equals和hashCode
按对象特定字段去重(例如 List<User> 按 id 去重)
当不能或不想重写 equals 时,可用 Collectors.toMap() 或自定义收集器。
List<User> users = ...;
List<User> uniqueById = users.stream()
.collect(Collectors.collectingAndThen(
Collectors.toMap(User::getId, user -> user, (u1, u2) -> u1),
map -> new ArrayList<>(map.values())
));
-
User::getId作为 key,保证每个 id 只保留一个 User - 合并函数
(u1, u2) -> u1表示遇到重复 id 时保留第一个 - 也可换成
(u1, u2) -> u2保留最后一个
手动遍历 + contains(简单但性能差,仅适合小数据)
适合教学理解或极小列表,时间复杂度 O(n²),不建议用于大数据量。
List<String> original = ...;
List<String> unique = new ArrayList<>();
for (String s : original) {
if (!unique.contains(s)) {
unique.add(s);
}
}
- 逻辑直观,无需额外依赖
-
contains在 ArrayList 中逐个比较,效率低 - 若改用
HashSet辅助判断,可优化为 O(n),但不如直接用LinkedHashSet简洁


















