我正在学习Java-8 Lambda,我正在尝试理解java.util.function.Function接口中的addThen默认方法。根据我的理解,addthen将首先执行First函数,然后它将执行第二个方法。 所以我创建了一个如下程序:
//Pojo class
class Bike {
public Bike(String bikeName, int price, String bikeType) {
this.bikeName = bikeName;
this.price = price;
this.bikeType = bikeType;
}
private String bikeType;
private String bikeName;
private int price;
public String getBikeType() {
return bikeType;
}
@Override
public String toString() {
return "Bike [bikeType=" + bikeType + ", bikeName=" + bikeName + ", price=" + price + "]";
}
public void setBikeType(String bikeType) {
this.bikeType = bikeType;
}
public String getBikeName() {
return bikeName;
}
public void setBikeName(String bikeName) {
this.bikeName = bikeName;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
//Main class
public class FunctionInbuildDefaultMethodsExample {
public static void main(String[] args) {
learningAndThen();
}
static void learningAndThen() {
Function<Bike, String> updateBikefunction = (Bike bike) -> {
System.out.println("OldBike Name is::" + bike.getBikeName());
bike.setBikeName("PULSOR-200CC");
return bike.getBikeName();
};
Function<Bike, String> updateBikePriceFunction = (Bike bike) -> {
System.out.println("OldBike Price is::" + bike.getPrice());
bike.setPrice(95000);
return bike.getBikeName();
};
/*
* First update Bike and then price
* */
/*Compilation error here*/
Function<Bike,String> bikeFunction = updateBikefunction.andThen(updateBikePriceFunction);
bikeFunction.apply( new Bike("PULSOR-125CC", 65000, "BAJAJ"));
}
}
我在第
行收到编译错误 Function<Bike,String> bikeFunction =
updateBikefunction.andThen(updateBikePriceFunction);
as
“函数类型中的方法和函数(函数)不适用于参数(函数)”
,在查看了Function接口的源代码之后,我明白了
addThen默认方法正在查找类型Function<String,Book>
的实例。我的问题是,如果addThen
默认方法应该执行第一个函数,然后是作为参数传递的下一个函数,为什么函数接口的addThen
默认方法以除了实例之外的方式编写类型为Function<String,Book>
。
答案 0 :(得分:4)
andThen
已应用于Function
的结果。所以这可以作为例子:
Function<Bike, String> bikeFunction = updateBikefunction
.andThen(s -> s.toUpperCase());
由于结果是String
的{{1}}。
答案 1 :(得分:3)
andThen
的{{1}}方法用作函数之间的管道。
您的Function
都会被Function
收入并返回Bike
,这就是问题所在。
当您调用String
,其中两者具有相同的[function1].andThen[function2]
参数化时,<Bike, String>
期待[function2]
,但从{{1}接收Bike
}}。
请参阅docs(我的粗体):
返回首先将此函数应用于其输入的组合函数,然后将after函数应用于结果。如果对任一函数的求值抛出异常,则将其转发给组合函数的调用者。
答案 2 :(得分:3)
Camera.Parameters parameters=mcamera.getParameters();
parameters.setRotation(90); //use 90, 180, 270
mCamera.setParameters(parameters);
要形成一系列函数,前一个结果应该是下一个函数的输出。这是这个条件被打破了。
mCamera.setParameters(mCamera.getParameters.setRotation(90));
可以更改为updateBikefunction = Bike -> String
updateBikePriceFunction = Bike -> String
updateBikefunction -> updateBikePriceFunction = Bike -> String -> Bike -> String
^^^^^^^^^^^^^^
updateBikefunction
编译该行:
Function<Bike, Bike>
答案 3 :(得分:3)
这很简单。函数不输出(Bike, String)
之类的元组,它有一个输入Bike
和一个输出String
。
如果你现在编写函数,那么第二个函数需要使用输出作为输入,如:
Function1: A -> B
Function2: B -> C
Composed: A (-> B) -> C
您的功能都是
updateBikefunction: Bike -> String
updateBikePriceFunction: Bike -> String
但编译器希望updateBikePriceFunction
使用updateBikefunction
的输出作为输入,因此它希望它看起来像:
updateBikePriceFunction: String -> ...
您还可以在documentation:
中清楚地看到这一点
Interface Function<T,R>
andThen(Function<? super R,? extends V> after)
因此,调用该方法的对象输入T
并输出R
。您需要用作参数的函数输入? super R
并输出? extends V
。
如果要链接操作方法,则应使用Bike -> Bike
并为getBikeNameFunction
之类的最终结果创建自己的方法,然后返回名字:
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();
};
您现在可以这样使用它:
Function<Bike, String> bikeFunction = updateBikefunction
.andThen(updateBikePriceFunction)
.andThen(getBikeNameFunction);
或者只是使用对方法的引用,如:
Function<Bike, String> bikeFunction = updateBikefunction
.andThen(updateBikePriceFunction)
.andThen(Bike::getName);