Exploring Java 8/4 : Method & Constructor Reference in Java 8
Hello there techie ninjas, I hope you are doing well. Welcome to Programming 4 Ninja and another blog on Method Reference & Constructor Reference in the Exploring Java 8 Series. Let's get started with the content then.
What is the Method Reference in Java 8?
Method Reference is another way of writing concise lambda of one line, in case your lambda is just calling a function on an object, or a static function on class.
let's take the example of the below lambda
1import java.util.function.Consumer;
2
3public class Example {
4
5 public void printStringInUpperCase(String str) {
6 System.out.println(str.toUpperCase());
7 }
8
9 public static void main(String args[]) {
10 Example example = new Example();
11 Consumer<String> uppercaseConverterAndPrinter =
12 (str) -> example.printStringInUpperCase(str);
13 uppercaseConverterAndPrinter.accept("hello world !");
14 }
15}
In the above code block, the line number 11,12 can be written more concisely like below,
1Consumer<String> uppercaseConverterAndPrinter =
2 example::printStringInUpperCase;
This type of declaration is called a method reference. Syntax of method reference is
1objeOfClass::methodWhichCanSatisfyInterfaceContract;
2className::staticMethodWhichCanSatisfyInterface;
So In the above example, we have used the Consumer interface, And you might be aware from the learning of the previous Blog,
Exploring Java 8: Functional Interface that the consumer interface accepts a parameter of type T and won't return anything.
Here in the above example, it satisfies the contract, then function for which we have created a method reference "printStringInUpperCase",
it accepts a parameter of type String and does not return anything.
Some more example around the Method Reference & Static Method Reference
1import java.util.Arrays;
2import java.util.List;
3import java.util.function.Consumer;
4
5public class ConsumerMethodReferenceExample {
6
7 public static void stringConsumerStaticMethod(String str) {
8 System.out.println(str);
9 }
10
11 public void stringConsumerInstanceMethod(String str) {
12 System.out.println(str);
13 }
14
15 public static void main(String[] args) {
16
17 ConsumerMethodReferenceExample instance = new ConsumerMethodReferenceExample();
18 Consumer<String> stringConsumerLambda = (str) -> ConsumerMethodReferenceExample.stringConsumerStaticMethod(str);
19 Consumer<String> stringConsumerMethodReference = ConsumerMethodReferenceExample::stringConsumerStaticMethod;
20 Consumer<String> stringConsumerMethodReferenceWithObject = instance::stringConsumerInstanceMethod;
21 Consumer<String> stringConsumerMethodReferenceWithCleanerCode = System.out::println;
22
23 stringConsumerLambda.accept("ABC");
24 stringConsumerMethodReference.accept("ABC");
25 stringConsumerMethodReferenceWithObject.accept("ABC");
26 stringConsumerMethodReferenceWithCleanerCode.accept("ABC");
27
28 List<String> listOfString = Arrays.asList("Apple", "Banana", "Cat", "Dog");
29 System.out.println("Lambda Way");
30 listOfString.forEach((str) -> ConsumerMethodReferenceExample.stringConsumerStaticMethod(str));
31
32 System.out.println("Method Reference Way");
33 listOfString.forEach(ConsumerMethodReferenceExample::stringConsumerStaticMethod);
34 listOfString.forEach(instance::stringConsumerInstanceMethod);
35
36 System.out.println("Method Reference Way more cleaner");
37 listOfString.forEach(System.out::println);
38 }
39}
In the example we have seen method reference for static and non static function for consumer functional interfaces, Lets have a look at method reference for other type of functional interfaces.
1import java.util.Arrays;
2import java.util.List;
3import java.util.function.Consumer;
4import java.util.function.Function;
5import java.util.function.Predicate;
6import java.util.function.Supplier;
7import java.util.stream.Collectors;
8
9public class MethodReferenceWithFunctionalInterfaces {
10 public static void main(String args[]) {
11 MethodReferenceWithFunctionalInterfaces object = new MethodReferenceWithFunctionalInterfaces();
12
13 Consumer<String> someConsumer = object::consumerKindOfMethod;
14 someConsumer.accept("xyz");
15
16 Supplier<Double> someSupplier = object::supplierKindOfMethod;
17 System.out.println(someSupplier.get());
18
19 Predicate<Integer> somePredicate = object::isEvenNumber;
20 System.out.println(somePredicate.test(126) ? "Even" : "Odd");
21
22 Function<List<String>, String> concatString = object::join;
23 System.out.println(concatString.apply(Arrays.asList("I", "Am", "Java", "Ninja")));
24 }
25
26 // consumer sort of functional interfaces
27 public void consumerKindOfMethod(String str) {
28 System.out.println(str);
29 }
30
31 // supplier sort of functional interface
32 public Double supplierKindOfMethod() {
33 return Math.random();
34 }
35
36 // you can use predicate interfaces for this
37 public boolean isEvenNumber(Integer number) {
38 return number % 2 == 0;
39 }
40
41 //you cabn function functional interface for this
42 public String join(List<String> list) {
43 return list.stream().collect(Collectors.joining(" "));
44 }
45}
I hope you have learned the method reference in java 8. In short, it is just concise ways of implementation of functional interfaces. Lambda would be little longer way of writing it. but with method reference it is more concise, more readable and more short.
Let's Start with Constructor Reference Now
Constructor reference is also similar to the method reference we have seen earlier. There is one difference, constructor reference will always be of type Function Functional interface. it would accept a parameter to pass in the constructor and will always return the object of a class. Java has a Functional and BiFunction functional interface available in java.lang.function package. Function for single parameter input, BiFunction is for two input parameter for a constructor.
Let's look at the below example which shows how you can code for Constructor reference
1import java.util.Arrays;
2import java.util.List;
3import java.util.function.Function;
4import java.util.stream.Collectors;
5
6class Things {
7 private String name;
8
9 public Things(String name) {
10 this.name = name;
11 }
12}
13
14public class ConstructorReferenceExample {
15 public static void main(String args[]) {
16 Function<String, Things> function = Things::new;
17 Things apple = function.apply("Apple");
18
19 /* Some real industry example about the constructor reference*/
20 List<String> thingsString = Arrays.asList("Apple", "Ball", "Cat", "Dog", "Egg");
21
22 List<Things> listOfThings = thingsString
23 .stream()
24 .map(Things::new) // accept a string and return object of class Things
25 .collect(Collectors.toList());
26 }
27}
I hope you have understood the concept behind method reference and constructor reference introduced in java 8. The basic intention behind the method reference is to make your code concise, readable and allows you to pass a function as a parameter that can be invoked later point in time based on your logic. it will allow you to build a code in a callback fashion, where you will declare your function, but it would be invoked far below in the call stack.
That's all for this blog ninjas. Let me know if you have any question, feedback, suggestion. I will always try to improve my blogs and will be happy to help you.
Till then Goodbye, Happy Coding !!!
<< Chapter 3 : Functional Interfaces | Chapter 5 : Introduction to Streams API >>
comments powered by Disqus