JAVA实体类集合该如何去重?

2023-12-13 20:46:29

JAVA实体类集合该如何去重?

最近在工作中经常遇到需要去重的需求,所以特意系统的来梳理一下

单元素去重

方法一:利用Set去重

 public static void main(String[] args) {

        // 生成含重复元素的集合并打印
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(2);
        list.add(3);
        System.out.println("去重前:" + list);


        // 利用HashSet去重后并打印
        HashSet<Integer> hashSet = new HashSet<>(list);
        list.clear();
        list.addAll(hashSet);
        System.out.println("去重后:" + list);
    }

执行:

在这里插入图片描述

方法二:利用java 8的stream写法,方便优雅快捷高效

 public static void main(String[] args) {

        // 生成含重复元素的集合并打印
        List<Integer> list = new ArrayList<>();
        list.add(2);
        list.add(3);
        list.add(3);
        list.add(4);
        System.out.println("去重前:" + list);


        // 利用java 8的stream写法
        list = list.stream().distinct().collect(Collectors.toList());
        System.out.println("去重后:" + list);
    }

执行:

在这里插入图片描述

实体类对象去重

先新建实体类:

/**
 * @Author: guqueyue
 * @Description: 学生类
 * @Date: 2023/12/12
 **/
public class Student {

    /** 姓名 */
    private String name;

    /** 年龄 */
    private Integer age;
    
    public Student() {
    }

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

单属性去重

方法一:利用map去重
public static void main(String[] args) {

        // 生成学生集合
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("张三", 19));
        studentList.add(new Student("张三", 22));
        studentList.add(new Student("李四", 18));
        System.out.println("去重前: " + studentList);

        // 利用map根据姓名去重
        Map<String, Student> map = new HashMap<>();
        for (Student student : studentList) {
            map.put(student.getName(), student);
        }
        studentList = new ArrayList<>(map.values());
        System.out.println("去重后: " + studentList);
    }

执行得:

在这里插入图片描述

方法二:利用map去重,java 8语法

比方法一代码看似简洁了,但实际上好似更加复杂了

 public static void main(String[] args) {

        // 生成学生集合
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("张三", 19));
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("李四", 18));
        System.out.println("去重前: " + studentList);

        // 利用map根据姓名去重,java 8语法
        studentList = studentList.stream()
                                 .collect(Collectors.toMap(student -> student.getName(), Function.identity(), (o, n) -> n))
                                 .values()
                                 .stream().collect(Collectors.toList());
        System.out.println("去重后: " + studentList);
    }

执行:

在这里插入图片描述

方法三:利用Set去重
public static void main(String[] args) {

        // 生成学生集合
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("张三", 19));
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("李四", 18));
        System.out.println("去重前: " + studentList);

        // 利用Set去重
//        Set<Student> set = new TreeSet<>(((o1, o2) -> o1.getName().compareTo(o2.getName())));
        Set<Student> set = new TreeSet<>((Comparator.comparing(Student::getName)));
        set.addAll(studentList);
        studentList.clear();
        studentList = new ArrayList<>(set);
        System.out.println("去重后: " + studentList);
    }

执行:

在这里插入图片描述

方法四: 利用Set去重,java 8写法
public static void main(String[] args) {

        // 生成学生集合
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("张三", 19));
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("李四", 18));
        System.out.println("去重前: " + studentList);

        // 利用Set去重,java 8写法
        studentList = studentList.stream().collect(
                                            Collectors.collectingAndThen(
                                                    Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getName))),
                                                    ArrayList::new
                                            )
                                    );
        System.out.println("去重后: " + studentList);
    }

执行:

在这里插入图片描述

方法五:定义过滤器
public static void main(String[] args) {

        // 生成学生集合
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("张三", 19));
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("李四", 18));
        System.out.println("去重前: " + studentList);

        // 定义过滤器
        studentList = studentList.stream().filter(distinctKey(Student::getName)).collect(Collectors.toList());
        System.out.println("去重后: " + studentList);
    }

    /**
     * @Description 自定义过滤器
     * @Param [keyExtractor]
     * @return java.util.function.Predicate<T>
     **/
    public static <T> Predicate<T> distinctKey(Function<? super T, Object> keyExtractor) {
        Map<Object, Boolean> map = new ConcurrentHashMap<>();
        return o -> map.putIfAbsent(keyExtractor.apply(o), Boolean.TRUE) == null;
    }

