简体   繁体   中英

Java Error: incompatible types: no instance(s) of type variable(s) R exist so that Stream<R> conforms to boolean

I am new to coding and I am getting an error in a java program that I have no idea how to solve. The code is meant to find the average time of cooking for a vegetarian recipe. As you can see below I tried putting a lambda expression inside the isVegetarian( ) method and I cant seem to figure out the problem. Thanks in advance.

Here is the program:

public enum Ingredient
{
BEEF, HAM, APPLES, PEAS, CARROTS;
}
   import java.util.ArrayList; 

public class Recipe
{
    public String name;
    public int time;
    public ArrayList<Ingredient> ingredient;
    public boolean meatveg;


    public int getTime( )
    {
        return time;
    }
    public boolean isVegetarian( )
    {
        meatveg = ingredient.stream( )
                    .filter((theingredients) -> !( theingredients == Ingredient.BEEF || theingredients == Ingredient.HAM ))
                    .map((theingredients) -> true );
        return meatveg;
    }

    public Recipe( String name, ArrayList<Ingredient> ingredient, int time )
    {
        this.name = name;
        this.ingredient = ingredient;
        this.time = time;

    }
}
import java.util.ArrayList;

public class Recipes {

  public static void main(String[] args) {
    ArrayList<Recipe> recipes = new ArrayList<>();


    fillTheList(recipes);

    int total = recipes.stream()
        .filter((recipe) -> recipe.isVegetarian())
        .map((recipe) -> recipe.getTime())
        .reduce(0, (time1, time2) -> time1 + time2);

    int count = recipes.stream()
        .filter((recipe) -> recipe.isVegetarian())
        .map((recipe) -> 1)
        .reduce(0, (value1, value2) -> value1 + value2);

    System.out.println(total / (double) count);
  }


  static void fillTheList(ArrayList recipes) {
    ArrayList<Ingredient> ingredients = new ArrayList<>();
    ingredients.add(Ingredient.BEEF);
    ingredients.add(Ingredient.HAM);
    ingredients.add(Ingredient.APPLES);
    recipes.add(new Recipe("Recipe 1", ingredients, 400));

    ingredients = new ArrayList<>();
    ingredients.add(Ingredient.PEAS);
    ingredients.add(Ingredient.CARROTS);
    recipes.add(new Recipe("Recipe 2", ingredients, 200));

    ingredients = new ArrayList<>();
    ingredients.add(Ingredient.PEAS);
    ingredients.add(Ingredient.APPLES);
    recipes.add(new Recipe("Recipe 3", ingredients, 300));
  }


}

And for this I get the error:

\Recipe.java:19: error: incompatible types: no instance(s) of type variable(s) R exist so that Stream<R> conforms to boolean
                                        .map((theingredients) -> true );
                                            ^
  where R,T are type-variables:
    R extends Object declared in method <R>map(Function<? super T,? extends R>)
    T extends Object declared in interface Stream
Note: Recipes.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error

The problem is that map returns a Stream<R> rather than a boolean , in your case what you want is allMatch instead of filter which returns true if all the elements satisfy the condition

meatveg = ingredient.stream( )
            .allMatch((theingredients) -> !( theingredients == Ingredient.BEEF || theingredients == Ingredient.HAM ));

As the compiler error suggests, types do not match. The returned type is Stream<Boolean> and not Boolean .

In order to do what you are trying to do, you need to leverage anyMatch method.

Boolean meatveg = ingredient.stream( )
  .anyMatch(i -> !( i == Ingredient.BEEF || i == Ingredient.HAM ));

You can write that in a slightly more readable way by utilizing Predicate.isEqual and doing static imports:

Boolean meatveg = ingredients.stream()
      .anyMatch(isEqual(BEEF).or(isEqual(HAM)));

Currently you have a stream of boolean but have to reduce it to just one boolean.

To do that either use

meatveg = ingredient.stream().allMatch((theingredients) -> !( theingredients == Ingredient.BEEF || theingredients == Ingredient.HAM ));

or a little simpler:

meatveg = ingredient.stream().noneMatch((theingredients) -> theingredients == Ingredient.BEEF || theingredients == Ingredient.HAM);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM