34

Is there any method for counting the occurrence of each item on an array?

Lets say I have:

String[] array = {"name1","name2","name3","name4", "name5"};

Here the output will be:

name1 1
name2 1
name3 1
name4 1
name5 1

and if I have:

String[] array = {"name1","name1","name2","name2", "name2"};

The output would be:

name1 2
name2 3

The output here is just to demonstrate the expected result.

Makoto
  • 100,191
  • 27
  • 181
  • 221
Favolas
  • 6,723
  • 28
  • 70
  • 117
  • Probably not, but it should be simple enough for you to implement a method on your own considering how easy the task is. It will perform in O(n) no matter what I reckon anyway (unless you make some assumptions about sorting to increase this speed) – gnomed Nov 11 '11 at 18:59

20 Answers20

50
List asList = Arrays.asList(array);
Set<String> mySet = new HashSet<String>(asList);

for(String s: mySet){
 System.out.println(s + " " + Collections.frequency(asList,s));
}
Damian
  • 2,812
  • 6
  • 36
  • 59
42

With , you can do it like this:

String[] array = {"name1","name2","name3","name4", "name5", "name2"};
Arrays.stream(array)
      .collect(Collectors.groupingBy(s -> s))
      .forEach((k, v) -> System.out.println(k+" "+v.size()));

Output:

name5 1
name4 1
name3 1
name2 2
name1 1

What it does is:

  • Create a Stream<String> from the original array
  • Group each element by identity, resulting in a Map<String, List<String>>
  • For each key value pair, print the key and the size of the list

If you want to get a Map that contains the number of occurences for each word, it can be done doing:

Map<String, Long> map = Arrays.stream(array)
    .collect(Collectors.groupingBy(s -> s, Collectors.counting()));

For more informations:

Hope it helps! :)

Community
  • 1
  • 1
Alexis C.
  • 87,500
  • 20
  • 164
  • 172
19

You could use a MultiSet from Google Collections/Guava or a Bag from Apache Commons.

If you have a collection instead of an array, you can use addAll() to add the entire contents to the above data structure, and then apply the count() method to each value. A SortedMultiSet or SortedBag would give you the items in a defined order.

Google Collections actually has very convenient ways of going from arrays to a SortedMultiset.

catch22
  • 1,384
  • 1
  • 16
  • 39
Uri
  • 86,748
  • 48
  • 217
  • 319
4

Using HashMap it is walk in the park.

main(){
    String[] array ={"a","ab","a","abc","abc","a","ab","ab","a"};
    Map<String,Integer> hm = new HashMap();

    for(String x:array){

        if(!hm.containsKey(x)){
            hm.put(x,1);
        }else{
            hm.put(x, hm.get(x)+1);
        }
    }
    System.out.println(hm);
}
Haboryme
  • 4,181
  • 1
  • 17
  • 21
Deva44
  • 73
  • 8
  • this works, but could explain little about hm.put(x, hm.get(x)+1); part ? thx – ikel Jul 21 '21 at 16:03
  • I meant how is hm.get(x) actually act like a counter not item value? – ikel Jul 21 '21 at 16:12
  • @ikel If key (x in this case) is already there in the hm, get the corresponding value, increment by one and store it back. – Deva44 Jul 22 '21 at 06:04
4

I wrote a solution for this to practice myself. It doesn't seem nearly as awesome as the other answers posted, but I'm going to post it anyway, and then learn how to do this using the other methods as well. Enjoy:

public static Integer[] countItems(String[] arr)
{
    List<Integer> itemCount = new ArrayList<Integer>();
    Integer counter = 0;
    String lastItem = arr[0];

    for(int i = 0; i < arr.length; i++)
    {
        if(arr[i].equals(lastItem))
        {
            counter++;
        }
        else
        {
            itemCount.add(counter);
            counter = 1;
        }
        lastItem = arr[i];
    }
    itemCount.add(counter);

    return itemCount.toArray(new Integer[itemCount.size()]);
}

