我们有一个集合 - Map<String,HashSet<String>> requestIdToproductMap
它旨在将requestId映射到与requestId对应的productId。
给定一组requestIds和productId,我们遍历每个键(requestId),以查找是否存在productId。
如果是,请将其删除并检查设置的值是否为空。
for (String reqId: requests) {
Set<String> productIdset = requestIdToproductMap.get(reqId);
productIdset.remove(productId);
if (productIdset.isEmpty()) {
//add requestId to discarded list
}
}
有没有更有效的方法来做到这一点 - 鉴于这是一个高容量操作?
只要你想保留你的Map<String,HashSet<String>> requestIdToproductMap
,并且需要从所有套装中删除productId
,我认为没有更好的方法来做到这一点。你必须检查给定requests
的所有集合并从所有这些中删除productId
- 这就是你所做的。
你现在的代码实际上应该是非常高效的。 HashMap.get
(如果你使用的是HashMap
)摊销O(1),HashSet.remove
也是如此。所以整体表现应该不错。
您可以考虑使用不同的数据结构。而不是将requestId
映射到productId
s集合,你只需存储成对的requestId
/ productId
。实现像RequestIdProductIdPair
这样的类(不要忘记equals(...)
和hashCode()
)。然后将RequestIdProductIdPair
s存放在HashSet<RequestIdProductIdPair> requestIdProductIds
中。然后,您可以简单地构造并删除所有给定的requestId
/ productId
对。
Set<String> discardedRequestIds = requests
.stream()
.map(requestId -> new RequestIdProductIdPair(requestId, productId))
.map(requestIdProductIdPair -> {
if (requestIdProductIds.remove(requestIdProductIdPair) {
return requestIdProductIdPair;
}
else {
return null;
}
})
.filter(Objects::nonNull)
.map(RequestIdProductIdPair::getRequestId)
.collect(Collectors.toSet());
更新:我已经考虑了一点,第二个想法我认为HashSet<RequestIdProductIdPair>
的第二个选项可能不会比你的代码更好。删除可能会更高效,但是这个代码为每个RequestIdProductIdPair
/ requestId
对创建一个新的productId
对象。所以它可能最终会比你的代码更糟糕。