Count Occurrences Using Streams

Java coding interview problem for Java 8 Streams: Count Occurrences Using Streams.

Counting occurrences of elements is one of the most common Java Collections and Stream API interview problems.

Examples:

  • Count how many times a number appears.
  • Count character frequency.
  • Count word occurrences.
  • Count employees by department.

This problem introduces:

  • Stream API
  • filter()
  • count()
  • Collectors.groupingBy()
  • Collectors.counting()
  • Frequency analysis

What is Counting Occurrences?

Occurrence counting means finding how many times an element appears in a collection.


Example:

Input:

[10,20,10,30,20,10]

Count:

10 → 3 times

20 → 2 times

30 → 1 time

Understanding Frequency and Occurrence Counting

Occurrence:

Number of times a particular element appears.


Frequency:

A mapping between elements and their occurrence count.


Example:

Input:

apple

Character frequency:

a → 1

p → 2

l → 1

e → 1

Difference Between Count and Frequency Map

Count

Returns:

Single number

Example:

How many times does:

Java

appear?

Output:

3

Frequency Map

Returns:

Element → Count

Example:

Java → 3

Spring → 2

AWS → 1

Why Occurrence Problems Are Important?

Occurrence counting is the foundation of many algorithms.

It helps with:

  • Duplicate detection
  • Frequency analysis
  • Data aggregation
  • Searching patterns
  • Analytics

Real-World Applications

Log Analysis

Count:

Error messages

Warning messages

Request types

Banking Systems

Count:

Transaction types

Failed payments

Successful payments

Search Engines

Analyze:

Keyword frequency

E-Commerce

Count:

Product views

Customer purchases

Problem Statement

Given a list of elements, count how many times a specific element occurs using Java Streams.


Example 1

Input:

[10,20,10,30,10]

Find:

10

Output:

10 occurs 3 times

Example 2

Input:

["Java","Spring","Java","AWS"]

Find:

Java

Output:

Java occurs 2 times

Java Stream API Overview

Streams provide a functional way to process collections.


Stream flow:

Collection

      ↓

Stream

      ↓

Operations

      ↓

Result

Example:

list.stream()

creates a stream pipeline.


Stream Pipeline Concept

Example:

numbers.stream()

.filter()

.count();

Flow:

List

 ↓

stream()

 ↓

Filter Matching Elements

 ↓

Count Results

Approach 1 — Traditional Loop Approach

Before Streams, counting was done using loops.


Algorithm

  1. Create counter.
  2. Traverse collection.
  3. Compare elements.
  4. Increment count.

Java Program

import java.util.*;

public class CountOccurrences {


    public static int count(
            List<Integer> numbers,
            int target) {


        int count = 0;


        for(Integer number : numbers) {


            if(number == target) {

                count++;

            }

        }


        return count;

    }


    public static void main(String[] args) {


        List<Integer> numbers =
                Arrays.asList(
                    10,
                    20,
                    10,
                    30,
                    10
                );


        System.out.println(
            count(numbers,10)
        );

    }

}

Output

3

Dry Run

Input:

[10,20,10,30,10]

Target:

10

Initial:

count = 0

Read:

10

Match.

count = 1

Read:

20

No match.


Read:

10

Match.

count = 2

Read:

30

No match.


Read:

10

Match.

count = 3

Final:

3

Complexity Analysis — Loop Approach

Let:

n = number of elements

Traversal:

O(n)

Space:

O(1)

Approach 2 — Using Stream filter() and count()

Java Streams provide:

filter()

and:

count()

for occurrence counting.


Syntax

stream()

.filter(condition)

.count();

Java Program

import java.util.*;

public class CountUsingStreams {


    public static long count(
            List<Integer> numbers,
            int target) {


        return numbers.stream()

                .filter(
                    number ->
                    number == target
                )

                .count();

    }


    public static void main(String[] args) {


        List<Integer> numbers =
                Arrays.asList(
                    10,
                    20,
                    10,
                    30,
                    10
                );


        System.out.println(
            count(numbers,10)
        );

    }

}

Output

3

Step-by-Step Stream Explanation

Input:

[10,20,10,30,10]

Stream:

10

20

10

30

10

Filter:

number == 10

Evaluation:

10 → true

20 → false

10 → true

30 → false

10 → true

Remaining:

10

10

10

Count:

3

Stream Pipeline Diagram

List<Integer>

       ↓

stream()

       ↓

filter()

       ↓

Matching Elements

       ↓

count()

       ↓

Long Result

Counting Character Occurrences

Example:

Input:

"programming"

Find:

g

Expected:

g occurs 2 times

Java Program

public static long countCharacter(
        String text,
        char target) {


    return text.chars()

            .filter(
                ch ->
                ch == target
            )

            .count();

}

Explanation

String:

programming

Characters:

p r o g r a m m i n g

Filter:

g == target

Matches:

g

g

Result:

2

Counting Word Occurrences

Example:

Input:

"Java Spring Java AWS Java"

Find:

Java

Java Program

String text =
"Java Spring Java AWS Java";


long count =

