web-dev-qa-db-ja.com

ストリーミング中にHashMapの要素を削除する方法(ラムダ)

ストリームから要素を削除する必要がある次の状況があります。

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

pre Java 8コードでイテレータから削除します-この状況に対処する最良の方法は何ですか?

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

ストリームではできませんが、他の新しいメソッドではできます。

編集:さらに良い:

map.values().removeAll(Collections.singleton("0"));
98
Louis Wasserman

here のように、Streamsが非干渉を持ちたいという願望のために、それは不可能だと思います(または間違いなく行われるべきではありません)

関数型プログラミングの構成要素がJavaにリークされたときにストリームについて考える場合は、それらを対応する関数型としてサポートするオブジェクトを考え、関数型プログラミングでは不変オブジェクトを操作します

これに対処する最良の方法は、あなたがやったようにフィルターを使うことです

4
maczikasz

1回目の返信。このスレッドを駆け巡り、他の人が検索している場合は更新することを考えました。ストリームを使用すると、フィルター処理されたマップ<>またはあなたが本当に好きなものを返すことができます。

  @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

1
Cyberpunk