Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find only repeated String attributes in list with Java 8

I know below is the code to find out the occurrence of each String attributes in list , how can I filter this list with only duplicates item i.e having more than 1 occurrence. Sorry I am new to java 8 .

Map<String, Long> result = list.stream()
            .collect(Collectors.groupingBy(Function.identity(),
                                              Collectors.counting()));
like image 866
Rishabh Chaturvedi Avatar asked Dec 02 '18 19:12

Rishabh Chaturvedi


People also ask

How do I find duplicates in a string 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. stream() .

How do you find duplicates in a string list in Java?

Get the stream of elements in which the duplicates are to be found. For each element in the stream, count the frequency of each element, using Collections. frequency() method. Then for each element in the collection list, if the frequency of any element is more than one, then this element is a duplicate element.

How do I remove duplicates from a list in Java 8?

To remove the duplicates from the arraylist, we can use the java 8 stream api as well. Use steam's distinct() method which returns a stream consisting of the distinct elements comparing by object's equals() method. Collect all district elements as List using Collectors. toList() .

How do you count the number of occurrences of an element in a Java 8 map?

With Eclipse Collections (formerly GS Collections), you can make use of a data structure called Bag that can hold the number of occurrences of each element. Using IntBag , the following will work: MutableList<Person> personsEC = ListAdapter. adapt(persons); IntBag intBag = personsEC.

How to find most repeated character in string in Java?

Most repeated char and its value is retrieved from getKey () and getValue () from Pair instance. 3. Java - Find Most Repeated Character In String Using ASCII sized Array

How to find duplicate objects in list in Java?

Java Find duplicate objects in list using Stream Group by In Java Stream perform group by operation based on that we can find duplicate object from collection or list. java.util.List<String> list = Arrays.asList("A", "B", "B", "C", "D", "D", "Z", "E", "E");

How many repeated substrings are there in a string?

Second, there's at least one repetition of a substring. This is best illustrated with some examples by checking out a few repeated substrings: And a few non-repeated ones:

Which is the most repeated character for 3 times in HashMap?

Input string : hello world l is the most repeated character for 3 times. The above program compiles and run without any errors. But this is lengthy program using HashMap. Here, we have captured the most repeated character and its count in Pair object. Most repeated char and its value is retrieved from getKey () and getValue () from Pair instance.


4 Answers

A simpler way to find that out could be

List<String> recurringItems = list.stream()
        .filter(item -> list.lastIndexOf(item) != list.indexOf(item))
        .collect(Collectors.toList());

Since for items occurring more than once, lastIndex wouldn't be equal to the first index.


Alternatively, you can use Collectors.toSet() to ensure the items are listed only once in case you are not interested in their order of recurrence.

Set<String> recurringItemsOnce = list.stream()
        .filter(item -> list.lastIndexOf(item) != list.indexOf(item))
        .collect(Collectors.toSet());

Or using Collections.frequency as:

Set<String> recurringItems = list.stream()
        .filter(item -> Collections.frequency(list, item) >= 2)
        .collect(Collectors.toSet());
like image 177
Naman Avatar answered Oct 23 '22 18:10

Naman


create a stream from the entrySet and filter:

List<Map.Entry<String, Long>> result =  list.stream()
                   .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
                   .entrySet()
                   .stream()
                   .filter(s -> s.getValue() >= 2)
                   .collect(Collectors.toList());

or if you want to maintain a map then:

Map<String, Long> result = stringList().stream()
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
                .entrySet()
                .stream()
                .filter(s -> s.getValue() >= 2)
                .collect(toMap(Map.Entry::getKey, Map.Entry::getValue));

on another note, if you just want the individual numbers that have more than or equal to 2 occurrences then you can do:

List<String> result = list.stream()
                .collect(Collectors.groupingBy(Function.identity(),
                        Collectors.counting()))
                .entrySet()
                .stream()
                .filter(x -> x.getValue() >= 2)
                .map(Map.Entry::getKey)
                .collect(toList());

another option being:

List<String> result = 
         list.stream()
             .filter(x -> list.stream().filter(x::equals).limit(2).count() == 2)
             .distinct()
             .collect(toList());
like image 38
Ousmane D. Avatar answered Oct 23 '22 19:10

Ousmane D.


If your List is mutable, you can directly remove all elements except their second occurrence:

// example list
List<String> example = new ArrayList<>();
Collections.addAll(example, "foo", "bar", "baz", "bar", "bar", "baz");

// actual operation
Map<String,Integer> temp = new HashMap<>();
example.removeIf(s -> temp.merge(s, 1, Integer::sum)!=2);

// example output
example.forEach(System.out::println);// prints bar baz

The solution above keeps only one copy for each string having multiple occurrences while removing all strings having no duplicates. If you want to keep all duplicates and just remove those string not having duplicates, there is no way around determining the duplicate status first.

// same example input as above

// actual operation
Map<String,Boolean> temp = new HashMap<>();
example.forEach(s -> temp.merge(s, true, (a,b) -> false));
example.removeIf(temp::get);

// example output
example.forEach(System.out::println);// prints bar baz bar bar baz

Here, the temporary map can be created with a Stream operation with the same logic:

Map<String,Boolean> temp = example.stream()
    .collect(Collectors.toMap(Function.identity(), s -> true, (a,b) -> false));
example.removeIf(temp::get);
like image 32
Holger Avatar answered Oct 23 '22 17:10

Holger


The other way would be like this. after groupBy then remove entry with value=1;

result = list.stream()
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
result.values().removeIf(v->v.intValue() == 1);
like image 33
Hadi J Avatar answered Oct 23 '22 19:10

Hadi J