In the Stream stream, deduplication based on the object + the attribute in the specified object

First define a student class:

@Data
@AllArgsConstructor
public class Student {
    
    

    private Long id;
    private String name;
    private Integer age;
    private Double high;
}

Construct four objects in the main method, of which the fourth object is a duplicate object, and now perform deduplication of objects and deduplication of a certain attribute in the object

public class ListStreamDistinctTest {
    
    

    public static void main(String[] args) {
    
    
        // 一个集合中放入4个学生对象
        List<Student> list = new ArrayList<>();
        list.add(new Student(10002L, "ZhangSan", 18, 175.2));
        list.add(new Student(10001L, "LiSi", 19, 175.2));
        list.add(new Student(10004L, "Peter", 19, 170.8));
        list.add(new Student(10004L, "Peter", 19, 170.8));
	}
	  }

1. Deduplication according to the object:
the following code is written in the main function:

 System.out.println("整个对象去重:");
        list.stream().distinct()
        .forEach(System.out::println);

The running results are as follows. It can be seen that the distinct of the stream only deduplicates the objects, and deduplicates the same third and fourth objects.
insert image description here
2. Deduplication according to a certain attribute (age) in the object:
method 1. Define other methods:
The following code is written in the main function:

 System.out.println("指定age属性去重(方法一):");
        list.stream().filter(distinctByKey1(s -> s.getAge()))
          .forEach(System.out::println);

Define a static method here: distinctByKey1, written outside the main function:

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

operation result:
insert image description here

Method 2:
The following code is written in the main function:

 System.out.println("指定age属性去重(方法二):");
        TreeSet<Student> students = new TreeSet<>(Comparator.comparing(s -> s.getAge()));
        for (Student student : list) {
    
    
            students.add(student);
        }
        new ArrayList<>(students)
                .forEach(System.out::println);

By constructing a treeset, traversing the list, adding elements to the treeset to complete the deduplication, and then converting it into a List, the running result:
insert image description here

Method 3:
The following code is written in the main function:

 System.out.println("指定age属性去重(方法三):");
        list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(s -> s.getAge()))), ArrayList::new))
                .forEach(System.out::println);

As a variant of Method 2, the running result is:
insert image description here

Reference link:
Java8 stream-List deduplication distinct, and deduplication of specified fields

Guess you like

Origin blog.csdn.net/weixin_42260782/article/details/129826507