Search code examples
javaconsumerfunctional-interface

When I try to remove a value from my list using BiCionsumer, it does not work


I have the following problem:

Goal: Remove from list the animal with "danger" == true;

Restraints: One of the functional interfaces (Consumer, Predicate, Function or Supplier) must be used (I chose BiConsumer because of the index);

Issue: BiConsumer is not updating the passed list (No error is displayed);

Attempts: I have also tried having a list inside removeDangerousAnimal, so that I could then do something like:

static List<Animal> removeDangerousAnimal(List<Animal> listOfAnimals) {
        List<Animal> newList = new Arraylist<>();
 
        BiConsumer<Boolean, Integer> removeDangerous = (isDangerous, index) -> {
            if(isDangerous == true){
                System.out.println("Dangerous animal: " + listOfAnimals.get(index).getName());
                listOfAnimals.remove(index);
                newList = listOfAnimals;
            }
        };

But I have learned that with lambdas local variables are immutable (Error: "Variable used in lambda expression should be final or effectively final").

Question: I do not understand why BiConsumer is not updating my list.

Main:

public class Main {
    public static void main(String[] args) {
        List<Animal> animals = new ArrayList<>();

        Dog dog = new Dog("Tom", "He's a good boy", "Chihuahua", 10, 0.30, false, "Dry food", 0.20);
        Cat cat = new Cat("Misty", "She has a temper!", "Tigress", 6, 0.40, true, "Soggy food", 0.5);
        Bird bird = new Bird("Twitty", "He's very cute!", "Parrot", 1.5, 0.15, false, "Dry food", 0.10);

        animals.add(dog);
        animals.add(cat);
        animals.add(bird);

        animals = removeDangerousAnimal(animals);

        for (Animal a: animals) {
            System.out.println("Animal name: " + a.getName());
        }
    }

    static List<Animal> removeDangerousAnimal(List<Animal> listOfAnimals){

        BiConsumer<Boolean, Integer> removeDangerous = (isDangerous, index) -> {
            if(isDangerous == true){
                System.out.println("Dangerous animal: " + listOfAnimals.get(index).getName());
                listOfAnimals.remove(index);
            }
        };

        for (int i = 0; i < listOfAnimals.size(); i++) {
            //System.out.println("Animal name: " + a.getName() + " " + a.isDanger());
            removeDangerous.accept(listOfAnimals.get(i).isDanger(), i);
        }

        return listOfAnimals;
    }
}

Animal:

public class Animal {

    private String name;
    private String description;
    private String race;
    private double weight;
    private double height;
    private boolean danger;
    private String food;
    private double foodQuantity;

    //---------------------------


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getRace() {
        return race;
    }

    public void setRace(String race) {
        this.race = race;
    }

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public boolean isDanger() {
        return danger;
    }

    public void setDanger(boolean danger) {
        this.danger = danger;
    }

    public String getFood() {
        return food;
    }

    public void setFood(String food) {
        this.food = food;
    }

    public double getFoodQuantity() {
        return foodQuantity;
    }

    public void setFoodQuantity(double foodQuantity) {
        this.foodQuantity = foodQuantity;
    }
}

Dog:

public class Dog extends Animal {
    private String name;
    private String description;
    private String race;
    private double weight;
    private double height;
    private boolean danger;
    private String food;
    private double foodQuantity;

    //---------------------------

    public Dog(String name, String description, String race, double weight, double height, boolean danger, String food, double foodQuantity) {
        this.name = name;
        this.description = description;
        this.race = race;
        this.weight = weight;
        this.height = height;
        this.danger = danger;
        this.food = food;
        this.foodQuantity = foodQuantity;
    }

    public Dog() {

    }
    //---------------------------

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getRace() {
        return race;
    }

    public void setRace(String race) {
        this.race = race;
    }

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public boolean isDanger() {
        return danger;
    }

    public void setDanger(boolean danger) {
        this.danger = danger;
    }

    public String getFood() {
        return food;
    }

    public void setFood(String food) {
        this.food = food;
    }

    public double getFoodQuantity() {
        return foodQuantity;
    }

    public void setFoodQuantity(double foodQuantity) {
        this.foodQuantity = foodQuantity;
    }
}

Cat:

public class Cat extends Animal {

    private String name;
    private String description;
    private String race;
    private double weight;
    private double height;
    private boolean danger;
    private String food;
    private double foodQuantity;

    //---------------------------

    public Cat(String name, String description, String race, double weight, double height, boolean danger, String food, double foodQuantity) {
        this.name = name;
        this.description = description;
        this.race = race;
        this.weight = weight;
        this.height = height;
        this.danger = danger;
        this.food = food;
        this.foodQuantity = foodQuantity;
    }

    public Cat() {

    }

    //---------------------------

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getRace() {
        return race;
    }

    public void setRace(String race) {
        this.race = race;
    }

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public boolean isDanger() {
        return danger;
    }

    public void setDanger(boolean danger) {
        this.danger = danger;
    }

    public String getFood() {
        return food;
    }

    public void setFood(String food) {
        this.food = food;
    }

    public double getFoodQuantity() {
        return foodQuantity;
    }

    public void setFoodQuantity(double foodQuantity) {
        this.foodQuantity = foodQuantity;
    }
}

Bird:

public class Bird extends Animal {

    private String name;
    private String description;
    private String race;
    private double weight;
    private double height;
    private boolean danger;
    private String food;
    private double foodQuantity;

    //---------------------------

    public Bird(String name, String description, String race, double weight, double height, boolean danger, String food, double foodQuantity) {
        this.name = name;
        this.description = description;
        this.race = race;
        this.weight = weight;
        this.height = height;
        this.danger = danger;
        this.food = food;
        this.foodQuantity = foodQuantity;
    }

    public Bird() {

    }

    //---------------------------

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getRace() {
        return race;
    }

    public void setRace(String race) {
        this.race = race;
    }

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public boolean isDanger() {
        return danger;
    }

    public void setDanger(boolean danger) {
        this.danger = danger;
    }

    public String getFood() {
        return food;
    }

    public void setFood(String food) {
        this.food = food;
    }

    public double getFoodQuantity() {
        return foodQuantity;
    }

    public void setFoodQuantity(double foodQuantity) {
        this.foodQuantity = foodQuantity;
    }
}

Solution

  • This may be missing the point of the question, but you could use removeIf and pass a Predicate that's based on the isDanger property:

    animals.removeIf(Animal::isDanger)