Java 8 Stream.distinct() list de duplication example

Keywords: Java

Java 8 Stream.distinct() example
 

     In this article, we will provide a Java 8 Stream distinct () example.   Distinct () returns a Stream composed of different elements of the Stream. Distinct () is the method of the Stream interface. Distinct () uses hashCode () and equals () methods to get different elements. Therefore, our class must implement the hashCode () and equals () methods. If distinct () is processing an ordered flow, for repeated elements, the elements that appear first in the encounter order are retained, and it is stable to select different elements in this way. In the case of disordered flow, the selection of different elements is not necessarily stable and can be changed. Distinct() performs stateful intermediate operations. In the case of parallel flows with ordered flows, maintaining the stability of distinct () requires a high cost because it requires a lot of buffer overhead. If we don't need to maintain the consistency of encounter order, we should be able to use the unordered flow implemented by the BaseStream.unordered () method.

1. Stream.distinct()

The distinct() method is declared as follows:
Stream<T> distinct()
   

It is the method of the Stream interface. In this example, we have a list of string data types that contain duplicate elements

DistinctSimpleDemo.java

   
  1. package com.concretepage;
  2. import java.util.Arrays;
  3. import java.util.List;
  4. import java.util.stream.Collectors;
  5. public class DistinctSimpleDemo {
  6. public static void main(String[] args) {
  7. List<String> list = Arrays.asList( "AA", "BB", "CC", "BB", "CC", "AA", "AA");
  8. long l = list.stream().distinct().count();
  9. System.out.println( "No. of distinct elements:"+l);
  10. String output = list.stream().distinct().collect(Collectors.joining( ","));
  11. System.out.println(output);
  12. }
  13. }
Output  
   
  1. No. of distinct elements: 3
  2. AA,BB,CC

2. Stream.distinct() with List of Objects

In this example, we have a list of Book objects. To de duplicate the list, this class overrides hashCode () and equals ().

Book.java

   
  1. package com.concretepage;
  2. public class Book {
  3. private String name;
  4. private int price;
  5. public Book(String name, int price) {
  6. this.name = name;
  7. this.price = price;
  8. }
  9. public String getName() {
  10. return name;
  11. }
  12. public int getPrice() {
  13. return price;
  14. }
  15. @Override
  16. public boolean equals(final Object obj) {
  17. if (obj == null) {
  18. return false;
  19. }
  20. final Book book = (Book) obj;
  21. if ( this == book) {
  22. return true;
  23. } else {
  24. return ( this.name.equals(book.name) && this.price == book.price);
  25. }
  26. }
  27. @Override
  28. public int hashCode() {
  29. int hashno = 7;
  30. hashno = 13 * hashno + (name == null ? 0 : name.hashCode());
  31. return hashno;
  32. }
  33. }
DistinctWithUserObjects.java
   
  1. package com.concretepage;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. public class DistinctWithUserObjects {
  5. public static void main(String[] args) {
  6. List<Book> list = new ArrayList<>();
  7. {
  8. list.add( new Book( "Core Java", 200));
  9. list.add( new Book( "Core Java", 200));
  10. list.add( new Book( "Learning Freemarker", 150));
  11. list.add( new Book( "Spring MVC", 300));
  12. list.add( new Book( "Spring MVC", 300));
  13. }
  14. long l = list.stream().distinct().count();
  15. System.out.println( "No. of distinct books:"+l);
  16. list.stream().distinct().forEach(b -> System.out.println(b.getName()+ "," + b.getPrice()));
  17. }
  18. }
Output  

    
  1. No. of distinct books: 3
  2. Core Java, 200
  3. Learning Freemarker, 150
  4. Spring MVC, 300

3. Distinct by Property

distinct () does not provide a direct implementation of de duplication of object lists by attributes. It works based on hashCode () and equals (). If we want to de duplicate the object list according to the object properties, we can implement it by other methods. The following code snippet shows:

    
  1. static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
  2. Map<Object,Boolean> seen = new ConcurrentHashMap<>();
  3. return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
  4. }
The above method can be received as a parameter by the filter() of the Stream interface, as shown below:

list.stream().filter(distinctByKey(b -> b.getName())); 
    

The distinguishbykey () method returns a hash map using ConcurrentHashMap   To maintain the previously seen state   Predicate   Example, the following is a complete example of using object properties for de duplication.

DistinctByProperty.java

    
  1. package com.concretepage;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import java.util.Map;
  5. import java.util.concurrent.ConcurrentHashMap;
  6. import java.util.function.Function;
  7. import java.util.function.Predicate;
  8. public class DistinctByProperty {
  9. public static void main(String[] args) {
  10. List<Book> list = new ArrayList<>();
  11. {
  12. list.add( new Book( "Core Java", 200));
  13. list.add( new Book( "Core Java", 300));
  14. list.add( new Book( "Learning Freemarker", 150));
  15. list.add( new Book( "Spring MVC", 200));
  16. list.add( new Book( "Hibernate", 300));
  17. }
  18. list.stream().filter(distinctByKey(b -> b.getName()))
  19. .forEach(b -> System.out.println(b.getName()+ "," + b.getPrice()));
  20. }
  21. private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
  22. Map<Object,Boolean> seen = new ConcurrentHashMap<>();
  23. return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
  24. }
  25. }
Output  

    
  1. Core Java, 200
  2. Learning Freemarker, 150
  3. Spring MVC, 200
  4. Hibernate, 300
from :  https://www.concretepage.com/java/jdk-8/java-8-distinct-example

Posted by phast1 on Fri, 08 Oct 2021 00:43:14 -0700