查找 Set 中不存在的元素 return 包含这些缺失元素的新 Set

Find elements that are not present in a Set a return a new Set containing these missing elements

我有一个枚举 Tags,其中包含可应用于 Product class 实例的完整标签列表。在这个 class 中有一个实例变量 tags,它是 StringsSet,包含这些标签的子集。我想要做的是找到一组尚未应用于特定产品的标签,并使用方法 return 将其作为新的 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;
        }
    }

如何做到这一点?

您要过滤 Tags 不在 Product 中的内容,并获取 Tags 的名称,下面的代码应该有效

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

你可以这样做:

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

但这仍然是两个表达式。不过,仍然比您的第一个版本干净很多。

如果您从 String 组切换到 TagsEnumSet,虽然...

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

这也有很好的副作用,可以使集合更快并且占用更少的内存。