Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 chained method reference?

Suppose there is a typical Java Bean:

class MyBean {     void setA(String id) {     }      void setB(String id) {      }      List<String> getList() {     } } 

And I would like to create a more abstract way of calling the setters with the help of a BiConsumer:

Map<SomeEnum, BiConsumer<MyBean, String>> map = ... map.put(SomeEnum.A, MyBean::setA); map.put(SomeEnum.B, MyBean::setB); map.put(SomeEnum.List, (myBean, id) -> myBean.getList().add(id)); 

Is there a way to replace the lambda (myBean, id) -> myBean.getList().add(id) with a chained method reference, something like (myBean.getList())::add or myBean::getList::add or something else?

like image 679
Random42 Avatar asked Mar 19 '15 13:03

Random42


People also ask

What is Java 8 method reference?

Java provides a new feature called method reference in Java 8. Method reference is used to refer method of functional interface. It is compact and easy form of lambda expression. Each time when you are using lambda expression to just referring a method, you can replace your lambda expression with method reference.

Can you chain methods in Java?

In Java, method chaining is the chain of methods being called one after another. It is the same as constructor chaining but the only difference is of method and constructor.

What is function chaining in Java 8?

Function in Java 8A Function is a functional interface (has a single abstract method called accept) that accepts one argument and produces a result. Example: We can create a stream of integers, map each integer element to double (2x) of its value, and collect the result as a list.

Is it possible to invoke chained methods in Java if so how will you invoke?

Method chaining in Java is a common syntax to invoke multiple methods calls in OOPs. Each method in chaining returns an object. It violates the need for intermediate variables.


1 Answers

No, method references do not support chaining. In your example it wouldn’t be clear which of the two methods ought to receive the second parameter.


But if you insist on it…

static <V,T,U> BiConsumer<V,U> filterFirstArg(BiConsumer<T,U> c, Function<V,T> f) {     return (t,u)->c.accept(f.apply(t), u); } 

BiConsumer<MyBean, String> c = filterFirstArg(List::add, MyBean::getList); 

The naming of the method suggest to view it as taking an existing BiConsumer (here, List.add) and prepend a function (here, MyBean.getList()) to its first argument. It’s easy to imagine how an equivalent utility method for filtering the second argument or both at once may look like.

However, it’s mainly useful for combining existing implementations with another operation. In your specific example, the use site is not better than the ordinary lambda expression

BiConsumer<MyBean, String> c = (myBean, id) -> myBean.getList().add(id); 
like image 187
Holger Avatar answered Sep 18 '22 17:09

Holger