🚀 Introduction to Java Function
Functional Interface
In Java functional programming, the Function<T, R>
interface (from java.util.function
) represents a function that takes one input and returns a result.
✅ T (Input Type): The type of the input value.
✅ R (Return Type): The type of the output value.
💡 Common Use Cases:
✔ Data transformation — Converting one type into another (e.g., string to uppercase).
✔ Composing functions — Applying multiple transformations sequentially.
✔ Processing user input — Validating, formatting, or mapping values.
📌 In this article, you’ll learn:
✅ How to use Function<T, R>
with examples.
✅ How to use apply()
, andThen()
, compose()
, and identity()
.
✅ Real-world use cases where Function
improves Java applications.
You can find the source code of this article on my GitHub repository.
1️⃣ Using apply()
Method for Basic Transformation
The apply(T t)
the method is used to transform the input into the output.
✔ Traditional Way (Before Java 8)
import java.util.function.Function;
public class FunctionDemo {
public static void main(String[] args) {
// Traditional way using anonymous class
Function<String, String> function = new Function<String, String>() {
@Override
public String apply(String s) {
return s.toUpperCase();
}
};
String result = function.apply("Ramesh");
System.out.println(result); // Output: RAMESH
}
}
📌 Problems:
❌ Verbose code — Requires defining a full anonymous class.
✔ Using Lambda Expression (Java 8+)
import java.util.function.Function;
public class FunctionDemo {
public static void main(String[] args) {
// ✅ Using Lambda Expression
Function<String, String> function1 = message -> message.toUpperCase();
System.out.println(function1.apply("Ramesh")); // Output: RAMESH
}
}
📌 Why is this better?
✅ More concise — Eliminates unnecessary class structure.
✅ Improves readability — Clearer function definition.
🚀 Use lambda expressions to simplify function usage!
2️⃣ Reversing Strings Using Function
Another useful example is reversing a string using a Function
.
✔ Example: Reversing a String
import java.util.function.Function;
public class FunctionDemo {
public static void main(String[] args) {
Function<String, String> reverseString = str -> new StringBuilder(str).reverse().toString();
System.out.println(reverseString.apply("Fadatare")); // Output: eratadaF
}
}
📌 Why use a Function
for this?
✅ Encapsulates logic into a reusable function.
✅ Easily composable with other transformations.
🚀 Use Function<T, R>
for encapsulated, reusable transformations!
3️⃣ Combining Functions with andThen()
✔ Using andThen()
for Chaining Functions
The andThen(Function<T, R>)
method allows applying one function after another.
import java.util.function.Function;
public class AndThenExample {
public static void main(String[] args) {
// Function to convert string to uppercase
Function<String, String> toUpperCase = str -> str.toUpperCase();
// Function to get the length of the string
Function<String, Integer> stringLength = str -> str.length();
// Apply uppercase first, then get length
Function<String, Integer> upperCaseThenLength = toUpperCase.andThen(stringLength);
int length = upperCaseThenLength.apply("Ramesh");
System.out.println(length); // Output: 6
}
}
📌 Why use andThen()
?
✅ Sequentially apply multiple transformations.
✅ Improves function composition and readability.
🚀 Use andThen()
to chain functions in a structured way!
4️⃣ Function Composition Using compose()
✔ Using compose()
for Preprocessing Before Function Execution
The compose(Function<T, R>)
method applies one function before another.
import java.util.function.Function;
public class ComposeExample {
public static void main(String[] args) {
// Function to trim whitespace
Function<String, String> trim = str -> str.trim();
// Function to convert string to uppercase
Function<String, String> toUpperCase = str -> str.toUpperCase();
// Apply trim first, then uppercase
Function<String, String> trimThenUpperCase = toUpperCase.compose(trim);
String result = trimThenUpperCase.apply(" hello ");
System.out.println(result); // Output: HELLO
}
}
📌 Why use compose()
?
✅ Useful for pre-processing inputs.
✅ Improves function chaining flexibility.
🚀 Use compose()
when preprocessing is required before applying the main function!
5️⃣ Identity Function Using Function.identity()
✔ When to Use identity()
Function.identity()
returns the input as output, without modification.
import java.util.function.Function;
public class IdentityExample {
public static void main(String[] args) {
Function<String, String> function = Function.identity();
String result = function.apply("hello");
System.out.println(result); // Output: hello
}
}
📌 Why use identity()
?
✅ Useful in stream operations where transformation isn’t needed.
✅ Prevents unnecessary operations in some cases.
🚀 Use Function.identity()
when you need a placeholder function!
6️⃣ Real-World Use Cases of Function
Interface
✔ Use Case 1: Data Processing in APIs
In APIs, Function
can help convert DTOs (Data Transfer Objects) into domain objects.
import java.util.function.Function;
class UserDTO {
String name;
int age;
UserDTO(String name, int age) { this.name = name; this.age = age; }
}
class User {
String fullName;
int age;
User(String fullName, int age) { this.fullName = fullName; this.age = age; }
}
public class ApiExample {
public static void main(String[] args) {
Function<UserDTO, User> userMapper = dto -> new User(dto.name, dto.age);
UserDTO dto = new UserDTO("Ramesh", 30);
User user = userMapper.apply(dto);
System.out.println(user.fullName + ", Age: " + user.age); // Output: Ramesh, Age: 30
}
}
📌 Why use Function
?
✅ Reduces boilerplate mapping code in APIs.
✅ Encapsulates conversion logic for reuse.
✔ Use Case 2: Logging Function for Error Handling
import java.util.function.Function;
public class LoggingExample {
public static void main(String[] args) {
Function<String, String> logError = message -> "ERROR: " + message;
System.out.println(logError.apply("Invalid input")); // Output: ERROR: Invalid input
}
}
📌 Why use Function
?
✅ Standardizes logging format across applications.
🚀 Use Function
in real-world applications for data transformation and logging!
🔑 Key Takeaways
✅ The Function<T, R>
interface allows one-parameter transformations.
✅ Use apply()
, andThen()
, compose()
, and identity()
for efficient processing.
✅ Apply Function
in real-world use cases like DTO mapping and logging.
By mastering the Function
functional interface, your Java code will be more modular, readable, and reusable! 🚀
Comments
Post a Comment
Leave Comment