[java] How to count the number of occurrences of an element in a List

I have an ArrayList, a Collection class of Java, as follows:

ArrayList<String> animals = new ArrayList<String>();
animals.add("bat");
animals.add("owl");
animals.add("bat");
animals.add("bat");

As you can see, the animals ArrayList consists of 3 bat elements and one owl element. I was wondering if there is any API in the Collection framework that returns the number of bat occurrences or if there is another way to determine the number of occurrences.

I found that Google's Collection Multiset does have an API that returns the total number of occurrences of an element. But that is compatible only with JDK 1.5. Our product is currently in JDK 1.6, so I cannot use it.

This question is related to java arraylist collections

The answer is


I wonder, why you can't use that Google's Collection API with JDK 1.6. Does it say so? I think you can, there should not be any compatibility issues, as it is built for a lower version. The case would have been different if that were built for 1.6 and you are running 1.5.

Am I wrong somewhere?


List<String> list = Arrays.asList("as", "asda", "asd", "urff", "dfkjds", "hfad", "asd", "qadasd", "as", "asda",
        "asd", "urff", "dfkjds", "hfad", "asd", "qadasd" + "as", "asda", "asd", "urff", "dfkjds", "hfad", "asd",
        "qadasd", "as", "asda", "asd", "urff", "dfkjds", "hfad", "asd", "qadasd");

Method 1:

Set<String> set = new LinkedHashSet<>();
set.addAll(list);

for (String s : set) {

    System.out.println(s + " : " + Collections.frequency(list, s));
}

Method 2:

int count = 1;
Map<String, Integer> map = new HashMap<>();
Set<String> set1 = new LinkedHashSet<>();
for (String s : list) {
    if (!set1.add(s)) {
        count = map.get(s) + 1;
    }
    map.put(s, count);
    count = 1;

}
System.out.println(map);

This shows, why it is important to "Refer to objects by their interfaces" as described in Effective Java book.

