Java DoubleConsumer Interface
Last modified: April 16, 2025
The java.util.function.DoubleConsumer
interface represents an
operation that accepts a single double-valued argument and returns no result.
It is a functional interface with a single abstract method accept
.
DoubleConsumer is commonly used for operations that consume primitive double
values without returning anything.
DoubleConsumer
is part of Java's functional programming utilities
added in Java 8. It enables behavior parameterization for double values and
helps write more concise code. The interface provides a default method for
consumer chaining.
DoubleConsumer Interface Overview
DoubleConsumer
interface contains one abstract method and one
default method. The key method accept
performs the operation on
the input. The default method enables consumer chaining.
@FunctionalInterface public interface DoubleConsumer { void accept(double value); default DoubleConsumer andThen(DoubleConsumer after); }
The code above shows the structure of DoubleConsumer
interface.
It operates on primitive double values. The interface is annotated with
@FunctionalInterface to indicate its single abstract method nature.
Basic DoubleConsumer Usage
The simplest way to use DoubleConsumer is with lambda expressions. We define what to do with the double value in the accept method. The example prints double values with formatting.
package com.zetcode; import java.util.function.DoubleConsumer; public class Main { public static void main(String[] args) { // Define a consumer that prints formatted double values DoubleConsumer printFormatted = d -> System.out.printf("Value: %.2f%n", d); // Use the consumer printFormatted.accept(3.14159); printFormatted.accept(2.71828); // Consumer using method reference DoubleConsumer printer = System.out::println; printer.accept(1.41421); } }
This example demonstrates basic DoubleConsumer usage with lambda and method reference. The printFormatted consumer formats and prints doubles. The printer consumer uses method reference to System.out.println for direct output.
DoubleConsumer with andThen
The andThen
method allows chaining consumers where each consumer
processes the same value in sequence. This enables creating complex processing
pipelines from simple consumers.
package com.zetcode; import java.util.function.DoubleConsumer; public class Main { public static void main(String[] args) { // First consumer logs the value DoubleConsumer logger = d -> System.out.println("Logging: " + d); // Second consumer calculates square DoubleConsumer squarer = d -> System.out.println("Square: " + (d * d)); // Chain the consumers DoubleConsumer logThenSquare = logger.andThen(squarer); System.out.println("Processing 3.0:"); logThenSquare.accept(3.0); System.out.println("\nProcessing 1.5:"); logThenSquare.accept(1.5); } }
This example shows consumer chaining with andThen
. The input value
first gets logged, then squared. Both operations happen in sequence for each
value passed to the combined consumer.
DoubleConsumer in Stream Processing
DoubleConsumer is commonly used with DoubleStream for processing primitive double values. The forEach terminal operation accepts a DoubleConsumer to process each stream element.
package com.zetcode; import java.util.stream.DoubleStream; public class Main { public static void main(String[] args) { // Create a stream of double values DoubleStream values = DoubleStream.of(1.1, 2.2, 3.3, 4.4, 5.5); // Define a consumer that processes each value values.forEach(d -> { double rounded = Math.round(d * 10) / 10.0; System.out.println("Original: " + d + ", Rounded: " + rounded); }); // Another example with method reference DoubleStream.of(0.5, 1.5, 2.5).forEach(System.out::println); } }
This example demonstrates DoubleConsumer usage in DoubleStream processing. We define a consumer that rounds and prints each value. Method reference provides a concise alternative for simple output operations.
Storing State in DoubleConsumer
While generally discouraged for pure functions, consumers can maintain state when needed. This example shows a consumer that tracks statistics about the values it processes.
package com.zetcode; import java.util.function.DoubleConsumer; public class Main { public static void main(String[] args) { // Consumer that tracks statistics class StatsConsumer implements DoubleConsumer { private double sum = 0; private int count = 0; private double min = Double.MAX_VALUE; private double max = Double.MIN_VALUE; @Override public void accept(double value) { sum += value; count++; min = Math.min(min, value); max = Math.max(max, value); } public void printStats() { System.out.printf("Count: %d, Sum: %.2f, Avg: %.2f%n", count, sum, sum/count); System.out.printf("Min: %.2f, Max: %.2f%n", min, max); } } StatsConsumer stats = new StatsConsumer(); // Process some values stats.accept(5.5); stats.accept(3.2); stats.accept(7.8); stats.accept(1.1); // Print collected statistics stats.printStats(); } }
This example shows a stateful DoubleConsumer implementation. The StatsConsumer tracks sum, count, min and max of processed values. While functional interfaces are often stateless, this demonstrates their flexibility when needed.
Combining DoubleConsumer with Other Functional Interfaces
DoubleConsumer can be effectively combined with other functional interfaces to create more complex operations. This example shows pairing it with DoublePredicate.
package com.zetcode; import java.util.function.DoubleConsumer; import java.util.function.DoublePredicate; public class Main { public static void main(String[] args) { // Predicate to check if value is positive DoublePredicate isPositive = d -> d > 0; // Consumer for positive values DoubleConsumer positiveConsumer = d -> System.out.println("Processing positive: " + d); // Consumer for negative values DoubleConsumer negativeConsumer = d -> System.out.println("Processing negative: " + d); // Combined processor DoubleConsumer processor = d -> { if (isPositive.test(d)) { positiveConsumer.accept(d); } else { negativeConsumer.accept(d); } }; // Test the processor processor.accept(3.14); processor.accept(-2.71); processor.accept(0.0); } }
This example demonstrates combining DoubleConsumer with DoublePredicate. We create different consumers for positive and negative values, then combine them with a predicate check. This pattern enables conditional processing pipelines.
DoubleConsumer in Real-World Scenario
This example shows a more practical use case where DoubleConsumer processes temperature readings from a sensor, with validation and multiple processing steps.
package com.zetcode; import java.util.function.DoubleConsumer; public class Main { public static void main(String[] args) { // Valid temperature range final double MIN_TEMP = -50.0; final double MAX_TEMP = 100.0; // Consumer to validate temperature DoubleConsumer validator = temp -> { if (temp < MIN_TEMP || temp > MAX_TEMP) { throw new IllegalArgumentException( String.format("Invalid temperature: %.1f", temp)); } }; // Consumer to convert to Fahrenheit DoubleConsumer fahrenheitConverter = temp -> { double fahr = temp * 9/5 + 32; System.out.printf("%.1f°C = %.1f°F%n", temp, fahr); }; // Consumer to check for extreme temperatures DoubleConsumer extremeChecker = temp -> { if (temp > 35.0) { System.out.println("WARNING: High temperature alert!"); } else if (temp < 0.0) { System.out.println("WARNING: Freezing temperature!"); } }; // Combined processing pipeline DoubleConsumer tempProcessor = validator .andThen(extremeChecker) .andThen(fahrenheitConverter); // Process some temperature readings double[] readings = {25.5, -1.2, 36.7, 150.0, -60.0}; for (double temp : readings) { try { System.out.println("\nProcessing: " + temp); tempProcessor.accept(temp); } catch (IllegalArgumentException e) { System.out.println("Error: " + e.getMessage()); } } } }
This example demonstrates a realistic use of DoubleConsumer for temperature processing. We chain validation, checking, and conversion operations. The pipeline handles invalid values gracefully with exception handling.
Source
Java DoubleConsumer Interface Documentation
In this article, we've covered the essential methods and features of the Java DoubleConsumer interface. Understanding these concepts is crucial for processing primitive double values in functional programming and stream operations.
Author
List all Java tutorials.