public static void main(String[] args)
{
    String[] array = {"name1","name1","name2","name2", "name2", "name3",
            "name1","name1","name2","name2", "name2", "name3"};
    Arrays.sort(array);
    Integer[] cArr = countItems(array);
    int num = 0;
    for(int i = 0; i < cArr.length; i++)
    {
        num += cArr[i]-1;
        System.out.println(array[num] + ": " + cArr[i].toString());
    }
}
Nick Rolando
  • 25,657
  • 13
  • 77
  • 114
  • It won't work for array like this: String[] array = { "Gates", "Michael","Gates","Peterson","Bush","Johnson","Johnson","Gates"}; – Gopal00005 Sep 12 '17 at 07:19
3

It can be done in a very simple way using collections please find the code below

String[] array = {"name1","name1","name2","name2", "name2"};
List<String> sampleList=(List<String>) Arrays.asList(array);
for(String inpt:array){
int frequency=Collections.frequency(sampleList,inpt);
System.out.println(inpt+" "+frequency);
}

Here the output will be like name1 2 name1 2 name2 3 name2 3 name2 3

To avoid printing redundant keys use HashMap and get your desired output

naveenTekkem
  • 61
  • 1
  • 8
3

Count String occurence using hashmap, streams & collections

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class StringOccurence {

public static void main(String args[]) {

    String[] stringArray = { "name1", "name1", "name2", "name2", "name2" };
    countStringOccurence(stringArray);
    countStringOccurenceUsingStream(stringArray);
    countStringOccurenceUsingCollections(stringArray);
}

private static void countStringOccurenceUsingCollections(String[] stringArray) {
    // TODO Auto-generated method stub
    List<String> asList = Arrays.asList(stringArray);
    Set<String> set = new HashSet<String>(asList);
    for (String string : set) {
        System.out.println(string + "   -->   " + Collections.frequency(asList, string));
    }

}

private static void countStringOccurenceUsingStream(String[] stringArray) {
    // TODO Auto-generated method stub
    Arrays.stream(stringArray).collect(Collectors.groupingBy(s -> s))
            .forEach((k, v) -> System.out.println(k + "   -->   " + v.size()));
}

private static void countStringOccurence(String[] stringArray) {
    // TODO Auto-generated method stub
    Map<String, Integer> map = new HashMap<String, Integer>();
    for (String s : stringArray) {
        if (map.containsKey(s)) {
            map.put(s, map.get(s) + 1);
        } else {
            map.put(s, 1);
        }
    }

    for (Map.Entry<String, Integer> entry : map.entrySet()) {
        System.out.println(entry.getKey() + "   -->   " + entry.getValue());
    }

}

}

Balakrishnan
  • 271
  • 2
  • 7
3

I would use a hashtable with in key takes the element of the array (here string) and in value an Integer.

then go through the list doing something like this :