Arrays.stream(
    text.split(" ")
)

.filter(
    word ->
    word.equals("Java")
)

.count();

Output:

3

Approach 3 — Using Collectors.groupingBy()

Instead of counting one element, we often need all frequencies.


Example:

Input:

[Java,Spring,Java,AWS,Spring]

Expected:

Java → 2

Spring → 2

AWS → 1

Java Program

import java.util.*;
import java.util.stream.Collectors;


Map<String,Long> frequency =

words.stream()

.collect(

Collectors.groupingBy(

word -> word,

Collectors.counting()

)

);

Output

{
Java=2,

Spring=2,

AWS=1
}

Step-by-Step Explanation

Input:

Java

Spring

Java

AWS

Spring

Grouping:

Java group

Spring group

AWS group

Counting:

Java → 2

Spring → 2

AWS → 1

Understanding Collectors.counting()

Collector:

Collectors.counting()

counts elements inside each group.


Example:

Group:

Java

Java

Count:

2

Handling Case Sensitivity

Input:

Java

java

JAVA

Default:

Different values:

Java → 1

java → 1

JAVA → 1

Case-insensitive:

Convert:

toLowerCase()

Example:

words.stream()

.map(
    String::toLowerCase
)

.collect(
    Collectors.groupingBy(
        word -> word,
        Collectors.counting()
    )
);

Handling Null Values

Input:

[Java,null,AWS]

Filter:

words.stream()

.filter(
    Objects::nonNull
)

.count();

Time and Space Complexity

filter() + count()

Time:

O(n)

Space:

O(1)

groupingBy() Frequency Map

Time:

O(n)

Space:

O(k)

where:

k = unique elements

Advantages

  • Clean functional approach.
  • Easy frequency analysis.
  • Less boilerplate.
  • Supports complex grouping.

Drawbacks

  • Requires Stream knowledge.
  • Frequency maps require additional memory.
  • Debugging can be harder.

Deep Dive Into Collectors.counting()

Collectors.counting() is a downstream collector used with grouping operations.

It counts:

Number of elements inside each group

Syntax

Collectors.counting()

Example:

Map<String,Long> result =

words.stream()

.collect(

Collectors.groupingBy(

word -> word,

Collectors.counting()

)

);

Input:

Java

Spring

Java

Processing:

Grouping:

Java → [Java,Java]

Spring → [Spring]

Counting:

Java → 2

Spring → 1

Counting Duplicate Elements

A common interview question:

Find duplicate elements in a list.


Example:

Input:

[10,20,10,30,20,40]

Frequency:

10 → 2

20 → 2

30 → 1

40 → 1

Duplicates:

10

20

Java Program

List<Integer> duplicates =

numbers.stream()

.collect(

Collectors.groupingBy(

number -> number,

Collectors.counting()

)

)

.entrySet()

.stream()

.filter(

entry ->
entry.getValue() > 1

)

.map(

Map.Entry::getKey

)

.toList();

Dry Run

Input:

[10,20,10,30,20]

Grouping:

10 → [10,10]

20 → [20,20]

30 → [30]

Counting:

10 → 2

20 → 2

30 → 1

Filter:

count > 1

Result:

[10,20]

Finding Most Frequent Element

Problem:

Find the element that appears maximum times.


Example:

Input:

[Java,AWS,Java,Spring,Java]

Frequency:

Java → 3

AWS → 1

Spring → 1

Result:

Java

Java Program

String mostFrequent =

words.stream()

.collect(

Collectors.groupingBy(

word -> word,

Collectors.counting()

)

)

.entrySet()

.stream()

.max(

Map.Entry.comparingByValue()

)

.map(

Map.Entry::getKey

)

.orElse(null);

Explanation

Step 1:

Create frequency map.

Java → 3

AWS → 1

Spring → 1

Step 2:

Find maximum value.

Java → 3

Step 3:

Return key.

Java

Finding First Repeated Element

Problem:

Find the first element that appears more than once.


Example:

Input:

[5,3,8,3,5]

Output:

3

because:

3 appears first as duplicate

Java Program

Integer firstRepeated =

numbers.stream()

.filter(

number ->

Collections.frequency(
    numbers,
    number
) > 1

)

.findFirst()

.orElse(null);

Note:

Collections.frequency() scans the list repeatedly.

For large data, use:

HashMap frequency counting

Better Stream Approach

Map<Integer,Long> frequency =

numbers.stream()

.collect(

Collectors.groupingBy(

number -> number,

Collectors.counting()

)

);


Integer result =

numbers.stream()

.filter(

number ->
frequency.get(number) > 1

)

.findFirst()

.orElse(null);

Counting Object Occurrences

Streams can count custom objects.

Example:

Order:

orderId

status

Requirement:

Count orders by status.


Input:

ORDER_CREATED

ORDER_COMPLETED

ORDER_CREATED

Expected:

ORDER_CREATED → 2

ORDER_COMPLETED → 1

Java Program

Map<String,Long> statusCount =

orders.stream()

.collect(

Collectors.groupingBy(

Order::getStatus,

Collectors.counting()

)

);