If you code to the implementation and use ArrayList in let's say, 50 places in your code, when you find a good "List" implementation that count the items, you will have to change all those 50 places, and probably you'll have to break your code ( if it is only used by you there is not a big deal, but if it is used by someone else uses, you'll break their code too)

By programming to the interface you can let those 50 places unchanged and replace the implementation from ArrayList to "CountItemsList" (for instance ) or some other class.

Below is a very basic sample on how this could be written. This is only a sample, a production ready List would be much more complicated.

import java.util.*;

public class CountItemsList<E> extends ArrayList<E> { 

    // This is private. It is not visible from outside.
    private Map<E,Integer> count = new HashMap<E,Integer>();

    // There are several entry points to this class
    // this is just to show one of them.
    public boolean add( E element  ) { 
        if( !count.containsKey( element ) ){
            count.put( element, 1 );
        } else { 
            count.put( element, count.get( element ) + 1 );
        }
        return super.add( element );
    }

    // This method belongs to CountItemList interface ( or class ) 
    // to used you have to cast.
    public int getCount( E element ) { 
        if( ! count.containsKey( element ) ) {
            return 0;
        }
        return count.get( element );
    }

    public static void main( String [] args ) { 
        List<String> animals = new CountItemsList<String>();
        animals.add("bat");
        animals.add("owl");
        animals.add("bat");
        animals.add("bat");

        System.out.println( (( CountItemsList<String> )animals).getCount( "bat" ));
    }
}

OO principles applied here: inheritance, polymorphism, abstraction, encapsulation.


Java 8 - another method

String searched = "bat";
long n = IntStream.range(0, animals.size())
            .filter(i -> searched.equals(animals.get(i)))
            .count();

Put the elements of the arraylist in the hashMap to count the frequency.


Java 8 - another method

String searched = "bat";
long n = IntStream.range(0, animals.size())
            .filter(i -> searched.equals(animals.get(i)))
            .count();

What you want is a Bag - which is like a set but also counts the number of occurances. Unfortunately the java Collections framework - great as they are dont have a Bag impl. For that one must use the Apache Common Collection link text


I'm pretty sure the static frequency-method in Collections would come in handy here:

int occurrences = Collections.frequency(animals, "bat");

That's how I'd do it anyway. I'm pretty sure this is jdk 1.6 straight up.


Put the elements of the arraylist in the hashMap to count the frequency.


Alternative Java 8 solution using Streams:

long count = animals.stream().filter(animal -> "bat".equals(animal)).count();

There is no native method in Java to do that for you. However, you can use IterableUtils#countMatches() from Apache Commons-Collections to do it for you.


A slightly more efficient approach might be

Map<String, AtomicInteger> instances = new HashMap<String, AtomicInteger>();

void add(String name) {
     AtomicInteger value = instances.get(name);
     if (value == null) 
        instances.put(name, new AtomicInteger(1));
     else
        value.incrementAndGet();
}

I didn't want to make this case more difficult and made it with two iterators I have a HashMap with LastName -> FirstName. And my method should delete items with dulicate FirstName.

public static void removeTheFirstNameDuplicates(HashMap<String, String> map)
{

    Iterator<Map.Entry<String, String>> iter = map.entrySet().iterator();
    Iterator<Map.Entry<String, String>> iter2 = map.entrySet().iterator();
    while(iter.hasNext())
    {
        Map.Entry<String, String> pair = iter.next();
        String name = pair.getValue();
        int i = 0;

        while(iter2.hasNext())
        {

            Map.Entry<String, String> nextPair = iter2.next();
            if (nextPair.getValue().equals(name))
                i++;
        }

        if (i > 1)
            iter.remove();

    }

}

If you are a user of my ForEach DSL, it can be done with a Count query.

Count<String> query = Count.from(list);
for (Count<Foo> each: query) each.yield = "bat".equals(each.element);
int number = query.result();

Simple Way to find the occurrence of string value in an array using Java 8 features.

public void checkDuplicateOccurance() {
        List<String> duplicateList = new ArrayList<String>();
        duplicateList.add("Cat");
        duplicateList.add("Dog");
        duplicateList.add("Cat");
        duplicateList.add("cow");
        duplicateList.add("Cow");
        duplicateList.add("Goat");          
        Map<String, Long> couterMap = duplicateList.stream().collect(Collectors.groupingBy(e -> e.toString(),Collectors.counting()));
        System.out.println(couterMap);
    }

Output : {Cat=2, Goat=1, Cow=1, cow=1, Dog=1}

You can notice "Cow" and cow are not considered as same string, in case you required it under same count, use .toLowerCase(). Please find the snippet below for the same.

Map<String, Long> couterMap = duplicateList.stream().collect(Collectors.groupingBy(e -> e.toString().toLowerCase(),Collectors.counting()));

Output : {cat=2, cow=2, goat=1, dog=1}


I'm pretty sure the static frequency-method in Collections would come in handy here:

int occurrences = Collections.frequency(animals, "bat");

That's how I'd do it anyway. I'm pretty sure this is jdk 1.6 straight up.


What you want is a Bag - which is like a set but also counts the number of occurances. Unfortunately the java Collections framework - great as they are dont have a Bag impl. For that one must use the Apache Common Collection link text


Alternative Java 8 solution using Streams:

long count = animals.stream().filter(animal -> "bat".equals(animal)).count();

What you want is a Bag - which is like a set but also counts the number of occurances. Unfortunately the java Collections framework - great as they are dont have a Bag impl. For that one must use the Apache Common Collection link text


To achieve that one can do it in several ways, namely:

Methods that return the number of occurrence of a single element:

Collection Frequency

Collections.frequency(animals, "bat");

Java Stream:

Filter

animals.stream().filter("bat"::equals).count();

Just iteration thought the list

public static long manually(Collection<?> c, Object o){
    int count = 0;
    for(Object e : c)
        if(e.equals(o))
            count++;
    return count;
}

Methods that create a map of frequencies:

Collectors.groupingBy

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

merge

Map<String, Long> map = new HashMap<>();
c.forEach(e -> map.merge(e, 1L, Long::sum));

Manually

Map<String, Integer> mp = new HashMap<>();
        animals.forEach(animal -> mp.compute(animal, (k, v) -> (v == null) ? 1 : v + 1));

A running example with all the methods:

public class Frequency {

    public static int frequency(Collection<?> c, Object o){
        return Collections.frequency(c, o);
    }

    public static long filter(Collection<?> c, Object o){
        return c.stream().filter(o::equals).count();
    }

    public static long manually(Collection<?> c, Object o){
        int count = 0;
        for(Object e : c)
            if(e.equals(o))
                count++;
        return count;
    }

    public static Map<?, Long> mapGroupBy(Collection<?> c){
        return c.stream()
                .collect(Collectors.groupingBy(Function.identity() , Collectors.counting()));
    }

    public static Map<Object, Long> mapMerge(Collection<?> c){
         Map<Object, Long> map = new HashMap<>();
         c.forEach(e -> map.merge(e, 1L, Long::sum));
         return map;
    }

    public static Map<Object, Long> manualMap(Collection<?> c){
        Map<Object, Long> map = new HashMap<>();
        c.forEach(e -> map.compute(e, (k, v) -> (v == null) ? 1 : v + 1));
        return map;
    }


    public static void main(String[] args){
        List<String> animals = new ArrayList<>();
        animals.add("bat");
        animals.add("owl");
        animals.add("bat");
        animals.add("bat");

        System.out.println(frequency(animals, "bat"));
        System.out.println(filter(animals,"bat"));
        System.out.println(manually(animals,"bat"));
        mapGroupBy(animals).forEach((k, v) -> System.out.println(k + " -> "+v));
        mapMerge(animals).forEach((k, v) -> System.out.println(k + " -> "+v));
        manualMap(animals).forEach((k, v) -> System.out.println(k + " -> "+v));
    }
}

The methods name should have reflected what those methods are doing, however, I used the name to reflect the approach being used instead (given that in the current context it is okey).


Sorry there's no simple method call that can do it. All you'd need to do though is create a map and count frequency with it.

HashMap<String,int> frequencymap = new HashMap<String,int>();
foreach(String a in animals) {
  if(frequencymap.containsKey(a)) {
    frequencymap.put(a, frequencymap.get(a)+1);
  }
  else{ frequencymap.put(a, 1); }
}

If you are a user of my ForEach DSL, it can be done with a Count query.

Count<String> query = Count.from(list);
for (Count<Foo> each: query) each.yield = "bat".equals(each.element);
int number = query.result();

A slightly more efficient approach might be

Map<String, AtomicInteger> instances = new HashMap<String, AtomicInteger>();

void add(String name) {
     AtomicInteger value = instances.get(name);
     if (value == null) 
        instances.put(name, new AtomicInteger(1));
     else
        value.incrementAndGet();
}

Map<String,Integer> hm = new HashMap<String, Integer>();
for(String i : animals) {
    Integer j = hm.get(i);
    hm.put(i,(j==null ? 1 : j+1));
}
for(Map.Entry<String, Integer> val : hm.entrySet()) {
    System.out.println(val.getKey()+" occurs : "+val.getValue()+" times");
}

You can use groupingBy feature of Java 8 for your use case.

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Test {
    public static void main(String[] args) {
        List<String> animals = new ArrayList<>();

        animals.add("bat");
        animals.add("owl");
        animals.add("bat");
        animals.add("bat");

        Map<String,Long> occurrenceMap =
                animals.stream().collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));
        System.out.println("occurrenceMap:: " + occurrenceMap);
    }
}

