簡體   English   中英

在遍歷 java stream 時從 hashmap 內的哈希集中刪除元素

[英]Remove elements from hashset inside hashmap while iterating through java stream

我在 Java 中有一個 hashmap ,帶有一個字符串鍵和一個 HashSet 值。 hashset 里面可能包含許多 PlacementBundle。

public Map<String, Set<PlacementBundle>> placementByConcept;

我試圖在迭代與特定條件匹配的 map 時從 HashSet 中刪除該值。

我嘗試了以下代碼,但無法從 HashSet 中刪除匹配元素。

placementByConcept.entrySet()
                  .stream()
                  .map(e -> e.getValue()
                             .removeIf(s -> s.getBeatObjectiveId().equals("non-scored")));

您可以使用 forEach:

placementByConcept.entrySet().forEach(e -> e.getValue().removeIf(s -> s.getBeatObjectiveId().equals("non-scored")));

在您的情況下, Set<PlacementBundle>是一個不可變的集合。 您不能從中刪除元素。 如果您按照接受的答案中的建議使用 foreach,您將獲得UnsupportedOperationException

import lombok.Builder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
public class Test {

    public static void main(String[] args) {
        Map<String, Set<PlacementBundle>> placementByConcept = new HashMap<>();
        placementByConcept.put("concept1", Set.of(
                PlacementBundle.builder().beatObjectiveId("scored").build(),
                PlacementBundle.builder().beatObjectiveId("non-scored").build())
        );
        placementByConcept.put("concept2", Set.of(
                PlacementBundle.builder().beatObjectiveId("scored").build(),
                PlacementBundle.builder().beatObjectiveId("non-scored").build())
        );

        log.info("Original: {}", placementByConcept);

        /* This won't give any exception, neither will remove the entries */
        placementByConcept.entrySet()
                          .stream()
                          .map(e -> e.getValue()
                                     .removeIf(s -> s.getBeatObjectiveId().equals("non-scored")));
        log.info("Does not work: {}", placementByConcept);

        /* This will give you the exception UnsupportedOperationException */
        // placementByConcept.entrySet().forEach(e -> e.getValue().removeIf(s -> s.getBeatObjectiveId().equals("non-scored")));

        /* This is one of the correct way */
        for (Map.Entry<String, Set<PlacementBundle>> entry : placementByConcept.entrySet()) {
            var filtered = entry.getValue().stream()
                    .filter(placementBundle -> !placementBundle.getBeatObjectiveId().equals("non-scored"))
                    .collect(Collectors.toUnmodifiableSet());
            log.debug("New Value Set: {}", filtered);
            entry.setValue(filtered);
        }

        log.info("After: {}", placementByConcept);
    }

}

@Builder
@Data
class PlacementBundle {
    private String beatObjectiveId;
}

Output:

Original: {concept2=[PlacementBundle(beatObjectiveId=scored), PlacementBundle(beatObjectiveId=non-scored)], concept1=[PlacementBundle(beatObjectiveId=scored), PlacementBundle(beatObjectiveId=non-scored)]}

Does not work: {concept2=[PlacementBundle(beatObjectiveId=scored), PlacementBundle(beatObjectiveId=non-scored)], concept1=[PlacementBundle(beatObjectiveId=scored), PlacementBundle(beatObjectiveId=non-scored)]}

After: {concept2=[PlacementBundle(beatObjectiveId=scored)], concept1=[PlacementBundle(beatObjectiveId=scored)]}
public class Remove {
    public static void main(String[] args)
    {
        HashMap<Integer, String>
            map = new HashMap<>();

        map.put(1, "Stack");
        map.put(2, "Overflow");
        map.put(3, "StackOverflow");

        int keyToBeRemoved = 2;

        System.out.println("Original HashMap: "
                        + map);

        map.entrySet()
            .removeIf(
                entry -> (keyToBeRemoved == entry.getKey()));

        System.out.println("New HashMap: "
                        + map);
    }
}

Output:

Original HashMap: {1=Stack, 2=Overflow, 3=StackOverflow}
New HashMap: {1=Stack, 3=StackOverflow}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM