如何很好地将两个地图的两个集合相交?

时间:2019-04-08 11:00:21

标签: java dictionary java-8 set java-stream

我们的对象具有“属性”;它们的当前状态表示为Map<String, Object>,其中键类似于属性的名称。这些值可以具有不同的类型,尽管我当前的任务只是处理 Boolean 属性。

除当前状态外,还通过此类映射对对象进行“更新”。

现在我必须防止禁用当前为true的属性(变成false)。

使用流,这在这里有效:

Set<String> currentlyEnabled = currentObjectPropertiesMap.
            .entrySet()
            .stream()
            .filter(e -> Boolean.TRUE.equals(e.getValue()))
            .map(Entry::getKey)
            .collect(Collectors.toSet());

Set<String> goingDisabled = updatedObjectPropertiesMap
        .entrySet()
        .stream()
        .filter(e -> Boolean.FALSE.equals(e.getValue()))
        .map(Entry::getKey)
        .collect(Collectors.toSet());

currentlyEnabled.retainAll(goingDisabled);

if (currentlyEnabled.isEmpty()) {
    return;
} else {
  throw new SomeExceptionThatKnowsAllBadProperties(currentlyEnabled);
}

上面的代码首先获取一组true的所有属性,然后分别收集将变为false的所有属性。如果这两个集合的交集为空,则表示我很好,否则出错。

以上方法有效,但我发现它很笨拙,并且我不喜欢currentlyEnabled集被误用于计算相交的事实。

有人建议如何以一种更加惯用但更易读的“流式”方式来做到这一点?

3 个答案:

答案 0 :(得分:7)

您只需选择所有值为true的键值对,然后通过键检查“更新”映射中的值是否为false

Set<String> matches = currentObjectPropertiesMap
    .entrySet()
    .stream()
    .filter(e -> Boolean.TRUE.equals(e.getValue()))
    .map(Map.Entry::getKey)
    .filter(k -> Boolean.FALSE.equals(
        updatedObjectPropertiesMap.get(k)
    ))
    .collect(Collectors.toSet());

if(!matches.isEmpty()) throw ...

答案 1 :(得分:2)

包括显式集合交集的一种解决方案可能是:

this.$axios.get('/gapcroplist/' + gapid)

答案 2 :(得分:0)

尝试anyMatch

boolean anyMatch = currentXXXMap.entrySet()
    .stream()
    .anyMatch(e -> e.getValue() && !updatedXXXMap.getOrDefault(e.getKey(), true));