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 Function.compose - Complete Tutorial with Examples Java Function.compose MethodLast modified: April 16, 2025
The
Function composition is a fundamental concept in functional programming. It
enables building complex operations from simple functions. The Function.compose Basics
The Function<Integer, String> intToString = Object::toString; Function<String, Integer> stringLength = String::length; // Composed function: get length of string representation of integer Function<Integer, Integer> composed = stringLength.compose(intToString); // Equivalent to: stringLength(intToString(x)) This example shows basic composition. The composed function first converts an integer to string, then gets the string's length. The execution order is right-to-left in the composition chain. Simple Composition Example
This example demonstrates basic function composition with Main.java
package com.zetcode;
import java.util.function.Function;
public class Main {
public static void main(String[] args) {
// Function to add 10 to a number
Function<Integer, Integer> addTen = x -> x + 10;
// Function to multiply by 2
Function<Integer, Integer> timesTwo = x -> x * 2;
// Compose: first addTen, then timesTwo
Function<Integer, Integer> addThenMultiply = timesTwo.compose(addTen);
System.out.println("Add then multiply 5: " + addThenMultiply.apply(5));
// Compare with andThen
Function<Integer, Integer> multiplyThenAdd = timesTwo.andThen(addTen);
System.out.println("Multiply then add 5: " + multiplyThenAdd.apply(5));
}
}
The example shows the difference between String Transformation CompositionThis example composes multiple string transformation functions. We create reusable string operations and combine them in different ways. Main.java
package com.zetcode;
import java.util.function.Function;
public class Main {
public static void main(String[] args) {
// Basic string transformations
Function<String, String> trim = String::trim;
Function<String, String> toUpper = String::toUpperCase;
Function<String, String> addExclamation = s -> s + "!";
// Compose transformations
Function<String, String> cleanAndExcite =
addExclamation.compose(toUpper).compose(trim);
String input = " hello world ";
System.out.println("Original: '" + input + "'");
System.out.println("Transformed: '" + cleanAndExcite.apply(input) + "'");
// Different composition order
Function<String, String> exciteThenUpper =
toUpper.compose(addExclamation).compose(trim);
System.out.println("Different order: '" + exciteThenUpper.apply(input) + "'");
}
}
The example shows how to build complex string processing from simple functions. The composition order matters - trim always happens first in both cases, but exclamation and uppercase change order. The results are different. Composing Multiple Functions
We can chain multiple Main.java
package com.zetcode;
import java.util.function.Function;
public class Main {
public static void main(String[] args) {
// Mathematical operations
Function<Integer, Integer> square = x -> x * x;
Function<Integer, Integer> half = x -> x / 2;
Function<Integer, Integer> increment = x -> x + 1;
Function<Integer, String> toString = Object::toString;
// Create processing pipeline
Function<Integer, String> processNumber =
toString.compose(half).compose(increment).compose(square);
System.out.println("Process 4: " + processNumber.apply(4));
System.out.println("Process 5: " + processNumber.apply(5));
// Breakdown of operations for input 4:
// 1. square(4) = 16
// 2. increment(16) = 17
// 3. half(17) = 8 (integer division)
// 4. toString(8) = "8"
}
}
This example demonstrates a multi-step processing pipeline. The operations execute in reverse order of composition - square first, then increment, then half, finally toString. The comments show the step-by-step execution for input 4. Composing Different Types
Main.java
package com.zetcode;
import java.util.function.Function;
public class Main {
public static void main(String[] args) {
// Function chain with different types
Function<String, Integer> parseInteger = Integer::parseInt;
Function<Integer, Double> intToDouble = Integer::doubleValue;
Function<Double, String> formatDouble = d -> String.format("%.2f", d);
// Compose the functions
Function<String, String> stringProcessor =
formatDouble.compose(intToDouble).compose(parseInteger);
System.out.println("Process '42': " + stringProcessor.apply("42"));
System.out.println("Process '100': " + stringProcessor.apply("100"));
// The processing flow:
// String -> Integer -> Double -> String
}
}
This example shows type transformation through composition. We start with a String, parse it to Integer, convert to Double, then format back to String. The type conversions happen automatically through the function chain. Composing with Method References
Method references work well with Main.java
package com.zetcode;
import java.util.function.Function;
class Product {
private String name;
private double price;
public Product(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() { return name; }
public double getPrice() { return price; }
public double getDiscountedPrice() { return price * 0.9; }
}
public class Main {
public static void main(String[] args) {
// Method references for product processing
Function<Product, Double> getPrice = Product::getPrice;
Function<Double, String> formatPrice = p -> String.format("$%.2f", p);
// Composed function to get formatted price
Function<Product, String> getFormattedPrice = formatPrice.compose(getPrice);
Product laptop = new Product("Laptop", 999.99);
System.out.println("Price: " + getFormattedPrice.apply(laptop));
// Alternative composition with discounted price
Function<Product, String> getFormattedDiscountedPrice =
formatPrice.compose(Product::getDiscountedPrice);
System.out.println("Discounted: " + getFormattedDiscountedPrice.apply(laptop));
}
}
The example shows clean composition using method references. We process Product objects to get formatted price strings. The second example shows direct method reference composition for discounted price formatting. Practical Use Case: Data Validation
This practical example shows how Main.java
package com.zetcode;
import java.util.function.Function;
public class Main {
public static void main(String[] args) {
// Validation functions
Function<String, String> trimInput = String::trim;
Function<String, String> checkEmpty = s ->
s.isEmpty() ? "EMPTY" : s;
Function<String, String> validateLength = s ->
s.length() > 10 ? "TOO_LONG" : s;
Function<String, String> sanitize = s ->
s.replaceAll("[^a-zA-Z0-9]", "");
// Compose validation pipeline
Function<String, String> validateInput =
sanitize.compose(validateLength).compose(checkEmpty).compose(trimInput);
System.out.println("Valid ' hello ': " + validateInput.apply(" hello "));
System.out.println("Valid '': " + validateInput.apply(""));
System.out.println("Long input: " + validateInput.apply("12345678901"));
System.out.println("With symbols: " + validateInput.apply("user@name"));
}
}
This example shows a practical validation pipeline. Input goes through trimming, empty check, length validation, and sanitization. Each function handles one specific validation aspect. The composition creates a complete validation process. SourceJava Function Interface Documentation
The 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. |