Java 8 Summarizing Methods with Examples

  • Last Updated: May 4, 2024
  • By: javahandson
  • Series
img

Java 8 Summarizing Methods with Examples

Java 8 Summarizing Methods help calculate count, sum, min, max, and average in a single stream operation. Learn summarizingInt(), summarizingLong(), summarizingDouble(), and IntSummaryStatistics with clear practical examples.

1. What Are Java 8 Summarizing Methods?

In Java 8, we get a set of summarizing methods in the Stream API through the Collectors class. These methods help us generate summary statistics for numeric data cleanly and efficiently.

In simple terms, Java 8 Summarizing Methods allow us to calculate count, sum, minimum, maximum, and average in a single stream operation. Instead of running multiple stream pipelines, we can collect all statistics at once. As a result, our code becomes shorter, clearer, and easier to maintain.

For example, when we process a list of numbers, we often need more than just the sum. We may also want the average, the highest value, and the lowest value. If we compute them separately, we must traverse the stream multiple times. However, summarizing methods solve this problem by performing all calculations in one pass.

Because of this approach, we reduce boilerplate code and improve efficiency. Therefore, when we work on reports, analytics, salary calculations, or performance metrics, these methods become extremely useful.

Overall, Java 8 Summarizing Methods give us a powerful and elegant way to extract statistical information from collections.

2. Variants of Java 8 Summarizing Methods

Java 8 provides three variants of summarizing methods. Each variant works with a specific numeric type, although the overall behavior remains the same.

We use:

  • summarizingInt() for int values
  • summarizingLong() for long values
  • summarizingDouble() for double values

All three methods follow the same pattern. However, we choose the appropriate one based on the numeric type we extract from the stream.

In the following sections, we will explore each method in detail with practical examples.

3. summarizingInt Method

We use summarizingInt() When we want to compute statistics based on an int value extracted from stream elements.

Instead of performing multiple operations like sum, average, and min separately, we can calculate everything in one pass. As a result, our code becomes cleaner and more efficient.

Syntax of summarizingInt

public static <T> Collector<T, ?, IntSummaryStatistics> 
       summarizingInt(ToIntFunction<? super T> mapper> mapper)

Understanding the Method Signature of summarizingInt

Let us break this down in a practical way.

We call this method using the Collectors class, which is why it is declared as public static. Therefore, we simply use it like this:

Collectors.summarizingInt(...)

Next comes <T>. This represents the type of elements in the stream. For example, if we stream Student objects, then T becomes Student. Because of generics, this method works with any object type, which makes it flexible and reusable.

The return type is:

Collector<T, ?, IntSummaryStatistics>

This means the method returns a Collector that processes elements of type T and finally produces an IntSummaryStatistics object. That object contains all the calculated values, such as count, sum, minimum, maximum, and average. In other words, instead of returning a single number, the method returns a complete statistical summary.

Now, let us focus on the parameter:

ToIntFunction<? super T> mapper

This part tells Java how to extract a int value from each element in the stream. ToIntFunction is a functional interface that takes an object and returns an int.

For example:

Student::getMarks

Here, we take each Student object and extract the marks value. The stream then uses these extracted int values to compute all statistics in one pass.

Putting everything together, when we write:

Collectors.summarizingInt(Student::getMarks)

We instruct Java to:

  • Take each Student
  • Extract the marks
  • Compute count, sum, min, max, and average
  • Return all results inside an IntSummaryStatistics object

Although the signature looks advanced, it simply enables us to perform multiple statistical operations in a single, efficient stream pipeline. As a result, our code remains clean, expressive, and performance-friendly.

Example: Calculate Student Marks Statistics using summarizingInt

Suppose we want to calculate statistics on student marks.

package com.javahands.collectors.summarizing;
public class Student {

    int rollNumber;
    String name;
    int marks;

    public Student(int rollNumber, String name, int marks) {
        this.rollNumber = rollNumber;
        this.name = name;
        this.marks = marks;
    }

