Suppose in real-time example, I have two object User and Address that is given below:
public User{
private Address address;
// setter, Getter
}
public Address{
private String country;
// setter, Getter
}
I want to find country from user so I can simply use
user.getAddress().getCountry();
to get address with the help of method reference, It can be used like
User::getAddress
but I have to find out the country name and I want to use in method reference way so how can I do?
CodePudding user response:
No, method references don't allow that kind of composition. Simplest is to add a getCountry()
method to User
which delegates to Address
, and you'll be able to refer to User::getAddress
.
CodePudding user response:
You can write a utility function to compose two method references:
public class Foo {
static class AClass {
private final BClass b = new BClass();
public BClass getB() {
return b;
}
}
static class BClass {
public String getFoo() {
return "foo";
}
}
static <A,B,C> Function<A,C> compose(Function<A,B> ab, Function<B,C> bc) {
return ab.andThen(bc);
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
System.out.println(Optional.of(new AClass()).map(AClass::getB).map(BClass::getFoo));
System.out.println(Optional.of(new AClass()).map(compose(AClass::getB, BClass::getFoo)));
}
}
CodePudding user response:
You cannot directly refer to getCountry () via User, but you can use stream to map to addresses and then reference getCountry (). However, you should specify in what situation you want to use.
but e.g if you have a user list, you can do this:
List <User> users = List.of(
user,
user1);
users.stream()
.map(User::getAddress)
.map(Address::getCountry)
.forEach(System.out::println)
CodePudding user response:
A simple way to compose multiple chained functions is to assign the first method reference to a local variable and apply .andThen(Other::ref)
:
Function<User, Address> user2Address = User::getAddress;
Function<User, String> user2Country = user2Address.andThen(Address::getCountry);
You can chain as many .andThen(Other::ref)
as you need to reach the target mapping and use the combined function as one step in say 'stream.map` operations.
List.of(user1, user2,user3).stream()
.map(user2Country)
.forEach(System.out::println);