我们有一个集合 - 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
}
}
有没有更有效的方法来实现这一点 - 假设这是一个高容量操作?
答案 0 :(得分:0)
只要您想要保留Map<String,HashSet<String>> requestIdToproductMap
,并且需要从所有套装中删除productId
,我认为没有更好的方法来执行此操作。您必须检查给定requests
的所有集合并从所有这些集合中移除productId
- 这就是您所做的。
您现在的代码实际上应该非常高效。 HashMap.get
(如果您使用HashMap
)是摊销的O(1),HashSet.remove
也是。所以整体表现应该不错。
您可以考虑使用不同的数据结构。如果不将requestId
映射到productId
集,您只需存储requestId
/ productId
对。实现类似RequestIdProductIdPair
的类(不要忘记equals(...)
和hashCode()
)。然后将RequestIdProductIdPair
存储在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
对象。所以最终可能会比你的代码更糟糕。