我正在尝试学习lambda表达式。我目前指的是OCP学习指南。
在lambda表达式的一个示例中,有一个Animal类和另一个名为CheckTrait的接口。 lambda表达式的功能对我来说非常混乱。示例代码如下所示:
没有lambda表达。
public interface CheckTrait {
public boolean test(Animal a);
}
public class Animal implements CheckTrait{
private String species;
private boolean canHop;
private boolean canSwim;
public Animal(String species, boolean canHop, boolean canSwim) {
super();
this.species = species;
this.canHop = canHop;
this.canSwim = canSwim;
}
public boolean canHop() {
return this.canHop;
}
public String toString() {
return species;
}
public boolean canSwim() {
return this.canSwim;
}
@Override
public boolean test(Animal a) {
return a.canHop();
}
}
public class FindMathcingAnimals {
private static void print(Animal animal, CheckTrait trait) {
if(trait.test(animal)){
System.out.println(animal+" can hop" );
}else {
System.out.println(animal+" cannot hop");
}
}
public static void main(String[] args) {
Animal animal2= new Animal("Kangaroo", true, false);
print(animal2,animal2);
}
}
当我们运行上面的类时,我们得到输出为袋鼠可以跳
使用lambda表达式
public interface CheckTrait {
public boolean test(Animal a);
}
public class Animal {
private String species;
private boolean canHop;
private boolean canSwim;
public Animal(String species, boolean canHop, boolean canSwim) {
super();
this.species = species;
this.canHop = canHop;
this.canSwim = canSwim;
}
public boolean canHop() {
return this.canHop;
}
public String toString() {
return species;
}
public boolean canSwim() {
return this.canSwim;
}
}
public class FindMathcingAnimals {
private static void print(Animal animal, CheckTrait trait) {
if(trait.test(animal)){
System.out.println(animal+" can hop" );
}else {
System.out.println(animal+" cannot hop");
}
}
public static void main(String[] args) {
Animal animal2= new Animal("Kangaroo", true, false);
print(animal2,s->s.canHop());
}
}
我的问题是,在下面这行 打印(animal2,仲 - > s.canHop());
我没有将任何值传递给s而只是表达式,那么程序如何计算结果呢?我知道它只是通过直觉获取动物对象和检查canhop变量,但我不理解这里的逻辑。请提供你的想法。
编辑:根据Aominè的回答:
那么,我能否得出结论。 在print方法中,我传递了CheckTrait的行为,并且在print方法中可以缩小为:
step1:if(trait.test(animal)){
第二步:if(s.canHop())
第3步:if(animal.canHop)
以上步骤仅供我理解。
答案 0 :(得分:3)
我没有将任何值传递给s而只是表达式,那是怎么回事 计算结果的程序?
下面你传递一个行为(一个函数)作为print方法的第二个参数,它将在print方法中使用。
print(animal2, s -> s.canHop());
此函数显示为"如果元素为s
,则在元素上调用canHop()
方法"
现在在打印方法中执行:
if(trait.test(animal)){ ... }
您正在调用trait.test(animal)
并将动物对象传递给我们传入的函数,然后我们将该函数应用于输入动物。
如果它有帮助:
print(animal2,s -> s.canHop());
可以看作是:
print(animal2, new CheckTrait() {
@Override
public boolean test(Animal s) {
return s.canHop();
}
});
修改强>
正如您所提到的,方法调用可以看作:
if(trait.test(animal)){..} -> if(s.canHop()){..} -> if(animal.canHop){..} // pseudocode
答案 1 :(得分:0)
lambda表达式只是一个函数。
表格
s -> s.canHop()
指定接收单个参数的函数,并在该参数上调用canHop
函数。
由于print
期望CheckTrait
,编译器知道参数的类型为Animal
。
答案 2 :(得分:0)
我假设你不熟悉函数式编程,所以你可以这样看 - lambda就像一个缩写。基本上,CheckTrait
是一个类,它包含一个方法,该方法接受Animal
并返回一个布尔值,指示它是否具有cerain属性。它不会执行任何外部操作或更改任何值或任何内容,它只是从另一个(Animal)计算一个值(布尔值)。从最纯粹的意义上讲,这是一种功能。
在旧版本的Java中,要创建表示CheckTrait
函数的对象,您必须这样做
CheckTrait canHop = new CheckTrait() {
public boolean test(Animal a) {
return a.canHop();
}
}
Animal a = ...;
canHop.test(a);
这需要输入很多内容,特别是因为这里唯一重要的细节是输入参数(Animal a
)和输出函数(return a.canHop()
)。因此,Java从函数式编程语言中借用了一种语法,您可以在其中指定这两个元素,省去所有噪声,并自动转换为上面的代码。
CheckTrait canHop = (Animal a) -> { return a.canHop(); }
Animal a = ...;
canHop.test(a);
这仅适用于具有单个方法的接口。更好的是,如果编译器可以猜测输入类型,并且函数只包含一个return语句,那么它们可以省略类型,甚至可以省略return
关键字。
CheckTrait canHop = a -> a.canHop();
Animal a = ...;
canHop.test(a);
这就是lambda的工作方式。它们基本上是匿名类的缩写形式。
TLDR; <{1}}是
的缩写print(animal2,s->s.canHop())