    public int getMarks() {
        return marks;
    }
}

Using summarizingInt()

package com.javahands.collectors.summarizing;

import java.util.Arrays;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.stream.Collectors;

public class SummarizingInt {
    public static void main(String[] args) {

        List<Student> studentList = Arrays.asList(
                new Student(101, "Suraj", 450),
                new Student(102, "Iqbal", 470),
                new Student(103, "Amar", 430),
                new Student(104, "Amit", 400),
                new Student(105, "Suchit", 380),
                new Student(106, "Kartik", 490));

        IntSummaryStatistics marksStats = studentList.stream()
                .collect(Collectors.summarizingInt(Student::getMarks));

        System.out.println("Average marks: " + marksStats.getAverage());
        System.out.println("Total marks: " + marksStats.getSum());
        System.out.println("Maximum marks: " + marksStats.getMax());
        System.out.println("Minimum marks: " + marksStats.getMin());
        System.out.println("Number of marks: " + marksStats.getCount());
    }
}
Output:
Average marks: 436.6666666666667
Total marks: 2620
Maximum marks: 490
Minimum marks: 380
Number of marks: 6

Here, we compute all statistics in a single stream traversal. Therefore, the solution remains both efficient and readable.

4. summarizingLong method

We use summarizingLong() When the extracted value is of type long. Although it behaves exactly like summarizingInt(), it works with larger numeric values.

Because of this, we prefer it when numbers might exceed the int range.

Syntax of summarizingLong

public static <T> Collector<T, ?, LongSummaryStatistics> 
       summarizingLong(ToLongFunction<? super T>mapper)

Understanding the Method Signature of summarizingLong

The summarizingLong() method follows the same pattern as summarizingInt(). However, it works with long values instead of int.

The key differences are straightforward.

Instead of ToIntFunction this method uses ToLongFunction. Therefore, we provide a mapping function that extracts a long value from each stream element.

Additionally, the method returns an LongSummaryStatistics object. This object stores count, sum, minimum, maximum, and average for long values.

Everything else remains the same. So, once we understand summarizingInt(), we can easily apply the same logic here. The only change lies in the numeric type we extract from the stream.

For example:

Collectors.summarizingLong(Product::getProductId)

Here, we extract the productId as a long and compute all statistics in a single stream operation.

Example: Calculate Product ID Statistics using summarizingLong

Suppose we want to analyze product IDs stored as long values.

package com.javahands.collectors.summarizing;

public class Product {

    long productId;
    String productName;
    double price;

    public Product(long productId, String productName, double price) {
        super();
        this.productId = productId;
        this.productName = productName;
        this.price = price;
    }

    public long getProductId() {
        return productId;
    }

