Найти дубликат в списке извлеченных сущностей

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 уже назначен данный рецепт (в качестве закуски или рецепта).

Интересно, есть ли более элегантный/краткий способ написать функцию.

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));
Holger 30.04.2019 09:56

вместо того, чтобы использовать arraylist, используйте hashSet и переопределите его метод equals & hashcode, это сэкономит время для этого вычисления.

Bishal Jaiswal 30.04.2019 14:25
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
2
110
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вероятно, вам следует избегать потоков

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);
}

Почему мне следует избегать стримов?

alexander 30.04.2019 10:22

Вы просили более короткий и элегантный способ. Потоки в этом случае не помогут.

Frank Neblung 30.04.2019 10:30

Я на самом деле согласен, это читается красиво и лаконично. Недостатком является то, что его будет сложно улучшить, особенно когда в будущем потребуется добавить больше условий OR. Когда вы сравните свой код с подходом Хольгера в его комментарии, вы увидите, что он может легко добавлять новые «вещи», такие как дополнительные закуски или что-то в этом роде... просто добавляя новые элементы в потоки.

GhostCat 30.04.2019 11:28
Ответ принят как подходящий

Решение, делающее все в одном потоке, это

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));
}

Действительно аккуратно. Это определенно лучший ответ, и его следует принять!

GhostCat 30.04.2019 14:05

Другие вопросы по теме