How to remove an element of a HashMap whilst streaming (lambda)

JavaDictionaryIteratorJava Stream

Java Problem Overview


I have the following situation where I need to remove an element from a stream.

map.entrySet().stream().filter(t -> t.getValue().equals("0")).
            forEach(t -> map.remove(t.getKey()));

in pre Java 8 code one would remove from the iterator - what's the best way to deal with this situation here?

Java Solutions


Solution 1 - Java

map.entrySet().removeIf(entry -> entry.getValue().equals("0"));

You can't do it with streams, but you can do it with the other new methods.

EDIT: even better:

map.values().removeAll(Collections.singleton("0"));

Solution 2 - Java

If you want to remove the entire key, then use:

myMap.entrySet().removeIf(map -> map.getValue().containsValue("0"));

Solution 3 - Java

I think it's not possible (or deffinitelly shouldn't be done) due to Streams' desire to have Non-iterference, as described here

If you think about streams as your functional programming constructs leaked into Java, then think about the objects that support them as their Functional counterparts and in functional programming you operate on immutable objects

And for the best way to deal with this is to use filter just like you did

Solution 4 - Java

1st time replying. Ran across this thread and thought to update if others are searching. Using streams you can return a filtered map<> or whatever you like really.

  @Test
  public void test() {

    Map<String,String> map1 = new HashMap<>();
    map1.put("dan", "good");
    map1.put("Jess", "Good");
    map1.put("Jaxon", "Bad");
    map1.put("Maggie", "Great");
    map1.put("Allie", "Bad");
    
    System.out.println("\nFilter on key ...");
    Map<String,String> map2 = map1.entrySet().stream().filter(x -> 
    x.getKey().startsWith("J"))
        .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));
    
    map2.entrySet()
      .forEach(s -> System.out.println(s));
    
    System.out.println("\nFilter on value ...");
    map1.entrySet().stream()
      .filter(x -> !x.getValue().equalsIgnoreCase("bad"))
      .collect(Collectors.toMap(e -> e.getKey(),  e -> e.getValue()))
      .entrySet().stream()
      .forEach(s -> System.out.println(s));
  }

------- output -------

Filter on key ...
Jaxon=Bad
Jess=Good

Filter on value ...
dan=good
Jess=Good
Maggie=Great

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDanView Question on Stackoverflow
Solution 1 - JavaLouis WassermanView Answer on Stackoverflow
Solution 2 - Javaabhi169jaisView Answer on Stackoverflow
Solution 3 - JavamaczikaszView Answer on Stackoverflow
Solution 4 - JavaCyberpunkView Answer on Stackoverflow