for(String s:array){
if(hash.containsKey(s)){
  Integer i = hash.get(s);
  i++;
}else{
  hash.put(s, new Interger(1));
}
Jason Rogers
  • 18,950
  • 26
  • 75
  • 111
  • 5
    This doesn't work, you'd have to use ```hash.put(s, hash.get(s) + 1);```. Doing ```i++;``` doesn't update the integer inside the hashtable. There's also other typos. – Jorn Vernee Apr 30 '16 at 17:58
1

Here is my solution - The method takes an array of integers(assuming the range between 0 to 100) as input and returns the number of occurrences of each element.

let's say the input is [21,34,43,21,21,21,45,65,65,76,76,76]. So the output would be in a map and it is: {34=1, 21=4, 65=2, 76=3, 43=1, 45=1}

public Map<Integer, Integer> countOccurrence(int[] numbersToProcess) {
    int[] possibleNumbers = new int[100];
    Map<Integer, Integer> result = new HashMap<Integer, Integer>();

    for (int i = 0; i < numbersToProcess.length; ++i) {
      possibleNumbers[numbersToProcess[i]] = possibleNumbers[numbersToProcess[i]] + 1;
      result.put(numbersToProcess[i], possibleNumbers[numbersToProcess[i]]);
    }

    return result;
}

Kinjal
  • 688
  • 2
  • 11
  • 21
1

There are several methods which can help, but this is one is using for loop.

import java.util.Arrays;

public class one_dimensional_for {

private static void count(int[] arr) {

    Arrays.sort(arr);

    int sum = 0, counter = 0;

    for (int i = 0; i < arr.length; i++) {
        if (arr[0] == arr[arr.length - 1]) {
            System.out.println(arr[0] + ": " + counter + " times");
            break;
        } else {
            if (i == (arr.length - 1)) {
                sum += arr[arr.length - 1];
                counter++;
                System.out.println((sum / counter) + " : " + counter
                        + " times");
                break;
            } else {
                if (arr[i] == arr[i + 1]) {
                    sum += arr[i];
                    counter++;
                } else if (arr[i] != arr[i + 1]) {
                    sum += arr[i];
                    counter++;
                    System.out.println((sum / counter) + " : " + counter
                            + " times");
                    sum = 0;
                    counter = 0;
                }
            }
        }
    }
}

public static void main(String[] args) {
    int nums[] = { 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5, 5, 5, 5, 6 };
    count(nums);
}

}
Konrad Borowski
  • 10,745
  • 3
  • 55
  • 71
Ertuğrul Çetin
  • 5,101
  • 4
  • 33
  • 67
1

You can do it by using Arrays.sort and Recursion. The same wine but in a different bottle....

import java.util.Arrays;

public class ArrayTest {
public static int mainCount=0;

public static void main(String[] args) {
    String prevItem = "";
    String[] array = {"name1","name1","name2","name2", "name2"};
    Arrays.sort(array);

    for(String item:array){
        if(! prevItem.equals(item)){
            mainCount = 0;
            countArray(array, 0, item);
            prevItem = item;
        }
    }
}

private static void countArray(String[] arr, int currentPos, String item) {
    if(currentPos == arr.length){
        System.out.println(item + " " +  mainCount);
        return;
    }
    else{
        if(arr[currentPos].toString().equals(item)){
            mainCount += 1;
        }
        countArray(arr, currentPos+1, item);
    }
  }
}
Avijit
  • 11
  • 2
0

This is a simple script I used in Python but it can be easily adapted. Nothing fancy though.

def occurance(arr):
  results = []
  for n in arr:
      data = {}
      data["point"] = n
      data["count"] = 0
      for i in range(0, len(arr)):
          if n == arr[i]:
              data["count"] += 1
      results.append(data)
  return results
willredington315
  • 199
  • 1
  • 13
0

you can find using HashMap with simple technic

public class HashMapExample {
    public static void main(String[] args) {
        stringArray();          
    }
public static void stringArray()
{
    String[] a = {"name1","name2","name3","name4", "name5"};

    Map<String, String> hm = new HashMap<String, String>();
    for(int i=0;i<a.length;i++)
    {
    String bl=(String)hm.get(a[i]);
    if(bl==null)
    {
        hm.put(a[i],String.valueOf(1));
    }else
    {
        String k=hm.get(a[i]);
        int j=Integer.valueOf(k);
        hm.put(a[i],String.valueOf(j+1));
    }

    }
    //hm.entrySet();
    System.out.println("map elements are "+hm.toString());
}

}
VISHWANATH N P
  • 284
  • 1
  • 7
  • 11
0

// An Answer w/o using Hashset or map or Arraylist

public class Count {
    static String names[] = {"name1","name1","name2","name2", "name2"};
    public static void main(String args[]) {

        printCount(names);

    }

    public static void printCount(String[] names){

        java.util.Arrays.sort(names);
        int n = names.length, c;
        for(int i=0;i<n;i++){
            System.out.print(names[i]+" ");
        }
        System.out.println();
        int result[] = new int[n];
        for(int i=0;i<n;i++){
            result[i] = 0;
        }

        for(int i =0;i<n;i++){
            if (i != n-1){
                for(int j=0;j<n;j++){
                    if(names[i] == names[j] )
                        result[i]++;
                }
            }
            else if (names[n-2] == names[n-1]){
            result[i] = result[i-1];
         }

         else result[i] = 1;
        }
        int max = 0,index = 0;
        for(int i=0;i<n;i++){
         System.out.print(result[i]+"     ");
            if (result[i] >= max){
                max = result[i];
                index = i;
            }

        }
    }
}
NIKET RAJ
  • 1
  • 1
0
public class Main
{
    public static void main(String[] args) {
        
        String[] a ={"name1","name1","name2","name2", "name2"};
        for (int i=0;i<a.length ;i++ )
        {
            int count =0;
            int count1=0;
            for(int j=0;j<a.length;j++)
            {
                if(a[i]==a[j])
                {
                    count++;
                    
                }
            }
            for(int j=i-1;j>=0 ;j--)
            {
                if(a[i]==a[j])
                {
                    count1++;
                }
            }
            if(count1 ==0)
            {
                System.out.println(a[i]+" occurs :"+count);
            }
        }
    }
}
Tomerikoo
  • 15,737
  • 15
  • 35
  • 52
N R
  • 1
0

You could use

for (String x : array){
   System.out.println(Collections.frequency(array,x));
}
Malinda
  • 326
  • 2
  • 12
0
import java.util.HashMap;
import java.util.Map;

public class FrequencyUsingMap {

    public static void main(String[] args) {
        int a[] = {1,1,1,1,2,2,3,4,1};
        int num = 0;
        int maxfreq = 0;
        int maxnum =0;
        Map<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i<a.length; i++){
            num = a[i];
        
            if(map.containsKey(num)){
                int frq = map.get(num);
                frq++;
                map.put(num, frq);
                if(frq>maxfreq){
                    maxfreq = frq;
                    maxnum = num;
                }
            }else{
                map.put(num, 1);
            }
        }
        System.out.println(map);
        System.out.println("number "+ maxnum + " having max frequency " +maxfreq);
    }
}
masud_moni
  • 1,085
  • 17
  • 32
  • Please try to add some description as well with your comment to make it more understandable. Do not only post codes as answers. – masud_moni Feb 28 '22 at 13:33