执行:

在这里插入图片描述

补充

补充一点,如何提取去重后的单元素集合:

public static void main(String[] args) {

        // 生成学生集合
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("张三", 19));
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("李四", 18));
        System.out.println("去重前: " + studentList);

        // 提取去重后的姓名
        List<String> nameList = studentList.stream().map(Student::getName).distinct().collect(Collectors.toList());
        System.out.println("去重后: " + nameList);
    }

执行:

在这里插入图片描述

多属性去重

方法一:利用map根据姓名、年龄去重
public static void main(String[] args) {

        // 生成学生集合
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("张三", 19));
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("李四", 18));
        System.out.println("去重前: " + studentList);

        // 利用map根据姓名、年龄去重
        Map<String, Student> map = new HashMap<>();
        for (Student student : studentList) {
            map.put(student.getName() + "_" + student.getAge(), student);
        }
        studentList = new ArrayList<>(map.values());
        System.out.println("去重后: " + studentList);
    }

执行:

在这里插入图片描述

方法二:利用map根据姓名、年龄去重,java 8写法
public static void main(String[] args) {

        // 生成学生集合
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("张三", 19));
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("李四", 18));
        System.out.println("去重前: " + studentList);

        // 利用map根据姓名、年龄去重,java 8写法
        studentList = studentList.stream()
                                 .collect(Collectors.toMap(s -> s.getName() + "_" + s.getAge(), Function.identity(), (o, n) -> n))
                                 .values()
                                 .stream().collect(Collectors.toList());
        System.out.println("去重后: " + studentList);
    }

执行:

在这里插入图片描述

方法三:利用Set根据姓名、年龄去重,java 8写法
public static void main(String[] args) {

        // 生成学生集合
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("张三", 19));
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("李四", 18));
        System.out.println("去重前: " + studentList);

        // 利用Set根据姓名、年龄去重,java 8写法
        studentList = studentList.stream().collect(Collectors.collectingAndThen(
                                                   Collectors.toCollection(
                                                           () -> new TreeSet<>(Comparator.comparing(o -> o.getName() + "_" + o.getAge()))
                                                   ), ArrayList::new));
        System.out.println("去重后: " + studentList);
    }

执行:

在这里插入图片描述

重写equals()和hashCode()方法

下面的几种方法首先需要在实体类中重写equals()和hashCode()方法

@Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return Objects.equals(name, student.name) && Objects.equals(age, student.age);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
方法四:利用java 8 的distinct(),最推荐
 public static void main(String[] args) {

        // 生成学生集合
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("张三", 19));
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("李四", 18));
        System.out.println("去重前: " + studentList);

        // 利用java 8 的distinct(),根据姓名和年龄去重
        studentList = studentList.stream().distinct().collect(Collectors.toList());
        System.out.println("去重后: " + studentList);
    }

执行:

在这里插入图片描述

方法五:通过contains()方法来调用equals()方法来对比
 public static void main(String[] args) {

        // 生成学生集合
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("张三", 19));
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("李四", 18));
        System.out.println("去重前: " + studentList);

        // 通过contains()方法来调用equals()方法来对比,根据姓名和年龄去重
        List<Student> newStudentList = new ArrayList<>();
        for (Student student : studentList) {
            if (!newStudentList.contains(student)) {
                newStudentList.add(student);
            }
        }
        System.out.println("去重后: " + newStudentList);
    }

执行:

在这里插入图片描述

方法六:重写方法后,通过Set去重
 public static void main(String[] args) {

        // 生成学生集合
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("张三", 19));
        studentList.add(new Student("张三", 18));
        studentList.add(new Student("李四", 18));
        System.out.println("去重前: " + studentList);

        // 通过Set,根据姓名和年龄去重
       Set<Student> set = new HashSet<>(studentList);
       studentList.clear();
       studentList.addAll(set);
        System.out.println("去重后: " + studentList);
    }

执行:

在这里插入图片描述
完结撒花!!!
在这里插入图片描述

文章来源:https://blog.csdn.net/Qizhi_Hu/article/details/134974996
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。