3

I am learning Java predicates and struck here on basic code. Below is my code.

package TestLambda;

public class Animal {
    private String species;
    private boolean canHop;
    private boolean canSwim;

    public Animal(String species,boolean canHop,boolean canSwim){
        this.species = species;
        this.canHop = canHop;
        this.canSwim = canSwim;
    }

    public boolean canHop(){return canHop;}
    public boolean canSwim(){return canSwim;}
    public String toString(){return species;}

Below is my interface.

package TestLambda;

@FunctionalInterface
public interface CheckTrait {
    boolean Test(Animal a);
}

Implementing the interface.

package TestLambda;

public class CheckIfHopper implements CheckTrait {
    public boolean Test(Animal a){
        return a.canHop();
    }
}

Now i am testing a simple Lambda.

package TestLambda;

import java.util.ArrayList;
import java.util.List;

public class LambdaSearch {

    public static void main(String[] args) {
        List<Animal> animals = new ArrayList<>();
        animals.add(new Animal("fish",false,true));
        animals.add(new Animal("dog",true,true));
        animals.add(new Animal("rabbit",true,false));
        animals.add(new Animal("horse",true,false));

        print(animals, a -> a.canHop());
    }

    public static void print(List<Animal> animals,CheckIfHopper checkIfHopper){
        for(Animal animal :animals){
            if(checkIfHopper.Test(animal)){
                System.out.println(animal + " ");
            }
        }
    }

}

Mycode is throwing error:- TestLambda.CheckIfHopper is not a functional interface

What i am doing wrong please?

Gaurav
  • 61
  • 1
  • 1
  • 6

3 Answers3

2

If your purpose is to test lambda expressions, then CheckIfHopper is redundant here.

Your print method would take a CheckTrait parameter:

public static void print(List<Animal> animals, CheckTrait checkIfHopper){
    for(Animal animal :animals){
        if(checkIfHopper.Test(animal)){
            System.out.println(animal + " ");
        }
    }
}

And the call would be:

print(animals, a -> a.canHop());

Or the following for brevity:

print(animals, Animal::canHop);

You can't make a lambda expression to provide an instance of a class, its target type must be a functional interface (this is essentially what the error message is saying)

You don't need the CheckIfHopper class, because a -> a.canHop() or Animal::canHop provide an implementation of CheckTrait without a class declaration (that's the point of lambda expressions, isn't it...)

ernest_k
  • 44,416
  • 5
  • 53
  • 99
2
public static void print(List<Animal> animals, CheckIfHopper checkIfHopper);

CheckIfHopper is a class not a functional interface, you should use CheckTrait instead.

user12047085
  • 162
  • 1
  • 12
0

If you are exploring lambda with predicates, study filter in streams api. For example instead of writing the print function above, you can write the code like the one below.

animals.stream()
       .filter(Animal::canHop)
       .foreach(System.out::println);

Also you can check this link: https://www.journaldev.com/17072/java-predicate

Nishant Lakhara
  • 2,295
  • 4
  • 23
  • 46