Java中有没有更简便的方法移除数组中属性相同的重复对象?
原生JDK Lambda 实现方案
你原有手写的双层循环时间复杂度为O(n²),数据量大的时候性能表现较差,用JDK8+自带的Stream+Lambda可以写出更简洁、性能更优的实现,支持任意自定义去重规则:
首先先写一个通用的去重谓词工具方法:
import java.util.Set; import java.util.Arrays; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; public class DistinctUtils { public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) { Set<Object> seen = ConcurrentHashMap.newKeySet(); return t -> seen.add(keyExtractor.apply(t)); } }
不同去重规则的使用示例:
- 按姓名去重,保留首次出现的元素:
List<Person> distinctByName = people.stream() .filter(DistinctUtils.distinctByKey(Person::getName)) .toList(); // JDK16及以上版本可用,低版本替换为.collect(Collectors.toList())
- 按「年龄相同+职业首字母相同」规则去重:
List<Person> distinctByComplexRule = people.stream() .filter(DistinctUtils.distinctByKey(p -> { // 自定义构造唯一标识key,规则可任意调整 char firstJobLetter = p.getJob().charAt(0); return Arrays.asList(p.getAge(), firstJobLetter); })) .toList();
以上实现和你原有双层循环的结果完全一致,都是保留首次出现的元素,时间复杂度为O(n)。
第三方库实现方案
常用的Java工具库都封装了这类集合过滤能力,不需要手写循环:
- Apache Commons Collections:可以直接在原集合上修改,效果和你原代码逻辑一致
Set<Object> seen = new HashSet<>(); // 按姓名去重示例,修改规则只需要替换add方法里的key构造逻辑 CollectionUtils.filter(people, p -> seen.add(p.getName()));
- Guava:可以用FluentIterable配合自定义Predicate实现,逻辑和上面的Stream方案一致。
内容的提问来源于stack exchange,提问作者Infini Dim
相关产品推荐
相关产品推荐

