Just Finished Studying Default Functional Interfaces in Java, I thought of sharing them all!
Functional interfaces are interfaces that have only one abstract method. They are necessary if you'll be dealing with lambda expressions (functional programming). They simplify code and are widely used in streams. While you can create your own functional interfaces, why worry when Java provides us with some important ones like Consumer, Predicate, Function, and Supplier?
Consumer is a functional interface that represents an operation that accepts a single input argument and returns no result. It’s typically used to perform an action on the given argument (like printing or logging) without modifying it.
Signature: void accept(T t) (where T is the Generic type)
Predicate is a functional interface that represents a single argument function that returns a boolean value. It’s often used for filtering or evaluating conditions (e.g., checking if a number is even).
Signature: boolean test(T t)
Function is a functional interface that represents a function that accepts one argument and produces a result. It’s commonly used for transformations (e.g., converting one type to another or modifying data).
Signature: R apply(T t)
Supplier is a functional interface that represents a function with no input arguments and returns a result. It’s often used for generating or supplying values without needing input.
Signature: T get()
We can effectively use functional interfaces like Consumer, Predicate, Function, and Supplier by typically defining generic methods that accept these interfaces as parameters. This allows us to leverage the power of generics and ensure that our methods can work with various types.
Here's example of the complete code that demonstrates the functionality of all of them
import java.util.List; import java.util.Random; import java.util.function.*; public class Main { public static void main(String[] args) { // Consumer usingConsumer((a) -> System.out.printf("Hello %s", a), "saami"); System.out.println(); // Bi-Consumer usingBiConsumer((a, b) -> System.out.printf("Name: %s, Age: %d", a, b), "saami", 20); System.out.println(); // Predicate var result1 = usingPredicate((a) -> a % 2 == 0, 34); if (result1) { System.out.println("Even"); } else { System.out.println("Odd"); } // Bi-Predicate var result2 = usingBiPredicate((a, b) -> a > b, 12, 22); if (result2) { System.out.println("Greater"); } else { System.out.println("Lesser"); } // Function var result3 = usingFunction((a) -> a + ": this is a number", 5); System.out.println(result3); // Bi-Function var result4 = usingBiFunction((a, b) -> (a > b ? "Greater": "Lesser"), 5, 6); System.out.println(result4); // Unary-Operator var result5 = usingUnaryOperator((a) -> a+5, 10); System.out.println(result5); // Binary-Operator var result6 = usingBinaryOperator((a, b) -> a + b, 12, 32); System.out.println(result6); Random r = new Random(); // Function as Predicate var result7 = usingFunctionAsPredicate((a) -> a > 99, 999); System.out.println(result7); // Using Consumer for printing of the list. printData((a) -> { for (var ele : a) { System.out.println(ele); } } , List.of("S1", "S2", "S3", "S4", "S5")); // Using Supplier as a random number generator String[] arr = {"saami", "john", "raymond", "puff"}; System.out.println(getRandomOne(arr, () -> new Random().nextInt(arr.length))); // Using Custom Comparator System.out.println(usingCustomFunctionalInterface((a, b, c) -> a + b + c, "Saami", " Abbas", " Khan")); } public static <T> void usingConsumer(Consumer<T> consumer, T a) { // Method that takes consumer interface will return void. // Can print something constituting 'a' consumer.accept(a); } public static <T, L> void usingBiConsumer(BiConsumer<T, L> biConsumer, T a, L b) { biConsumer.accept(a, b); } public static <T> boolean usingPredicate(Predicate<T> predicate, T a) { return predicate.test(a); } public static <T, L> boolean usingBiPredicate(BiPredicate<T, L> biPredicate, T a, L b) { return biPredicate.test(a, b); } public static <T, R> R usingFunction(Function<T, R> function, T a) { // T for the parameter and R for the return type here the return type could be as same as T or // could be different like if T is Integer the R could be String 8 + "" return function.apply(a); } public static <T, U, R> R usingBiFunction(BiFunction<T, U, R> biFunction, T a, U b) { return biFunction.apply(a, b); } public static <T> T usingUnaryOperator(UnaryOperator<T> unaryOperator, T a) { return unaryOperator.apply(a); } public static <T> T usingBinaryOperator(BinaryOperator<T> binaryOperator, T a, T b) { return binaryOperator.apply(a, b); } public static <T, R> R usingFunctionAsPredicate(Function<T, R> prediFunction, T a) { return prediFunction.apply(a); } public static <T> void printData(Consumer<T> consumer, T a) { /* * Prints the data, (List.of()) using a for loop inside of lambda function. */ consumer.accept(a); } public static String getRandomOne(String[] arr, Supplier<Integer> supplier) { return arr[supplier.get()]; } @FunctionalInterface interface Concat<T> { T concat(T a, T b, T c); } public static <T> T usingCustomFunctionalInterface(Concat<T> concat, T a, T b, T c) { return concat.concat(a, b, c); } }
Functional interfaces in Java are a powerful tool for simplifying code and improving readability. Whether you're processing collections, performing transformations, or handling data flow, these interfaces make it easier to define concise operations.
By understanding and applying functional interfaces like Consumer, Predicate, Function, Supplier, and custom ones, you can take full advantage of Java’s functional programming features.
以上是Default Functional Interfaces in Java的详细内容。更多信息请关注PHP中文网其他相关文章!