22 December 2015

Method Reference =

Method references help to point to methods by their names. A method reference is described using :: (double colon) symbol.

Some times, A lambda expression do nothing but just calls a method which is already defined. To be more lazy to write, You can use method references. Method references are just compact and more readable form of a lambda expression for already written methods.

A method reference can be used to point the following types of methods −

  • Static methods
  • Instance method of a particular object
  • Instance method of an arbitrary object of a particular type
  • Constructors using new operator (TreeSet::new)

Example (as a static method reference)

import java.util.List;
    import java.util.ArrayList;

    public class StaticRef {

        public static void main(String[] args) {
            List vehicles = new ArrayList<>();
            vehicles.add("Car");
            vehicles.add("Bicycle");
            vehicles.add("Scooter");
            vehicles.add("Bus");
            vehicles.add("Train");

            vehicles.forEach(System.out::println);
        }
    }

Output

Car
    Bicycle
    Scooter
    Bus
    Train

Example (as a reference to an instance method of a particular object)

class ComparisonProvider {
        public int compareByBrand(Mobile a, Mobile b) {
            return a.getName().compareTo(b.getName());
        }
            
        public int compareByPrice(Mobile a, Mobile b) {
            return a.getBirthday().compareTo(b.getBirthday());
        }
    }

    ComparisonProvider myComparisonProvider = new ComparisonProvider();
    Arrays.sort(rosterAsArray, myComparisonProvider::compareByBrand);

The method reference myComparisonProvider::compareByBrand invokes the method compareByBrand that is part of the object myComparisonProvider. The JRE infers the method type arguments, which in this case are (Mobile, Mobile).

Example (as a reference to an instance method of an arbitrary object of a particular type)

String[] stringArray = { "Shweta", "Smith", "Abhi", "John", "Siya" };
    Arrays.sort(stringArray, String::compareToIgnoreCase);

The equivalent lambda expression for the method reference String::compareToIgnoreCase would have the formal parameter list (String a, String b), where a and b are arbitrary names used to better describe this example. The method reference would invoke the method a.compareToIgnoreCase(b).

Example (as a constructor)

public class ReferenceToConstructor {
        
        public static void main(String[] args) {
            List  numbers = Arrays.asList(4,9,16,25,36);
            List squaredNumbers = ReferenceToConstructor.findSquareRoot(numbers,Double::new); 
            
            //In lambda List squaredNumbers = ReferenceToConstructor.findSquareRoot(numbers, x -> new Double(x));
            System.out.println("Square root of numbers = "+squaredNumbers);
        }
    
        private static List findSquareRoot(List list, Function<double,double> f){
            List result = new ArrayList();
            list.forEach(x -> result.add(f.apply(Math.sqrt(x))));
            return result;
        }
    }

Example

interface IsReferable {
        public void referenceDemo();
    }
    class ReferenceDemo {
        public static void commonMethod() {
            System.out.println("This method is already defined.");
    }
    public void implement() {
        // Anonymous class.
        IsReferable demoOne = new IsReferable() {
            @Override
            public void referenceDemo() {
                ReferenceDemo.commonMethod();
            }
        };
        demoOne.referenceDemo();
        
        // Lambda implementaion.
            IsReferable demo = () -> ReferenceDemo.commonMethod();
            demo.referenceDemo();
            
        // Method reference.
            IsReferable demoTwo = ReferenceDemo::commonMethod;
            demoTwo.referenceDemo();
    }
    }

Q. When to use method reference.

When a Lambda expression is invoking already defined method, you can replace it with reference to that method.

Q. When you can not use Method reference.

You can not pass arguments to the method reference.

Example, you can not use method reference for following lambda.

IsReferable demo = () -> ReferenceDemo.commonMethod("Argument in method.");

Because Java does not support currying without Wrapper methods or Lambda.



blog comments powered by Disqus