Explain Codes LogoExplain Codes Logo

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

java
collections
java-8
best-practices
Alex KataevbyAlex Kataev·Jan 12, 2025
TLDR

To count occurrences in a List, use Collections.frequency(List list, Object element). It's a straight-to-the-point approach:

int occurrences = Collections.frequency(myList, "apple"); // Get an "apple" count; how do you like them apples?

This line finds how often our "apple" is chilling in myList.

Rolling up the sleeves with HashMap

If Collections.frequency doesn't cut it for you or you're the type who wants to see what's happening under the hood, manually count the occurrences using HashMap. Here's how to do it:

HashMap<String, Integer> frequencyMap = new HashMap<>(); for(String item : myList) { frequencyMap.put(item, frequencyMap.getOrDefault(item, 0) + 1); // Increase the frequency of the party } int occurrences = frequencyMap.getOrDefault("apple", 0); // Get the party scale of "apple"

This approach offers flexibility and exciting insight into the inner workings of the frequency count.

Swagging it up with Java 8 streams

Java 8 introduced functional programming features, adding a modern touch to collections processing. Let's count occurrences using streams:

long occurrences = myList.stream() .filter("apple"::equals) .count(); // Here we go, counting all the "apple" in the stream. No Adam and Eve though.

This method shines in cases where you're into streams and you want to keep the groove going.

Building your List with built-in counting

If you need a collection that tracks element frequency by design, why not create a custom collection? Here's how to whip one up using a pinch of inheritance:

public class FrequencyList<E> extends ArrayList<E> { private final HashMap<E, Integer> frequencyMap = new HashMap<>(); @Override public boolean add(E e) { frequencyMap.put(e, frequencyMap.getOrDefault(e, 0) + 1); // Welcome to the party, E! Here's your number. return super.add(e); } public int getFrequency(E e) { return frequencyMap.getOrDefault(e, 0); // E, do you remember your number? } }

This custom class tucks away counting logic neatly and maintains a slick abstraction.

Juggling edge cases

While these methods work seamlessly for Strings or simple objects, counting can throw a curveball with complex objects. Make sure to override equals() and hashCode() methods to ensure smooth sailing, especially when working with collections or streams.

If multiple threads are knocking at your List, go with ConcurrentHashMap or synchronize your counting blocks to prevent concurrency headaches.

Counting without class surgery

In some scenarios, you might not have the liberty to rework existing classes. No worries! Use Java interfaces and lambda expressions to use a predicate that finds your elements:

long occurrences = myList.stream() .filter(item -> item.meetsCondition()) // sorting out the cool kids .count(); // getting the headcount for the party

Polymorphic Count: A tale of many types

Dealing with different element types in a List? Polymorphism permits various subclasses to be counted accurately:

HashMap<Class<?>, Integer> typeFrequency = new HashMap<>(); for(Object item : myList){ typeFrequency.put(item.getClass(), typeFrequency.getOrDefault(item.getClass(), 0) + 1); // Let's see who's more popular. }

Upgrading to Java 8 and future-proofing

While classic iteration methods hold their ground, refactoring to Java 8 streams can lead to cleaner, terse code, providing a ready springboard for future updates.