我有一张地图,其中键也可以作为其中一个值存在。我需要从值中删除它们。我写了一个方法来做我需要的东西,只是我有超过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));
}
}
这可以更简单或更快地完成吗?
答案 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的全文搜索引擎。当然,这样的框架允许对真正大的索引进行有效更新。