Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 Streams : get non repeated counts

Here is the SQL version for the input and output :

     with tab1 as (

        select 1 as id from dual union all
        select 1 as id from dual union all
        select 2 as id from dual union all
        select 2 as id from dual union all
        select 5 as id from dual 
        )

    select id from tab1 group by id having count(id)=1;

Output is Id=5 and count is 1

As 5 is non repeated.How do i implement it using JAVA 8 streams?

I tried below but obviously it is giving wrong result

List<Integer> myList = new ArrayList<Integer>();
                myList.add(1);
                myList.add(1);
                myList.add(2);
                myList.add(2);
                myList.add(5);

                Long f =  myList.stream()
                          .distinct().count();

                System.out.println(f);
like image 621
Oracle Mokey Avatar asked Aug 16 '18 14:08

Oracle Mokey


People also ask

How do I get unique values from a collection stream?

distinct() returns a stream consisting of distinct elements in a stream. distinct() is the method of Stream interface. This method uses hashCode() and equals() methods to get distinct elements. In case of ordered streams, the selection of distinct elements is stable.

How do you remove duplicates in Java 8?

You can use the Stream. distinct() method to remove duplicates from a Stream in Java 8 and beyond. The distinct() method behaves like a distinct clause of SQL, which eliminates duplicate rows from the result set.

How do I find duplicate values in Java 8?

In Java 8 Stream, filter with Set. Add() is the fastest algorithm to find duplicate elements, because it loops only one time. Set<T> items = new HashSet<>(); return list.


2 Answers

long result = myList.stream()
         .collect(Collectors.groupingBy(
                   Function.identity(),
                  Collectors.counting()))
         .entrySet()
         .stream()
         .filter(entry -> entry.getValue() == 1)
         .map(Entry::getKey)
         .count();

Well you collect all the elements to a Map<Integer, Long>, where the key is the value itself, and value is how many times it is repeated. Later we stream the entry set from that resulting map and filter only those entries that that have a count of 1 (meaning they are not repeated), later we map to Entry::getKey - to get that value from the List and count.

like image 109
Eugene Avatar answered Oct 06 '22 01:10

Eugene


An alternative is to filter repeated elements out of the list but it's not very efficient so I would only use it if the list is small:

List<Integer> result = myList.stream()
                             .filter(i -> Collections.frequency(myList, i) == 1)
                             .collect(toList());
like image 26
assylias Avatar answered Oct 05 '22 23:10

assylias