I am trying to learn lambda expressions. I am currently referring to OCP study guide.
In one example of lambda expression there is a Animal class and another another interface called CheckTrait. The functioning of lambda expression is very confusing for me. Example code is as shown below:
Without lambda expression.
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);
}
}
When we run the above class we get the output as Kangaroo can hop
With lambda expression
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());
}
}
My Question is, In the below line
print(animal2,s->s.canHop());
I am not passing any value to s but just an expression, then how is the program computing the result? I am aware that it is taking the animal object and checking the canhop variable just by intuition,but I am not understanding the logic here. Kindly provide your thoughts.
Edit: based on Aominè’s answer:
So, can i conclude that.
In the print method I am passing the behavior for CheckTrait, and in the print method can be reduced as:
step1: if(trait.test(animal)){
step2: if(s.canHop())
step3: if(animal.canHop)
the above steps are just for my understanding.
Solution:
I am not passing any value to s but just an expression, then how is
the program computing the result?
below you pass in a behaviour (a function) as the second argument to the print method which will be used within the print method.
print(animal2, s -> s.canHop());
this function reads as “given an element say s, call the canHop() method on the element”
now within the print method when you do:
if(trait.test(animal)){ ... }
you’re calling trait.test(animal) and passing the animal object to the function we passed in, we then apply the function to the input animal.
if it helps this:
print(animal2,s -> s.canHop());
can be seen as being the same as:
print(animal2, new CheckTrait() {
@Override
public boolean test(Animal s) {
return s.canHop();
}
});
edit:
as you’ve mentioned the method calls can be seen as:
if(trait.test(animal)){..} -> if(s.canHop()){..} -> if(animal.canHop){..} // pseudocode