GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing zetcode.com — Java BiConsumer Interface - Complete Tutorial with Examples Java BiConsumer InterfaceLast modified: April 16, 2025
The
BiConsumer Interface Overview
@FunctionalInterface
public interface BiConsumer<T, U> {
void accept(T t, U u);
default BiConsumer<T, U> andThen(BiConsumer<? super T, ? super U> after);
}
The code above shows the structure of Basic BiConsumer UsageThe simplest way to use BiConsumer is with lambda expressions. We define how to process two input values in the accept method. The example prints key-value pairs. Main.java
package com.zetcode;
import java.util.function.BiConsumer;
public class Main {
public static void main(String[] args) {
// Define a BiConsumer that prints two values
BiConsumer<String, Integer> printPair = (key, value) ->
System.out.println("Key: " + key + ", Value: " + value);
// Use the BiConsumer
printPair.accept("age", 30);
printPair.accept("score", 95);
// BiConsumer using method reference
BiConsumer<String, String> concatPrinter = System.out::println;
concatPrinter.accept("Hello", "World");
}
}
This example demonstrates basic BiConsumer usage with lambda and method reference. The printPair takes String and Integer inputs and prints them. Method reference provides concise syntax for existing methods that match BiConsumer signature. BiConsumer with Map Iteration
Main.java
package com.zetcode;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
public class Main {
public static void main(String[] args) {
Map<String, Integer> scores = new HashMap<>();
scores.put("Alice", 85);
scores.put("Bob", 92);
scores.put("Charlie", 78);
// BiConsumer to print map entries
BiConsumer<String, Integer> printEntry =
(name, score) -> System.out.println(name + ": " + score);
// Iterate map with BiConsumer
scores.forEach(printEntry);
// Direct lambda in forEach
scores.forEach((k, v) -> {
if (v > 80) {
System.out.println(k + " passed");
}
});
}
}
This example shows BiConsumer usage with Map.forEach. We first define a separate BiConsumer for printing entries, then use direct lambda for conditional logic. Map iteration becomes very expressive with BiConsumer. Chaining BiConsumers with andThen
The Main.java
package com.zetcode;
import java.util.function.BiConsumer;
public class Main {
public static void main(String[] args) {
// First BiConsumer logs the operation
BiConsumer<String, Integer> logger =
(item, qty) -> System.out.println("Processing: " + item + " x" + qty);
// Second BiConsumer processes the order
BiConsumer<String, Integer> processor =
(item, qty) -> System.out.println("Ordered " + qty + " of " + item);
// Chain the BiConsumers
BiConsumer<String, Integer> orderHandler = logger.andThen(processor);
// Use the chained BiConsumer
orderHandler.accept("Laptop", 2);
orderHandler.accept("Mouse", 5);
}
}
This example demonstrates BiConsumer chaining with BiConsumer for Object Modification
Main.java
package com.zetcode;
import java.util.function.BiConsumer;
class Product {
String name;
double price;
Product(String name, double price) {
this.name = name;
this.price = price;
}
@Override
public String toString() {
return name + ": $" + price;
}
}
public class Main {
public static void main(String[] args) {
// BiConsumer to update product price with discount
BiConsumer<Product, Double> applyDiscount =
(product, discount) -> {
product.price = product.price * (1 - discount/100);
System.out.println("Applied " + discount + "% discount");
};
Product laptop = new Product("Laptop", 999.99);
Product phone = new Product("Phone", 699.99);
applyDiscount.accept(laptop, 10.0);
applyDiscount.accept(phone, 15.0);
System.out.println(laptop);
System.out.println(phone);
}
}
This example shows BiConsumer modifying object state. The applyDiscount BiConsumer takes a Product and discount percentage, then updates the product's price. This pattern is useful for applying consistent modifications. BiConsumer in Stream Operations
Main.java
package com.zetcode;
import java.util.List;
import java.util.function.BiConsumer;
public class Main {
public static void main(String[] args) {
List<String> names = List.of("Alice", "Bob", "Charlie");
List<Integer> scores = List.of(85, 92, 78);
// BiConsumer to print name-score pairs
BiConsumer<String, Integer> printResult =
(name, score) -> System.out.println(name + " scored " + score);
// Process parallel lists with BiConsumer
if (names.size() == scores.size()) {
for (int i = 0; i < names.size(); i++) {
printResult.accept(names.get(i), scores.get(i));
}
}
// More complex BiConsumer
BiConsumer<String, Integer> resultAnalyzer = (name, score) -> {
String status = score >= 80 ? "Pass" : "Fail";
System.out.println(name + ": " + score + " (" + status + ")");
};
System.out.println("\nAnalysis:");
for (int i = 0; i < names.size(); i++) {
resultAnalyzer.accept(names.get(i), scores.get(i));
}
}
}
This example demonstrates BiConsumer processing parallel lists. We define two BiConsumers - one for simple printing and another for more complex analysis. This pattern is useful when processing related data in separate collections. Primitive Specializations of BiConsumerJava provides specialized versions of BiConsumer for primitive types to avoid autoboxing overhead. These include ObjIntConsumer, ObjLongConsumer, and ObjDoubleConsumer. Main.java
package com.zetcode;
import java.util.function.ObjIntConsumer;
import java.util.function.ObjDoubleConsumer;
public class Main {
public static void main(String[] args) {
// ObjIntConsumer example
ObjIntConsumer<String> printWithNumber =
(s, i) -> System.out.println(s + ": " + i);
printWithNumber.accept("Count", 42);
// ObjDoubleConsumer example
ObjDoubleConsumer<String> temperatureLogger =
(location, temp) -> System.out.printf("%s: %.1f°C%n", location, temp);
temperatureLogger.accept("New York", 22.5);
// Using BiConsumer with boxed primitives
BiConsumer<String, Integer> boxedConsumer =
(s, i) -> System.out.println(s.repeat(i));
boxedConsumer.accept("Hi ", 3);
}
}
This example shows primitive specializations of BiConsumer. ObjIntConsumer and ObjDoubleConsumer avoid boxing overhead when working with primitives. The last example shows regular BiConsumer with boxed Integer for comparison. Combining BiConsumer with Other Functional Interfaces
Main.java
package com.zetcode;
import java.util.function.BiConsumer;
import java.util.function.Function;
public class Main {
public static void main(String[] args) {
// Function to calculate area
Function<Double, Double> areaCalculator = radius -> Math.PI * radius * radius;
// BiConsumer to print formatted results
BiConsumer<String, Double> resultPrinter =
(label, value) -> System.out.printf("%s: %.2f%n", label, value);
// Process radius values
double[] radii = {1.0, 2.5, 3.0};
for (double r : radii) {
double area = areaCalculator.apply(r);
resultPrinter.accept("Radius " + r + " area", area);
}
// More complex combination
BiConsumer<String, Function<Double, Double>> calculator =
(name, func) -> {
double result = func.apply(10.0);
System.out.println(name + " at 10.0: " + result);
};
calculator.accept("Square", x -> x * x);
calculator.accept("Cube", x -> x * x * x);
}
}
This example demonstrates combining BiConsumer with Function. We first use them separately for calculation and printing, then create a BiConsumer that accepts a Function as its second parameter. This shows the flexibility of functional interfaces. SourceJava BiConsumer Interface Documentation In this article, we've covered the essential methods and features of the Java BiConsumer interface. Understanding these concepts is crucial for functional programming and collection processing in modern Java applications. AuthorMy name is Jan Bodnar, and I am a dedicated programmer with many years of experience in the field. I began writing programming articles in 2007 and have since authored over 1,400 articles and eight e-books. With more than eight years of teaching experience, I am committed to sharing my knowledge and helping others master programming concepts. List all Java tutorials. |
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |