Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Counting the number of occurrences of each item in a list

I have a streaming input which has repeated values. I can use any data structure but I have to count the number of occurence of each element. Suppose I have a list of mobile phone suppliers like the following:

Apple
Nokia
Samsung
Apple
LG
Nokia
HTC
Android
Apple
Nokia
Nokia
Apple
Samsung

I have to build any data structure preferably a map with details like

Apple,4
Nokia,4
Samsung,2
LG,1
Android,1

I am not sure whether this is optimal. Is there a better solution than this?
In fact I have yet to write the above as a code. So better code will also help.

like image 276
Harish Avatar asked Jun 29 '09 16:06

Harish


2 Answers

Yes, I would use a Map<String, Integer>. I would wrap the add in something like this:

private static void incrementValue(Map<String, Integer> counters, String toAdd) {
    Integer currValue = counters.get(toAdd);
    if (currValue == null)
        counters.put(toAdd, 1);
    else
        counters.put(toAdd, currValue+1);
}

Or without generics:

private static void incrementValue(Map counters, String toAdd) {
    Integer currValue = (Integer) counters.get(toAdd);
    if (currValue == null)
        counters.put(toAdd, 1);
    else
        counters.put(toAdd, currValue+1);
}
like image 146
Michael Myers Avatar answered Oct 06 '22 21:10

Michael Myers


Since it was mentioned by the questioner that generics could not be used, as the target platform was Java 1.4, one could use the Apache Commons Collections which doesn't use generics.

The answer by pjp mentions that a Bag can be used.

It turns out, the Apache Commons Collections has a Bag which has a getCount method which will return the count of a certain object that was added to the Bag.

The following is an example that adds some Integer objects to a HashBag, and counts how many of each Integer object that the Bag contains:

Bag b = new HashBag();

b.add(Integer.valueOf(1));
b.add(Integer.valueOf(2));
b.add(Integer.valueOf(2));
b.add(Integer.valueOf(3));

System.out.println("Count for 1: " + b.getCount(Integer.valueOf(1)));
System.out.println("Count for 2: " + b.getCount(Integer.valueOf(2)));
System.out.println("Count for 3: " + b.getCount(Integer.valueOf(3)));

The results were:

Count for 1: 1
Count for 2: 2
Count for 3: 1

(I should add a disclaimer that this code was actually compiled and run on Java 6, but I believe I've only used features which were present from the pre-Java 5 days.)

like image 42
coobird Avatar answered Oct 06 '22 21:10

coobird