在 java 中,使用 stream 流对自定义对象数组去重的核心是确保对象能正确判断“重复”的逻辑。以下是具体实现方法及场景分析:
方法 1:直接使用 distinct()(需重写 equals 和 hashcode)
若自定义对象已正确重写 equals() 和 hashcode() 方法,可直接通过 distinct() 去重。
适用场景:对象的唯一性由所有字段共同决定(如数据库实体类的主键)。
示例代码
public class person {
private string id;
private string name;
// 构造方法、getter/setter 省略
@override
public boolean equals(object o) {
if (this == o) return true;
if (o == null || getclass() != o.getclass()) return false;
person person = (person) o;
return objects.equals(id, person.id); // 根据 id 判断是否相等
}
@override
public int hashcode() {
return objects.hash(id); // 基于 id 生成哈希
}
}
// 使用 stream 去重
person[] people = ...; // 自定义对象数组
list<person> uniquelist = arrays.stream(people)
.distinct()
.collect(collectors.tolist());
方法 2:基于对象的某个唯一属性去重(无需重写 equals 和 hashcode)
若无法修改对象类(如第三方库的类),或需根据部分字段去重,可用 collectors.tomap 或 treeset 实现。
(1) 使用 collectors.tomap
适用场景:根据唯一键(如 id)去重,保留第一个出现的元素。
list<person> uniquelist = arrays.stream(people)
.collect(collectors.tomap(
person::getid, // key 提取函数(根据 id 去重)
p -> p, // value 为对象本身
(existing, replacement) -> existing // 冲突时保留已存在的元素
))
.values() // 获取去重后的 value 集合
.stream()
.collect(collectors.tolist());
(2) 使用 treeset 自定义比较器
适用场景:需要根据多个字段去重,或动态指定去重规则。
list<person> uniquelist = arrays.stream(people)
.collect(collectors.tocollection(
() -> new treeset<>(comparator.comparing(p -> p.getid() + p.getname()))
))
.stream()
.collect(collectors.tolist());
方法 3:使用 filter + 内存状态去重
适用场景:需根据动态条件去重(如去重后保留最后一个元素)。
(1) 使用 concurrenthashmap 维护状态
set<string> seenids = concurrenthashmap.newkeyset();
list<person> uniquelist = arrays.stream(people)
.filter(p -> seenids.add(p.getid())) // 若 id 未出现过,保留
.collect(collectors.tolist());
(2) 保留最后一个出现的元素
list<person> uniquelist = arrays.stream(people)
.collect(collectors.tomap(
person::getid,
p -> p,
(oldvalue, newvalue) -> newvalue // 冲突时保留新元素
))
.values()
.stream()
.collect(collectors.tolist());
总结回答
- 直接去重:若对象重写了
equals()和hashcode(),直接用distinct()。 - 按属性去重:使用
collectors.tomap或treeset,根据唯一键(如id)过滤。 - 动态去重:通过
filter配合内存集合(如concurrenthashmap)控制去重逻辑。
关键点:明确业务中“重复”的定义(如全字段相等或部分字段相等),选择性能与代码简洁性兼顾的方案。
到此这篇关于java使用stream流对自定义对象数组去重的实现的文章就介绍到这了,更多相关java 自定义对象数组去重内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论