迭代Set的值

时间:2018-03-01 05:16:51

标签: java

我们有一个集合 - 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
    }
}

有没有更有效的方法来实现这一点 - 假设这是一个高容量操作?

1 个答案:

答案 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对象。所以最终可能会比你的代码更糟糕。