java8 method reference

In java we can use object reference by creating new object

    List<String> list = new ArrayList<>();
    store(list);

So what about the method, if we want to use the method of the object in another method, then we have to pass the object into this method. Consider the following, would it be better for us to pass the behavior of the method as a parameter. In java8, lambda expressions can do this easily, the syntax for method reference is Object::methodName.

    Consumer<String> c = s -> System.out.println(s);
    
    为了使代码更清晰,可以将lambda表达式转换为方法引用。
    
    Consumer<String> c = System.out :: println;

In a method reference, place the object (or class) containing the method before the :: operator and after the name of the method where it has no parameters. First, method references cannot be used in any method. It can only be used to replace a lambda expression for a single method. To use a lambda expression, you must first have a
functional interface, that is, a functional interface with only one abstract method.

Several types of method references
  • 1 A method reference to a static method.
  • 2 A method reference to an example method of an object of a particular type.
  • 3 A method reference to an existing object instance method.
  • 4 Method references to constructors.
Method reference for static method
    (args)-> Class.staticMethod(args);
     Class :: staticMethod;
 

We use the method reference notation :: instead of . , and don't pass parameters to method references, normally we don't have to pass parameters to method references. But the parameters depend on the type of the method reference.
In this case, any arguments the method takes (if any) are automatically passed to the back. Please see the example below

    public static boolean isMoreThanFifty(int n1, int n2) {
        return (n1 + n2) > 50;
    }
    
    public static List<Integer> findNumbers(List<Integer> l, BiPredicate<Integer, Integer> p) {
        
        return l.stream()
                .filter(i -> p.test(i, i + 10))
                .collect(Collectors.toList());
    }

    /*
     * 使用匿名内部类实现
     */
    String s1 = findNumbers(list, new BiPredicate<Integer, Integer>() {

        @Override
        public boolean test(Integer t, Integer u) {
            
            return (t + u) > 50;
        }
    }).toString();
    System.out.println("s1 : " + s1);
    
    /**
     * 使用lambda表达式
     */
    String s2 = findNumbers(list, (i1, i2) -> Numbers.isMoreThanFifty(i1, i2)).toString();
    System.out.println("s2 : " + s2);
    /**
     * 使用方法引用
     */
    String s3 = findNumbers(list, Numbers :: isMoreThanFifty).toString();
    System.out.println("s3 : " + s3);

    //console log
    s1 : [45, 33, 24, 40]
    s2 : [45, 33, 24, 40]
    s3 : [45, 33, 24, 40]
a method reference to an example method of an object of a particular type

We have the following lambda expression

    (obj, args) -> obj.instanceMethod(args)
    

If an instance of an object is passed and one of its methods is executed with some optional parameters, this can be translated into the following method reference.

    ObjectType::instanceMethod
    
    public double calculateWeight() {
        double weight = 0;
        // Calculate weight
        return weight;
    }
    
    public void test() {
        List<Shipment> l = new ArrayList<Shipment>();

        // Using an anonymous class
        calculateOnShipments(l, new Function<Shipment, Double>() {
          public Double apply(Shipment s) { // The object
            return s.calculateWeight(); // The method
          }
        });

        // Using a lambda expression
        calculateOnShipments(l, s -> s.calculateWeight());

        // Using a method reference
        calculateOnShipments(l, Shipment::calculateWeight);
    }
    
a method reference to an existing object instance method
    public class Car {
        private String id;
        private String color;
    }
    
    public void execute(Car car, Consumer<Car> c) {
        c.accept(car);
    }
    
    execute(car, mechanic::fix);
method reference to constructor
    Supplier<List<String>> supplier = new Supplier<List<String>>() {

        @Override
        public List<String> get() {
            return new ArrayList<String>();
        }
    };
    
    Supplier<List<String>> supplier2 = () -> new ArrayList<String>();
    
    Supplier<List<String>> supplier3 = ArrayList::new;
    
    /*
     * 如果构造函数有一个参数,可以使用Function接口。构造函数是两个参数的,可以使用BiFunction,如果是三个参数的话,则不得不创建以自己的函数接口了。
     */
    Function<String, Integer> function = Integer::new;
    
    BiFunction<String, String, Locale> biFunction = new BiFunction<String, String, Locale>() {

        @Override
        public Locale apply(String t, String u) {
            return new Locale(u, t);
        }
    };
    
    biFunction = (lang, country) -> new Locale(lang, country);
    
    biFunction = Locale::new;
    
concluding remarks

Using method references in programming, lambdas can be optimized, and the code is more concise and expressive. The code referenced above can be downloaded on GitHub

java8 method reference
why the perfect lambda expression is only one line
java8 functional programming

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325362475&siteId=291194637