Output

occurrenceMap:: {bat=3, owl=1}


There is no native method in Java to do that for you. However, you can use IterableUtils#countMatches() from Apache Commons-Collections to do it for you.


So do it the old fashioned way and roll your own:

Map<String, Integer> instances = new HashMap<String, Integer>();

void add(String name) {
     Integer value = instances.get(name);
     if (value == null) {
        value = new Integer(0);
        instances.put(name, value);
     }
     instances.put(name, value++);
}

Sorry there's no simple method call that can do it. All you'd need to do though is create a map and count frequency with it.

HashMap<String,int> frequencymap = new HashMap<String,int>();
foreach(String a in animals) {
  if(frequencymap.containsKey(a)) {
    frequencymap.put(a, frequencymap.get(a)+1);
  }
  else{ frequencymap.put(a, 1); }
}

Simple Way to find the occurrence of string value in an array using Java 8 features.

public void checkDuplicateOccurance() {
        List<String> duplicateList = new ArrayList<String>();
        duplicateList.add("Cat");
        duplicateList.add("Dog");
        duplicateList.add("Cat");
        duplicateList.add("cow");
        duplicateList.add("Cow");
        duplicateList.add("Goat");          
        Map<String, Long> couterMap = duplicateList.stream().collect(Collectors.groupingBy(e -> e.toString(),Collectors.counting()));
        System.out.println(couterMap);
    }

Output : {Cat=2, Goat=1, Cow=1, cow=1, Dog=1}