0

You can use Hash Map as given in the example below:

import java.util.HashMap;
import java.util.Set;

/**
 * 
 * @author Abdul Rab Khan
 * 
 */
public class CounterExample {
    public static void main(String[] args) {
        String[] array = { "name1", "name1", "name2", "name2", "name2" };
        countStringOccurences(array);
    }

    /**
     * This method process the string array to find the number of occurrences of
     * each string element
     * 
     * @param strArray
     *            array containing string elements
     */
    private static void countStringOccurences(String[] strArray) {
        HashMap<String, Integer> countMap = new HashMap<String, Integer>();
        for (String string : strArray) {
            if (!countMap.containsKey(string)) {
                countMap.put(string, 1);
            } else {
                Integer count = countMap.get(string);
                count = count + 1;
                countMap.put(string, count);
            }
        }
        printCount(countMap);
    }

    /**
     * This method will print the occurrence of each element
     * 
     * @param countMap
     *            map containg string as a key, and its count as the value
     */
    private static void printCount(HashMap<String, Integer> countMap) {
        Set<String> keySet = countMap.keySet();
        for (String string : keySet) {
            System.out.println(string + " : " + countMap.get(string));
        }
    }
}
Nick Rolando
  • 25,657
  • 13
  • 77
  • 114
-1

You can use HashMap, where Key is your string and value - count.

coms
  • 449
  • 15
  • 38
-2
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

public class MultiString {

    public HashMap<String, Integer> countIntem( String[] array ) {

        Arrays.sort(array);
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        Integer count = 0;
        String first = array[0];
        for( int counter = 0; counter < array.length; counter++ ) {
            if(first.hashCode() == array[counter].hashCode()) {
                count = count + 1;
            } else {
                map.put(first, count);
                count = 1;
            }
            first = array[counter];
            map.put(first, count);
        }

        return map;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String[] array = { "name1", "name1", "name2", "name2", "name2",
                "name3", "name1", "name1", "name2", "name2", "name2", "name3" };

        HashMap<String, Integer> countMap = new MultiString().countIntem(array);
        System.out.println(countMap);
    }
}



Gives you O(n) complexity.
sandipkbhaumik
  • 187
  • 1
  • 11