Are you still using contains to deduplicate List?

Initialize the List

Define the Student object

public class Student extends Person implements Serializable {
    private String name;
    private Integer age;
    private Integer testScore;

    public Student(String name, Integer age, Integer testScore) {
        this.name = name;
        this.age = age;
        this.testScore = testScore;
    }
    
    //省略set get方法

    @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(getName(), student.getName())
                && Objects.equals(getAge(), student.getAge())
                && Objects.equals(getTestScore(), student.getTestScore());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getName(), getAge(), getTestScore());
    }
}

 Initializes a collection List containing repeated elements

        allStudents = new ArrayList<Student>() {
   
   {
            for (int i = 0; i < 100000; i++) {
                add(new Student("爱琴孩", i, 99));
                add(new Student("爱琴孩", i, 99));
            }
        }};

Deduplication by contains

    @Test
    public void testDistinctByContains() {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        List<Student> distinctStudents = new ArrayList<>();
        System.out.println("去重前" + allStudents.size());
        for (Student student : allStudents) {
            if (distinctStudents.contains(student)) {
                continue;
            }
            distinctStudents.add(student);
        }
        System.out.println("去重后" + distinctStudents.size());
        stopWatch.stop();
        System.out.println("采用contains去重耗时" + stopWatch.getTotalTimeMillis());
    }

operation result

Look at the source code of the contains method, and match it by traversing

  Deduplication through HashSet

   @Test
    public void testDistinctByHashSet() {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        System.out.println("去重前" + allStudents.size());
        List<Student> distinctStudents = new ArrayList<>(new HashSet<>(allStudents));
        System.out.println("去重后" + distinctStudents.size());
        stopWatch.stop();
        System.out.println("采用Hashset去重耗时" + stopWatch.getTotalTimeMillis());
    }

operation result

Look at the source code of contains in HashSet

 containsKey is as follows

Deduplication through Stream

    @Test
    public void testDistinctByStream() {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        System.out.println("去重前" + allStudents.size());
        List<Student> distinctStudents = allStudents.stream().distinct().collect(Collectors.toList());
        System.out.println("去重后" + distinctStudents.size());
        stopWatch.stop();
        System.out.println("采用stream去重耗时" + stopWatch.getTotalTimeMillis());
    }

The result of the operation is as follows

 in conclusion

Deduplication efficiency, HashSet deduplication > Stream.distinct() deduplication > traverse contains deduplication

Guess you like

Origin blog.csdn.net/qq_28165595/article/details/131262374