You can notice "Cow" and cow are not considered as same string, in case you required it under same count, use .toLowerCase(). Please find the snippet below for the same.

Map<String, Long> couterMap = duplicateList.stream().collect(Collectors.groupingBy(e -> e.toString().toLowerCase(),Collectors.counting()));

Output : {cat=2, cow=2, goat=1, dog=1}


I didn't want to make this case more difficult and made it with two iterators I have a HashMap with LastName -> FirstName. And my method should delete items with dulicate FirstName.

public static void removeTheFirstNameDuplicates(HashMap<String, String> map)
{

    Iterator<Map.Entry<String, String>> iter = map.entrySet().iterator();
    Iterator<Map.Entry<String, String>> iter2 = map.entrySet().iterator();
    while(iter.hasNext())
    {
        Map.Entry<String, String> pair = iter.next();
        String name = pair.getValue();
        int i = 0;

        while(iter2.hasNext())
        {

            Map.Entry<String, String> nextPair = iter2.next();
            if (nextPair.getValue().equals(name))
                i++;
        }

        if (i > 1)
            iter.remove();

    }

}

To get the occurrences of the object from the list directly:

int noOfOccurs = Collections.frequency(animals, "bat");

To get the occurrence of the Object collection inside list, override the equals method in the Object class as:

@Override
public boolean equals(Object o){
    Animals e;
    if(!(o instanceof Animals)){
        return false;
    }else{
        e=(Animals)o;
        if(this.type==e.type()){
            return true;
        }
    }
    return false;
}

Animals(int type){
    this.type = type;
}

Call the Collections.frequency as:

int noOfOccurs = Collections.frequency(animals, new Animals(1));

Sorry there's no simple method call that can do it. All you'd need to do though is create a map and count frequency with it.

HashMap<String,int> frequencymap = new HashMap<String,int>();
foreach(String a in animals) {
  if(frequencymap.containsKey(a)) {
    frequencymap.put(a, frequencymap.get(a)+1);
  }
  else{ frequencymap.put(a, 1); }
}

?If you use Eclipse Collections, you can use a Bag. A MutableBag can be returned from any implementation of RichIterable by calling toBag().

MutableList<String> animals = Lists.mutable.with("bat", "owl", "bat", "bat");
MutableBag<String> bag = animals.toBag();
Assert.assertEquals(3, bag.occurrencesOf("bat"));
Assert.assertEquals(1, bag.occurrencesOf("owl"));

The HashBag implementation in Eclipse Collections is backed by a MutableObjectIntMap.

Note: I am a committer for Eclipse Collections.


This shows, why it is important to "Refer to objects by their interfaces" as described in Effective Java book.

