迭代Set的值

问题描述 投票:-2回答:1

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

有没有更有效的方法来做到这一点 - 鉴于这是一个高容量操作?

java
1个回答
0
投票

只要你想保留你的Map<String,HashSet<String>> requestIdToproductMap,并且需要从所有套装中删除productId,我认为没有更好的方法来做到这一点。你必须检查给定requests的所有集合并从所有这些中删除productId - 这就是你所做的。

你现在的代码实际上应该是非常高效的。 HashMap.get(如果你使用的是HashMap)摊销O(1),HashSet.remove也是如此。所以整体表现应该不错。

您可以考虑使用不同的数据结构。而不是将requestId映射到productIds集合,你只需存储成对的requestId / productId。实现像RequestIdProductIdPair这样的类(不要忘记equals(...)hashCode())。然后将RequestIdProductIdPairs存放在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对象。所以它可能最终会比你的代码更糟糕。

© www.soinside.com 2019 - 2024. All rights reserved.