开发者

java使用Stream流对自定义对象数组去重的实现

目录
  • 方法 1:直接使用 distinct()(需重写 equals 和 hashCode)
    • 示例代码
  • 方法 2:基于对象的某个唯一属性去重(无需重写 equals 和 hashCode)
    • (1) 使用 Collectors.toMap
    • (2) 使用 TreeSet 自定义比较器
  • 方法 3:使用 filter + 内存状态去重
    • (1) 使用 ConcurrentHashMap 维护状态
    • (2) 保留最后一个出现的元素
  • 总结回答

    在 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&编程客栈lt;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<>php(Comparator.comparing(p -> p.getId() + p.getName()))
            ))
            .stream()
            .collwww.devze.comect(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 自定义对象数组去重内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