If you code to the implementation and use ArrayList in let's say, 50 places in your code, when you find a good "List" implementation that count the items, you will have to change all those 50 places, and probably you'll have to break your code ( if it is only used by you there is not a big deal, but if it is used by someone else uses, you'll break their code too)

By programming to the interface you can let those 50 places unchanged and replace the implementation from ArrayList to "CountItemsList" (for instance ) or some other class.

Below is a very basic sample on how this could be written. This is only a sample, a production ready List would be much more complicated.

import java.util.*;

public class CountItemsList<E> extends ArrayList<E> { 

    // This is private. It is not visible from outside.
    private Map<E,Integer> count = new HashMap<E,Integer>();

    // There are several entry points to this class
    // this is just to show one of them.
    public boolean add( E element  ) { 
        if( !count.containsKey( element ) ){
            count.put( element, 1 );
        } else { 
            count.put( element, count.get( element ) + 1 );
        }
        return super.add( element );
    }

    // This method belongs to CountItemList interface ( or class ) 
    // to used you have to cast.
    public int getCount( E element ) { 
        if( ! count.containsKey( element ) ) {
            return 0;
        }
        return count.get( element );
    }

    public static void main( String [] args ) { 
        List<String> animals = new CountItemsList<String>();
        animals.add("bat");
        animals.add("owl");
        animals.add("bat");
        animals.add("bat");

        System.out.println( (( CountItemsList<String> )animals).getCount( "bat" ));
    }
}

OO principles applied here: inheritance, polymorphism, abstraction, encapsulation.


So do it the old fashioned way and roll your own:

Map<String, Integer> instances = new HashMap<String, Integer>();

void add(String name) {
     Integer value = instances.get(name);
     if (value == null) {
        value = new Integer(0);
        instances.put(name, value);
     }
     instances.put(name, value++);
}

package traversal;

import java.util.ArrayList;
import java.util.List;

public class Occurrance {
    static int count;

    public static void main(String[] args) {
        List<String> ls = new ArrayList<String>();
        ls.add("aa");
        ls.add("aa");
        ls.add("bb");
        ls.add("cc");
        ls.add("dd");
        ls.add("ee");
        ls.add("ee");
        ls.add("aa");
        ls.add("aa");

        for (int i = 0; i < ls.size(); i++) {
            if (ls.get(i) == "aa") {
                count = count + 1;
            }
        }
        System.out.println(count);
    }
}

Output: 4


There is no native method in Java to do that for you. However, you can use IterableUtils#countMatches() from Apache Commons-Collections to do it for you.


Sorry there's no simple method call that can do it. All you'd need to do though is create a map and count frequency with it.

HashMap<String,int> frequencymap = new HashMap<String,int>();
foreach(String a in animals) {
  if(frequencymap.containsKey(a)) {
    frequencymap.put(a, frequencymap.get(a)+1);
  }
  else{ frequencymap.put(a, 1); }
}

List<String> list = Arrays.asList("as", "asda", "asd", "urff", "dfkjds", "hfad", "asd", "qadasd", "as", "asda",
        "asd", "urff", "dfkjds", "hfad", "asd", "qadasd" + "as", "asda", "asd", "urff", "dfkjds", "hfad", "asd",
        "qadasd", "as", "asda", "asd", "urff", "dfkjds", "hfad", "asd", "qadasd");

Method 1:

Set<String> set = new LinkedHashSet<>();
set.addAll(list);

for (String s : set) {

    System.out.println(s + " : " + Collections.frequency(list, s));
}

Method 2:

int count = 1;
Map<String, Integer> map = new HashMap<>();
Set<String> set1 = new LinkedHashSet<>();
for (String s : list) {
    if (!set1.add(s)) {
        count = map.get(s) + 1;
    }
    map.put(s, count);
    count = 1;

}
System.out.println(map);

A slightly more efficient approach might be

Map<String, AtomicInteger> instances = new HashMap<String, AtomicInteger>();

void add(String name) {
     AtomicInteger value = instances.get(name);
     if (value == null) 
        instances.put(name, new AtomicInteger(1));
     else
        value.incrementAndGet();
}

So do it the old fashioned way and roll your own:

Map<String, Integer> instances = new HashMap<String, Integer>();

void add(String name) {
     Integer value = instances.get(name);
     if (value == null) {
        value = new Integer(0);
        instances.put(name, value);
     }
     instances.put(name, value++);
}

You can use groupingBy feature of Java 8 for your use case.

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Test {
    public static void main(String[] args) {
        List<String> animals = new ArrayList<>();

        animals.add("bat");
        animals.add("owl");
        animals.add("bat");
        animals.add("bat");

        Map<String,Long> occurrenceMap =
                animals.stream().collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));
        System.out.println("occurrenceMap:: " + occurrenceMap);
    }
}

Output

occurrenceMap:: {bat=3, owl=1}


Actually, Collections class has a static method called : frequency(Collection c, Object o) which returns the number of occurrences of the element you are searching for, by the way, this will work perfectly for you:

ArrayList<String> animals = new ArrayList<String>();
animals.add("bat");
animals.add("owl");
animals.add("bat");
animals.add("bat");
System.out.println("Freq of bat: "+Collections.frequency(animals, "bat"));

Put the elements of the arraylist in the hashMap to count the frequency.


This shows, why it is important to "Refer to objects by their interfaces" as described in Effective Java book.

