private boolean hasDuplicates(Recipe recipe) {
List<Recipe> currentRecipes = new ArrayList<>();
Stream.of(this.breakfast, this.lunch, this.dinner).forEach(meal -> {
currentRecipes.add(meal.getRecipe());
currentRecipes.add(meal.getSnack());
});
currentRecipes.add(this.snack);
return currentRecipes.contains(recipe);
};
}
// Представим геттер и сеттер для всех полей.
public class Menuplan {
private Meal breakfast;
private Meal lunch;
private Meal dinner;
private Recipe snack;
}
public class Meal {
private Recipe recipe;
private Reicpe snack;
}
Я получил описанный выше метод для проверки, если в Menuplan уже назначен данный рецепт (в качестве закуски или рецепта).
Интересно, есть ли более элегантный/краткий способ написать функцию.
вместо того, чтобы использовать arraylist, используйте hashSet и переопределите его метод equals & hashcode, это сэкономит время для этого вычисления.




Вероятно, вам следует избегать потоков
private boolean hasDuplicates(Recipe recipe) {
for (Meal each : Arrays.asList(breakfast, lunch, dinner)) {
if (each.getRecipe().equals(recipe) || each.getSnack().equals(recipe) {
return true;
}
}
return snack.equals(recipe);
}
Почему мне следует избегать стримов?
Вы просили более короткий и элегантный способ. Потоки в этом случае не помогут.
Я на самом деле согласен, это читается красиво и лаконично. Недостатком является то, что его будет сложно улучшить, особенно когда в будущем потребуется добавить больше условий OR. Когда вы сравните свой код с подходом Хольгера в его комментарии, вы увидите, что он может легко добавлять новые «вещи», такие как дополнительные закуски или что-то в этом роде... просто добавляя новые элементы в потоки.
Решение, делающее все в одном потоке, это
private boolean hasDuplicates(Recipe recipe) {
return Stream.concat(
Stream.of(this.breakfast, this.lunch, this.dinner)
.flatMap(meal -> Stream.of(meal.getRecipe(), meal.getSnack())),
Stream.of(this.snack))
.anyMatch(Predicate.isEqual(recipe));
}
Три элемента потока this.breakfast, this.lunch, this.dinner получают одинаковую обработку вызова meal.getRecipe() и meal.getSnack() для формирования нового потока, который объединяется с потоком одного элемента, просто удерживающим this.snack.
anyMatch вернет true, как только найдет элемент, удовлетворяющий условию. В противном случае он вернется false.
Вместо этого вы можете рассмотреть возможность перемещения одного элемента, который не соответствует шаблону, общему для других, из операции Stream:
private boolean hasDuplicates(Recipe recipe) {
return this.snack.equals(recipe) ||
Stream.of(this.breakfast, this.lunch, this.dinner)
.flatMap(meal -> Stream.of(meal.getRecipe(), meal.getSnack())
.anyMatch(Predicate.isEqual(recipe));
}
Другой альтернативой является
private boolean hasDuplicates(Recipe recipe) {
return this.snack.equals(recipe) ||
Stream.of(this.breakfast, this.lunch, this.dinner)
.anyMatch(meal -> meal.getRecipe().equals(recipe)
|| meal.getSnack().equals(recipe));
}
Действительно аккуратно. Это определенно лучший ответ, и его следует принять!
return Stream.concat(Stream.of(this.breakfast, this.lunch, this.dinner).flatMap(meal -> Stream.of(meal.getRecipe(), meal.getSnack())), Stream.of(this.snack)) .anyMatch(Predicate.isEqual(recipe));