50

変換およびフィルタリングしたい Java Map があります。簡単な例として、すべての値を整数に変換してから、奇数のエントリを削除するとします。

Map<String, String> input = new HashMap<>();
input.put("a", "1234");
input.put("b", "2345");
input.put("c", "3456");
input.put("d", "4567");

Map<String, Integer> output = input.entrySet().stream()
        .collect(Collectors.toMap(
                Map.Entry::getKey,
                e -> Integer.parseInt(e.getValue())
        ))
        .entrySet().stream()
        .filter(e -> e.getValue() % 2 == 0)
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));


System.out.println(output.toString());

これは正しく、結果は次のとおりです。{a=1234, c=3456}

とはいえ、二度電話しないようにするにはどうしたらいいのだろうかと考えずにはいられません.entrySet().stream()

変換操作とフィルター操作の両方を実行 .collect()し、最後に 1 回だけ呼び出す方法はありますか?

4

6 に答える 6

6

Guavaはあなたの友達です:

Map<String, Integer> output = Maps.filterValues(Maps.transformValues(input, Integer::valueOf), i -> i % 2 == 0);

outputこれは、 の変換され、フィルター処理されたビューであることに注意してくださいinput。それらを個別に操作する場合は、コピーを作成する必要があります。

于 2016-02-19T05:22:58.787 に答える
4

メソッドを使用しStream.collect(supplier, accumulator, combiner)てエントリを変換し、条件付きでそれらを蓄積できます。

Map<String, Integer> even = input.entrySet().stream().collect(
    HashMap::new,
    (m, e) -> Optional.ofNullable(e)
            .map(Map.Entry::getValue)
            .map(Integer::valueOf)
            .filter(i -> i % 2 == 0)
            .ifPresent(i -> m.put(e.getKey(), i)),
    Map::putAll);

System.out.println(even); // {a=1234, c=3456}

ここでは、アキュムレータ内で、Optionalメソッドを使用して変換と述語の両方を適用しています。オプションの値がまだ存在する場合は、収集されているマップに追加しています。

于 2016-02-18T19:15:59.663 に答える
0

ここにAbacusUtilによるコードがあります

Map<String, String> input = N.asMap("a", "1234", "b", "2345", "c", "3456", "d", "4567");

Map<String, Integer> output = Stream.of(input)
                          .groupBy(e -> e.getKey(), e -> N.asInt(e.getValue()))
                          .filter(e -> e.getValue() % 2 == 0)
                          .toMap(Map.Entry::getKey, Map.Entry::getValue);

N.println(output.toString());

宣言: 私は AbacusUtil の開発者です。

于 2016-11-29T22:39:24.340 に答える