If you code to the implementation and use ArrayList in let's say, 50 places in your code, when you find a good "List" implementation that count the items, you will have to change all those 50 places, and probably you'll have to break your code ( if it is only used by you there is not a big deal, but if it is used by someone else uses, you'll break their code too)

By programming to the interface you can let those 50 places unchanged and replace the implementation from ArrayList to "CountItemsList" (for instance ) or some other class.

Below is a very basic sample on how this could be written. This is only a sample, a production ready List would be much more complicated.

import java.util.*;

public class CountItemsList<E> extends ArrayList<E> { 

    // This is private. It is not visible from outside.
    private Map<E,Integer> count = new HashMap<E,Integer>();

    // There are several entry points to this class
    // this is just to show one of them.
    public boolean add( E element  ) { 
        if( !count.containsKey( element ) ){
            count.put( element, 1 );
        } else { 
            count.put( element, count.get( element ) + 1 );
        }
        return super.add( element );
    }

    // This method belongs to CountItemList interface ( or class ) 
    // to used you have to cast.
    public int getCount( E element ) { 
        if( ! count.containsKey( element ) ) {
            return 0;
        }
        return count.get( element );
    }

    public static void main( String [] args ) { 
        List<String> animals = new CountItemsList<String>();
        animals.add("bat");
        animals.add("owl");
        animals.add("bat");
        animals.add("bat");

        System.out.println( (( CountItemsList<String> )animals).getCount( "bat" ));
    }
}

OO principles applied here: inheritance, polymorphism, abstraction, encapsulation.


So do it the old fashioned way and roll your own:

Map<String, Integer> instances = new HashMap<String, Integer>();

void add(String name) {
     Integer value = instances.get(name);
     if (value == null) {
        value = new Integer(0);
        instances.put(name, value);
     }
     instances.put(name, value++);
}

Actually, Collections class has a static method called : frequency(Collection c, Object o) which returns the number of occurrences of the element you are searching for, by the way, this will work perfectly for you:

ArrayList<String> animals = new ArrayList<String>();
animals.add("bat");
animals.add("owl");
animals.add("bat");
animals.add("bat");
System.out.println("Freq of bat: "+Collections.frequency(animals, "bat"));

I wonder, why you can't use that Google's Collection API with JDK 1.6. Does it say so? I think you can, there should not be any compatibility issues, as it is built for a lower version. The case would have been different if that were built for 1.6 and you are running 1.5.

Am I wrong somewhere?


There is no native method in Java to do that for you. However, you can use IterableUtils#countMatches() from Apache Commons-Collections to do it for you.


Put the elements of the arraylist in the hashMap to count the frequency.


List<String> lst = new ArrayList<String>();

lst.add("Ram");
lst.add("Ram");
lst.add("Shiv");
lst.add("Boss");

Map<String, Integer> mp = new HashMap<String, Integer>();

for (String string : lst) {

    if(mp.keySet().contains(string))
    {
        mp.put(string, mp.get(string)+1);

    }else
    {
        mp.put(string, 1);
    }
}

System.out.println("=mp="+mp);

Output:

=mp= {Ram=2, Boss=1, Shiv=1}

package traversal;

import java.util.ArrayList;
import java.util.List;

public class Occurrance {
    static int count;

    public static void main(String[] args) {
        List<String> ls = new ArrayList<String>();
        ls.add("aa");
        ls.add("aa");
        ls.add("bb");
        ls.add("cc");
        ls.add("dd");
        ls.add("ee");
        ls.add("ee");
        ls.add("aa");
        ls.add("aa");

        for (int i = 0; i < ls.size(); i++) {
            if (ls.get(i) == "aa") {
                count = count + 1;
            }
        }
        System.out.println(count);
    }
}

Output: 4


In Java 8:

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

?If you use Eclipse Collections, you can use a Bag. A MutableBag can be returned from any implementation of RichIterable by calling toBag().

MutableList<String> animals = Lists.mutable.with("bat", "owl", "bat", "bat");
MutableBag<String> bag = animals.toBag();
Assert.assertEquals(3, bag.occurrencesOf("bat"));
Assert.assertEquals(1, bag.occurrencesOf("owl"));

The HashBag implementation in Eclipse Collections is backed by a MutableObjectIntMap.

Note: I am a committer for Eclipse Collections.


In Java 8:

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

To get the occurrences of the object from the list directly:

int noOfOccurs = Collections.frequency(animals, "bat");

To get the occurrence of the Object collection inside list, override the equals method in the Object class as:

@Override
public boolean equals(Object o){
    Animals e;
    if(!(o instanceof Animals)){
        return false;
    }else{
        e=(Animals)o;
        if(this.type==e.type()){
            return true;
        }
    }
    return false;
}

Animals(int type){
    this.type = type;
}

Call the Collections.frequency as:

int noOfOccurs = Collections.frequency(animals, new Animals(1));

I wonder, why you can't use that Google's Collection API with JDK 1.6. Does it say so? I think you can, there should not be any compatibility issues, as it is built for a lower version. The case would have been different if that were built for 1.6 and you are running 1.5.

Am I wrong somewhere?


List<String> lst = new ArrayList<String>();

lst.add("Ram");
lst.add("Ram");
lst.add("Shiv");
lst.add("Boss");

Map<String, Integer> mp = new HashMap<String, Integer>();

for (String string : lst) {

    if(mp.keySet().contains(string))
    {
        mp.put(string, mp.get(string)+1);

    }else
    {
        mp.put(string, 1);
    }
}

System.out.println("=mp="+mp);

Output:

=mp= {Ram=2, Boss=1, Shiv=1}

To achieve that one can do it in several ways, namely:

Methods that return the number of occurrence of a single element:

Collection Frequency

Collections.frequency(animals, "bat");

Java Stream:

Filter

animals.stream().filter("bat"::equals).count();

Just iteration thought the list

public static long manually(Collection<?> c, Object o){
    int count = 0;
    for(Object e : c)
        if(e.equals(o))
            count++;
    return count;
}

Methods that create a map of frequencies:

Collectors.groupingBy

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

merge

Map<String, Long> map = new HashMap<>();
c.forEach(e -> map.merge(e, 1L, Long::sum));

Manually

Map<String, Integer> mp = new HashMap<>();
        animals.forEach(animal -> mp.compute(animal, (k, v) -> (v == null) ? 1 : v + 1));

A running example with all the methods:

public class Frequency {

    public static int frequency(Collection<?> c, Object o){
        return Collections.frequency(c, o);
    }

    public static long filter(Collection<?> c, Object o){
        return c.stream().filter(o::equals).count();
    }

    public static long manually(Collection<?> c, Object o){
        int count = 0;
        for(Object e : c)
            if(e.equals(o))
                count++;
        return count;
    }

    public static Map<?, Long> mapGroupBy(Collection<?> c){
        return c.stream()
                .collect(Collectors.groupingBy(Function.identity() , Collectors.counting()));
    }

    public static Map<Object, Long> mapMerge(Collection<?> c){
         Map<Object, Long> map = new HashMap<>();
         c.forEach(e -> map.merge(e, 1L, Long::sum));
         return map;
    }

    public static Map<Object, Long> manualMap(Collection<?> c){
        Map<Object, Long> map = new HashMap<>();
        c.forEach(e -> map.compute(e, (k, v) -> (v == null) ? 1 : v + 1));
        return map;
    }


    public static void main(String[] args){
        List<String> animals = new ArrayList<>();
        animals.add("bat");
        animals.add("owl");
        animals.add("bat");
        animals.add("bat");

        System.out.println(frequency(animals, "bat"));
        System.out.println(filter(animals,"bat"));
        System.out.println(manually(animals,"bat"));
        mapGroupBy(animals).forEach((k, v) -> System.out.println(k + " -> "+v));
        mapMerge(animals).forEach((k, v) -> System.out.println(k + " -> "+v));
        manualMap(animals).forEach((k, v) -> System.out.println(k + " -> "+v));
    }
}

The methods name should have reflected what those methods are doing, however, I used the name to reflect the approach being used instead (given that in the current context it is okey).


Map<String,Integer> hm = new HashMap<String, Integer>();
for(String i : animals) {
    Integer j = hm.get(i);
    hm.put(i,(j==null ? 1 : j+1));
}
for(Map.Entry<String, Integer> val : hm.entrySet()) {
    System.out.println(val.getKey()+" occurs : "+val.getValue()+" times");
}

Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to arraylist

Adding null values to arraylist How to iterate through an ArrayList of Objects of ArrayList of Objects? Dynamically adding elements to ArrayList in Groovy How to replace existing value of ArrayList element in Java How to remove the last element added into the List? How to append elements at the end of ArrayList in Java? Removing Duplicate Values from ArrayList How to declare an ArrayList with values? In Java, can you modify a List while iterating through it? Load arrayList data into JTable

Examples related to collections

Kotlin's List missing "add", "remove", Map missing "put", etc? How to unset (remove) a collection element after fetching it? How can I get a List from some class properties with Java 8 Stream? Java 8 stream map to list of keys sorted by values How to convert String into Hashmap in java How can I turn a List of Lists into a List in Java 8? MongoDB Show all contents from all collections Get nth character of a string in Swift programming language Java 8 Distinct by property Is there a typescript List<> and/or Map<> class/library?