    public void setProductId(long productId) {
        this.productId = productId;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

Using summarizingLong()

package com.javahands.collectors.summarizing;

import java.util.Arrays;
import java.util.List;
import java.util.LongSummaryStatistics;
import java.util.stream.Collectors;

public class SummarizingLong {
    public static void main(String[] args) {

        List<Product> products = Arrays.asList(
                new Product(101l, "Wheat", 155.50),
                new Product(102l, "Rice", 255.00),
                new Product(103l, "Cooking Oil", 525.70),
                new Product(104l, "Cookies", 200.00),
                new Product(105l, "Beans", 150.50));

        LongSummaryStatistics longSummaryStatistics = products.stream()
                .collect(Collectors.summarizingLong(Product::getProductId));

        System.out.println(longSummaryStatistics);
    }
}
Output: LongSummaryStatistics{count=5, sum=515, min=101, average=103.000000, max=105}

Again, we compute everything in one operation. As a result, the code remains concise and efficient.

5. summarizingDouble method

We use summarizingDouble() When the extracted value is of type double. This method becomes useful when we deal with decimal or precision values.

For example, we often use it for price, salary, or percentage calculations.

Syntax of summarizingDouble

public static <T> Collector<T, ?, DoubleSummaryStatistics> 
       summarizingDouble(ToDoubleFunction<? super T> mapper)

Understanding the Method Signature of summarizingDouble

The summarizingDouble() method follows the same structure as summarizingInt() and summarizingLong(). However, it works specifically with double values, which makes it suitable for precision-based data such as prices, percentages, or measurements.

Let us focus only on what changes here.

First, instead of ToIntFunction or ToLongFunction, this method uses ToDoubleFunction. That means we must provide a mapping function that extracts a double value from each stream element.

Second, the method returns a DoubleSummaryStatistics object. This object stores count, sum, minimum, maximum, and average for double values.

Everything else remains the same. Therefore, if we understand how summarizingInt() works, we already understand this method as well. The only difference lies in the numeric type we extract from the stream.

For example, when we write:

Collectors.summarizingDouble(Product::getPrice)

We instruct Java to extract the price data from each product and compute all statistics in a single pass.

Because of this design, we can efficiently process precision-based data without writing multiple stream operations.

Example: Calculate Product Price Statistics using summarizingDouble

package com.javahands.collectors.summarizing;

import java.util.Arrays;
import java.util.DoubleSummaryStatistics;
import java.util.List;
import java.util.stream.Collectors;

public class SummarizingDouble {
    public static void main(String[] args) {

        List<Product> products = Arrays.asList(
                new Product(101l, "Wheat", 155.50),
                new Product(102l, "Rice", 255.00),
                new Product(103l, "Cooking Oil", 525.70),
                new Product(104l, "Cookies", 200.00),
                new Product(105l, "Beans", 150.50));

        DoubleSummaryStatistics doubleSummaryStatistics = products.stream()
                .collect(Collectors.summarizingDouble(Product::getPrice));

        System.out.println(doubleSummaryStatistics);
    }
}
Output: DoubleSummaryStatistics{count=5, sum=1286.700000, min=150.500000, average=257.340000, max=525.700000}

Because we collect all statistics together, we avoid multiple stream operations. Therefore, our implementation remains both elegant and practical.

All three summarizing methods follow the same pattern. The only difference lies in the numeric type we extract:

  • summarizingInt() → for int values
  • summarizingLong() → for long values
  • summarizingDouble() → for double values

Whenever we need multiple statistics from a stream, these methods provide the cleanest solution.

6. Conclusion

Java 8 Summarizing Methods provide a clean and efficient way to compute multiple statistics in a single stream operation. Instead of writing separate logic for sum, average, minimum, maximum, and count, we can collect all values at once using summarizingInt(), summarizingLong(), or summarizingDouble().

Because these methods return summary statistics objects, we gain both clarity and performance. As a result, our code becomes more expressive and easier to maintain. Whether we work with student marks, product IDs, or price calculations, summarizing methods help us write concise and production-ready stream pipelines.

In real-world applications such as reporting, analytics, or financial computations, Java 8 Summarizing Methods allow us to extract meaningful insights with minimal code. Therefore, understanding these collectors strengthens our overall command of the Java 8 Stream API.

Further Reading

For the official documentation and complete details about summarizing collectors, see:

Collectors API – Java 8 Documentation (Oracle)
The official Java documentation explains how summarizingInt(), summarizingLong(), and summarizingDouble() work internally, along with other powerful collectors available in the Stream API.

We can also explore: IntSummaryStatistics, LongSummaryStatistics, and DoubleSummaryStatistics – Java API Docs
These classes define how summary statistics such as count, sum, min, max, and average are computed and stored.

What’s Next

In the next chapter, we move from calculating numeric summaries to organizing data into structured groups.

Grouping in Java 8 introduces the Collectors.groupingBy() method, which allows us to categorize stream elements based on specific properties. With grouping, we can transform flat collections into meaningful data structures such as maps of lists or aggregated results.

This shift takes us from summarizing values to structuring data, which is a powerful next step in mastering the Java 8 Stream API.

Leave a Comment