Counting Employees by Department

Common enterprise interview question.


Employee:

John IT

Alice HR

Bob IT

David Finance

Expected:

IT → 2

HR → 1

Finance → 1

Java Program

Map<String,Long> employeeCount =

employees.stream()

.collect(

Collectors.groupingBy(

Employee::getDepartment,

Collectors.counting()

)

);

Counting Transactions by Status

Example:

Transactions:

SUCCESS

FAILED

SUCCESS

PENDING

Result:

SUCCESS → 2

FAILED → 1

PENDING → 1

Code:

Map<String,Long> result =

transactions.stream()

.collect(

Collectors.groupingBy(

Transaction::getStatus,

Collectors.counting()

)

);

count() vs counting()

Both count elements, but they are used differently.


Stream count()

Used directly on a Stream.

Example:

long count =

numbers.stream()

.filter(
    n -> n > 10
)

.count();

Returns:

Single count value

Example:

Numbers greater than 10 = 5

Collectors.counting()

Used inside collectors.

Example:

Collectors.groupingBy(

Employee::getDepartment,

Collectors.counting()

)

Returns:

Count per group

Comparison

Feature count() counting()
Usage Terminal operation Collector
Result One count Group counts
Works with Stream Collectors
Example Count all values Count by category

Primitive Stream Counting

Java provides:

IntStream

LongStream

DoubleStream

Example:

long count =

IntStream
.of(1,2,3,4,5)

.filter(
    n -> n % 2 == 0
)

.count();

Output:

2

Stream vs Loop Comparison

Feature Loop Streams
Code More Compact
Readability Simple Declarative
Grouping Manual Map handling Collectors
Parallel support Manual Built-in
Functional style No Yes

HashMap Internal Working

Frequency counting usually uses:

HashMap

When adding:

map.put(value,count)

Java performs:

Element

   ↓

hashCode()

   ↓

Bucket

   ↓

Store Count

Example:

Java → 3

Internally:

Key:

Java


Value:

3

Parallel Stream Considerations

For large datasets:

parallelStream()

can process groups in parallel.


Example:

Map<String,Long> result =

words.parallelStream()

.collect(

Collectors.groupingByConcurrent(

word -> word,

Collectors.counting()

)

);

Benefits:

  • Parallel execution
  • Better large-scale processing

Consider:

  • Dataset size
  • Thread overhead
  • Ordering requirements

Common Interview Mistakes

Mistake 1

Using:

count()

for frequency maps.

Wrong:

Need each element count

Use:

groupingBy() + counting()

Mistake 2

Ignoring case sensitivity.

Example:

Java

java

Different values.


Solution:

.map(
String::toLowerCase
)

Mistake 3

Using repeated frequency scans.

Example:

Collections.frequency()

inside loops.

Problem:

O(n²)

Mistake 4

Ignoring null values.

Use:

.filter(
Objects::nonNull
)

Edge Cases

Case Handling
Empty list Return empty map
Single element Count = 1
All duplicates One frequency entry
Null values Filter or handle
Large data Consider concurrent collectors

Interview Follow-up Questions

Q1. Difference between count() and counting()?

Q2. Find duplicate elements using Streams.

Q3. Find most frequent character.

Q4. Count employees by department.

Q5. How does groupingBy() work internally?

Q6. How to handle duplicate objects?

Q7. How to optimize frequency counting?


Related Java Collection Problems

  • Character Frequency Using Streams
  • Count Word Frequency Using HashMap
  • Find Duplicate Elements Using Streams
  • Group Employees by Department
  • Remove Duplicates Using Streams
  • Convert List to Map Using Streams

Key Takeaways

Occurrence counting patterns:

Single Element Count

        ↓

filter()

        ↓

count()

Frequency Map:

Elements

        ↓

groupingBy()

        ↓

counting()

        ↓

Element → Count

Duplicate Detection:

Frequency

        ↓

count > 1

        ↓

Duplicates

Most Frequent:

Frequency Map

        ↓

max()

        ↓

Highest Count Element

Complexity:

Simple count:

O(n)

Frequency map:

O(n)

Space:

O(k)

where:

k = unique elements

Frequently Asked Interview Questions

Q1. Why use groupingBy() with counting()?

Because groupingBy creates groups and counting calculates the size of each group.


Q2. Difference between count() and counting()?

count() counts stream elements directly.

counting() counts elements inside a collector.


Q3. How to find duplicate elements?

Create frequency map and filter:

count > 1

Q4. How to find the most frequent element?

Use:

groupingBy()

+

counting()

+

max()

Interview Tip

When asked:

"Count occurrences using Java Streams."

Explain:

  1. For one value use filter().count().
  2. For all frequencies use groupingBy().counting().
  3. For duplicates filter frequency greater than one.
  4. Handle case sensitivity and null values.
  5. Discuss HashMap-based complexity.

For senior Java interviews, discuss:

  • Collector design.
  • Frequency map patterns.
  • HashMap internals.
  • Parallel collectors.
  • Performance optimization.

This demonstrates strong understanding of Java Streams, Collections, and data aggregation patterns.