How to find duplicate rows and display the number of repetitions in front of them

Viewed 206

Yes, a trivial question, but I did not find a duplicate. At the moment, from this collection (ArrayList):

Java
C#
Java
Python

I must get this: (That is, over each word will be the number of duplicates encountered)

Java 2
C# 1
Java 2
Python 1

At the moment I'm using Map, but it removes duplicates and that's what I get.

Java 2
C# 1
Python 1

Here is my code:

      Map<String, Integer> map = new HashMap<>();
        for (String temp : array) {
            Integer count = map.get(temp);
            if (count != null){
                map.put(temp, count + 1);
            }
            else {
                map.put(temp, 1);
            }
        }

I had an idea to write data to another list, to go through this list comparing each element of the "parent" list with all the elements of the new list. Something like that:

List<String> resultList = new ArrayList<>();
List<String> mainList = new ArrayList<>();

    for (int i = 0; i < arrayList.size(); i++) {
        mainList.add(i,arrayList.get(i));
    }

    for (int i = 0; i < mainList.size(); i++) {
            int x = 1;
        for (String anArray : arrayList) {
            if (mainList.get(i).equals(anArray)) {
                resultList.add(i,mainList.get(i) + " "+ x++);
            }
        }
    }
    resultList.forEach(System.out::println);

Which works as I need, but also creates an additional line when it encounters a duplicate.

Java 2
C# 1
Java 2
Python 1
Java 1
Java 1

In the implementation with List, I have a problem in that it increases the current element by 1, but also creates another one at the same time.

Guys, I'll be happy with any idea or clue that will guide me to solving my problem!

UPD: All answers to this question are divine. Thank you guys! I feel awkward trying to choose the right answer without offending others.

6 Answers
public static void main(String[] args) {

    List<String> list = Arrays.asList("Java", "C#", "Java", "Python");

    list.forEach( s -> System.out.println(s + " " + list.stream().filter( s::equals ).count()));

}

You can use Collections.frequency while iterating the list to print the number of occurrences of each word in the list:

public static void main(String[] args) {
    List<String> list = Arrays.asList("Java", "C#", "Java", "Python");
    list.forEach( s -> System.out.println(s + " " + Collections.frequency(list, s)));
}

Output:

Java 2
C# 1
Java 2
Python 1

I would do it in this way. First you collet to a Map<String, Long> the occurrences of each of the items in your list. After that you just iterate through your original list, print the item along with it's count from your obtained map.

Here's an example:

List<String> list  = new ArrayList<>();
list.add("Java");
list.add("CORE");
list.add("Java");
list.add("Java");


Map<String, Long> stringLongMap = list.stream() // collectors (java 8)
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));



for(String item: list) { // I just printed the result, you can do whatever you want
    System.out.println(item + " " + stringLongMap.get(item));
}
List<String> arrayList = Arrays.asList("JAVA", "C", "JAVA", "PYTHON");

Map<String, Integer> map = new HashMap<>();
for (String s : arrayList) {
    // computeIfAbsent checks if the key already exists in the map:
    //  -- if it exists, it just returns the value for that key.
    //     else the second param (Function) is applied to get the value.
    Integer count = map.computeIfAbsent(s, key -> 0); // If key is absent, 0 will be set as value for this key. If present, value associated with this key is returned.
    map.put(s, count + 1); // increment and set.
}

for (String s : arrayList){
    System.out.println(s +" -> " + map.get(s));

}

You can perform a second iteration and lookup the count associated with each entry.

The following creates a pair linking original keys to their respective count:

List<String> list = Arrays.asList("Java", "C#", "Java", "Python");

Map<String, Long> counts = list.stream()
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

//You could replace `Pair` with any other suitable type, 
//such as java.util.AbstractMap.SimpleEntry<String, Long>

List<Pair<String, Long>> pairs = list.stream().map(str -> Pair.of(str, counts.get(str)))
        .collect(Collectors.toList());

The result (pairs) is [(Java,2), (C#,1), (Java,2), (Python,1)]

You can just iterate through the "array" again and query the hash map for the frequency.

Map<String, Integer> map = new HashMap<>();
    for (String temp : array) {
        Integer count = map.get(temp);
        if (count != null){
            map.put(temp, count + 1);
        }
        else {
            map.put(temp, 1);
        }
    }
array.foreach(item -> System.out.println(item + " -> " + map.get(item))
Related