Поиск элементов, которых нет в наборе, возвращает новый набор, содержащий эти отсутствующие элементы

У меня есть перечисление Tags, содержащее полный список тегов, которые можно применять к экземплярам класса Product. В этом классе есть переменная экземпляра tags, которая является Set из Strings и содержит подмножество этих тегов. Что я пытаюсь сделать, так это найти набор тегов, которые еще не были применены к определенному продукту, и вернуть его как новый Set с помощью метода.

        Set<String> suggestedTags = new HashSet<>();
        Arrays.stream(Tags.values())
                .forEach(tagsList -> {
                    if (!this.tags.contains(tagsList.getTagName())) {
                        suggestedTags.add(tagsList.getTagName());
                    }
                });
        return suggestedTags;

Я протестировал приведенный выше код, и он работает так, как ожидалось. Однако я хочу добиться того же результата всего одним оператором. Что-то вроде этого:

        return Arrays.stream(Tags.values())
                .map(tagsList -> {
                    // code to find missing elements goes here
                })
                .collect(Collectors.toSet());

Я застрял здесь, так как не уверен, какая промежуточная операция подойдет для такой задачи. Я думал об использовании map() и filter(), но пока безуспешно.

Перечисление Tags выглядит следующим образом:

    public enum Tags {

        BIRTHDAY("birthday"),
        GRADUATION("graduation"),
        GET_WELL_SOON("get well soon");

        final String tagName;

        private Tags(String tagName) {
            this.tagName = tagName;
        }

        public String getTagName() {
            return tagName;
        }
    }

Как это может быть сделано?

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

Ответы 2

Вы хотите отфильтровать Tags, которого нет в Product, и получить имя Tags, приведенный ниже код должен работать

  return Arrays.stream(Tags.values()).filter(tag -> !this.tags.contains(tag)).map(Tags::getTagName).collect(Collectors.toSet());

Intellij предупреждает меня о том, что порядок фильтра и карты должен быть изменен, вызовет ли этот порядок какие-либо заметные проблемы?

CM K 04.04.2022 09:21

@CMK, когда ваш набор содержит имена тегов, проще сначала сопоставить имена, т. Е. .map(Tags::getTagName) .filter(name -> !tags.contains(name)), потому что тогда вы не вызываете getTagName() дважды для каждого элемента.

Holger 04.04.2022 11:47
Ответ принят как подходящий

Вы можете сделать что-то вроде этого:

Set<String> suggestedTags = Arrays.stream(Tags.values())
                                  .map(Tags::getTagName)
                                  .collect(Collectors.toCollection(HashSet::new));
suggestedTags.removeAll(tags);

но это все еще два выражения. Тем не менее, все еще намного чище, чем ваша первая версия.

Если вы переключитесь с наборов String на EnumSetTags, хотя...

EnumSet<Tags> suggestedTags = EnumSet.complementOf(tags);
// Assuming EnumSet<Tags> tags = EnumSet.of(Tags.BIRTHDAY);
// suggestedTags contains GRADUATION and GET_WELL_SOON

Это также имеет приятный побочный эффект, делая наборы намного быстрее и занимая меньше памяти.

до сих пор не знал об EnumSet. Спасибо за информацию, попробую использовать.

CM K 04.04.2022 09:22

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