Java对象List根据ID去重

Java对象List根据ID去重

  • 一、前言
    • [1. 使用HashSet去重](#1. 使用HashSet去重)
    • [2. 使用Stream API去重](#2. 使用Stream API去重)
    • [3. 使用HashMap去重](#3. 使用HashMap去重)
    • [4. 使用TreeSet去重并保持顺序](#4. 使用TreeSet去重并保持顺序)
    • [5. 使用LinkedHashMap确保插入顺序](#5. 使用LinkedHashMap确保插入顺序)

一、前言

在Java中处理大数据时,常常会遇到需要去重的情况。假设我们有一个对象数组,其中对象具有一个ID字段,我们希望将ID相同的对象去重,保留一个对象。下面将介绍几种实现这种去重操作的方法,包括使用集合、流(Streams)以及Map数据结构。

1. 使用HashSet去重

HashSet利用哈希表的特性,可以有效地对元素进行去重。此方法的时间复杂度接近O(n)。

java 复制代码
import java.util.*;

class MyObject {
    private int id;
    private String data;

    public MyObject(int id, String data) {
        this.id = id;
        this.data = data;
    }

    public int getId() {
        return id;
    }

    // Equals and hashCode should be based on the ID for correct behavior in HashSet
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        MyObject myObject = (MyObject) o;
        return id == myObject.id;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

    @Override
    public String toString() {
        return "MyObject{id=" + id + ", data='" + data + "'}";
    }
}

public class Main {
    public static void main(String[] args) {
        List<MyObject> list = Arrays.asList(
            new MyObject(1, "data1"),
            new MyObject(2, "data2"),
            new MyObject(1, "data3"),
            new MyObject(3, "data4")
        );

        Set<MyObject> set = new HashSet<>(list);
        List<MyObject> resultList = new ArrayList<>(set);

        System.out.println(resultList);
    }
}

2. 使用Stream API去重

Java 8引入了Stream API,可以通过distinct()方法直接对流中的元素进行去重。

java 复制代码
import java.util.*;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<MyObject> list = Arrays.asList(
            new MyObject(1, "data1"),
            new MyObject(2, "data2"),
            new MyObject(1, "data3"),
            new MyObject(3, "data4")
        );

        List<MyObject> resultList = list.stream()
            .filter(distinctByKey(MyObject::getId))
            .collect(Collectors.toList());

        System.out.println(resultList);
    }

    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }
}

3. 使用HashMap去重

利用HashMap的键值对特性,我们可以通过ID作为键来去重,只保留最后一个出现的对象。

java 复制代码
import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<MyObject> list = Arrays.asList(
            new MyObject(1, "data1"),
            new MyObject(2, "data2"),
            new MyObject(1, "data3"),
            new MyObject(3, "data4")
        );

        Map<Integer, MyObject> map = new HashMap<>();
        for (MyObject obj : list) {
            map.put(obj.getId(), obj);
        }

        List<MyObject> resultList = new ArrayList<>(map.values());
        System.out.println(resultList);
    }
}

4. 使用TreeSet去重并保持顺序

使用TreeSet可以实现去重并按自然顺序或指定顺序(通过Comparator)排序。

java 复制代码
import java.util.*;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<MyObject> list = Arrays.asList(
            new MyObject(1, "data1"),
            new MyObject(2, "data2"),
            new MyObject(1, "data3"),
            new MyObject(3, "data4")
        );

        TreeSet<MyObject> set = list.stream()
            .collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparingInt(MyObject::getId))));

        List<MyObject> resultList = new ArrayList<>(set);
        System.out.println(resultList);
    }
}

5. 使用LinkedHashMap确保插入顺序

LinkedHashMap不仅能去重,还能保持插入顺序。

java 复制代码
import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<MyObject> list = Arrays.asList(
            new MyObject(1, "data1"),
            new MyObject(2, "data2"),
            new MyObject(1, "data3"),
            new MyObject(3, "data4")
        );

        Map<Integer, MyObject> map = new LinkedHashMap<>();
        for (MyObject obj : list) {
            map.putIfAbsent(obj.getId(), obj);
        }

        List<MyObject> resultList = new ArrayList<>(map.values());
        System.out.println(resultList);
    }
}

以上是几种不同的方法来实现对象数组中根据ID去重的操作。这些方法各有优劣,具体选择取决于你的实际需求和数据特点。

相关推荐
淡海水7 小时前
07-04-并发-ConcurrentBag-T-工作窃取WorkStealing算法
开发语言·算法·c#·bag·concurrent·workstealing
CS_Zero7 小时前
C语言sizeof是函数吗?
c语言·开发语言
-今昭-8 小时前
《V2V 迁移实战:将 VMware 虚拟机转为 OpenStack 可用 Glance qcow2 镜像》
开发语言·python
zww89491119 小时前
匿名树洞系统开发实战:从需求分析到部署指南
java·eclipse
黑马程序员毕设10 小时前
基于Java的医院药品管理系统的优化设计与实现
java·开发语言·spring boot·小程序·架构·课程设计·毕设
木井巳10 小时前
【BFS/DFS 解决 FloodFill 算法】太平洋大西洋水流问题
java·算法·leetcode·深度优先·广度优先·宽度优先·推荐算法
白山编程大哥10 小时前
Java 集合算法:从排序、查找到底层原理的实战指南
java·python·算法
_Twink1e11 小时前
openJiuwen 实训营 Day 1 · WorkSwarm 入门教程
开发语言·c++·openjiuwen
devpotato11 小时前
缓存与数据库更新顺序不一致问题
java·数据库·redis
问天_观心11 小时前
大模型微调学习(一)
开发语言·人工智能·学习·语言模型·github