如果它们存在于map中的值中,则删除它们

时间:2018-06-02 17:43:19

标签: java

我有一张地图,其中键也可以作为其中一个值存在。我需要从值中删除它们。我写了一个方法来做我需要的东西,只是我有超过8万个密钥,它需要永远。

static void cleanSetMap(Map<String, Set<String>> inputMap){
    List<String> keys = new ArrayList<>(inputMap.keySet());
    List<Set<String>> values = new ArrayList<>(inputMap.values());

    for (int i = 0; i < keys.size(); i++) {
        String key = keys.get(i);
        for (int j = 0; j < values.size(); j++) {
            Set<String> set = values.get(j);
            set.remove(key);
            values.set(j, set);
        }
    }

    for (int i = 0; i < keys.size(); i++) {
        inputMap.put(keys.get(i), values.get(i));
    }

}

这可以更简单或更快地完成吗?

3 个答案:

答案 0 :(得分:1)

以下语句将从其中包含任何值的所有集合中删除任何字符串中的键。

    inputMap.keySet().parallelStream().forEach(
         key -> inputMap.values().stream().forEach(set -> set.remove(key)));

这只是所有地图条目上的并行流,在值集上运行另一个连续流以删除每个键。

在这种情况下,您可能需要测试并行流的行为。如果值Set实例不是线程安全的,那么您可能应该调用inputMap.keySet().stream()...(但在这种情况下,内部流可以与key -> inputMap.values().parallelStream()...并行(Set.remove)不会在任何给定的地图值上同时调用)

答案 1 :(得分:0)

查看示例代码,您似乎正在寻找从值集中删除所有键,即使它们不存在于该键值对中。

您可以尝试:

List<String> keys = new ArrayList<>(inputMap.keySet());
List<Set<String>> values = new ArrayList<>(inputMap.values());
Iterator<Set<String>> itr = values.iterator();
while (itr.hasNext()) {
    itr.next().removeAll(keys);
}

答案 2 :(得分:0)

我认为另一种选择是引入更有用的抽象。

含义:例如,使用某种索引可能会有所帮助,而不是保留字符串和字符串集的“原始”映射。

如下:记住使用它的每个字符串。而不是引入迭代大型地图中所有值的需要。

重点是:如果删除用作键的字符串并且在这些值集中是一种常见的操作,那么您只需选择一种允许您有效地执行此操作的数据类型。

或者你退后一步。例如,通过使用诸如Solr的全文搜索引擎。当然,这样的框架允许对真正大的索引进行有效更新。