Description
It is pretty simple. The function does not output tuples of type (Bike, String) ; it has Bike input and String output.
If you are now composing functions, the second function should use this output as its input , for example:
Function1: A -> B Function2: B -> C Composed: A (-> B) -> C
Your functions are
updateBikefunction: Bike -> String updateBikePriceFunction: Bike -> String
however, the compiler expects updateBikePriceFunction to use the output of updateBikefunction as its input, so it wants it to look like this:
updateBikePriceFunction: String -> ...
You can also see this in the documentation :
Interface Function<T,R>
andThen(Function<? super R,? extends V> after)
So, the object you are calling the method on has input T and outputs R Does the function you should use as an argument have an input ? super R ? super R and outputs ? extends V ? extends V
How to fix
If you want to bind manipulation methods, you should use Bike -> Bike and create your own method for final results like getBikeNameFunction , which then returns the name:
Function<Bike, Bike> updateBikefunction = (Bike bike) -> { System.out.println("OldBike Name is::" + bike.getBikeName()); bike.setBikeName("PULSOR-200CC"); return bike; }; Function<Bike, Bike> updateBikePriceFunction = (Bike bike) -> { System.out.println("OldBike Price is::" + bike.getPrice()); bike.setPrice(95000); return bike; }; Function<Bike, String> getBikeNameFunction = (Bike bike) -> { return bike.getBikeName(); };
Now you can use it as follows:
Function<Bike, String> bikeFunction = updateBikefunction .andThen(updateBikePriceFunction) .andThen(getBikeNameFunction);
Or just use the method reference, for example:
Function<Bike, String> bikeFunction = updateBikefunction .andThen(updateBikePriceFunction) .andThen(Bike::getName);