整数のリストを合計したい。次のように動作しますが、構文は正しくありません。コードを最適化できますか?
Map<String, Integer> integers;
integers.values().stream().mapToInt(i -> i).sum();
これはうまくいくでしょうが、i -> i
は自動アンボックス化をしているので、それは奇妙に「感じる」理由です。以下のいずれかが機能し、コンパイラが内部で行っていることを元の構文でよりよく説明します。
integers.values().stream().mapToInt(i -> i.intValue()).sum();
integers.values().stream().mapToInt(Integer::intValue).sum();
私はもう2つのオプションを提案する:
integers.values().stream().mapToInt(Integer::intValue).sum();
integers.values().stream().collect(Collectors.summingInt(Integer::intValue));
2番目のものは Collectors.summingInt()
collectorを使います、mapToLong
と一緒に使うsummingLong()
コレクターもあります。
そして3番目の選択肢:Java 8は並列ストリームとマルチスレッド環境での要約をスピードアップするように設計された非常に効果的な LongAdder
accumulatorを導入します。これが、使用例です。
LongAdder a = new LongAdder();
map.values().parallelStream().forEach(a::add);
sum = a.intValue();
docs から
縮小演算縮小演算(フォールドとも呼ばれます)は、一連の入力要素を取り、一連の数値の合計または最大値を求める、要素を次の要素に累積するなど、結合操作を繰り返し適用して単一の要約結果にまとめます。リスト。ストリームクラスには、reduce()およびcollect()と呼ばれる複数の形式の一般的な縮約操作、およびsum()、max()、count()などの複数の特殊な縮約形式があります。
もちろん、このような操作は、次のように単純な順次ループとして簡単に実装できます。
int sum = 0; for (int x : numbers) { sum += x; }
ただし、上記のような突然変異の累積よりも縮小操作を優先するのには十分な理由があります。縮小は「より抽象的」である - 個々の要素ではなくストリーム全体を操作する - だけでなく、要素の処理に使用される関数が結合的である限り、適切に構築されたreduce操作は本質的に並列化可能であるそしてステートレス。たとえば、合計を求めたい数値のストリームを考えると、次のように書くことができます。
int sum = numbers.stream().reduce(0, (x,y) -> x+y);
または
int sum = numbers.stream().reduce(0, Integer::sum);
これらの縮小操作は、ほとんど修正を加えることなく安全に並行して実行できます。
int sum = numbers.parallelStream().reduce(0, Integer::sum);
だから、地図のためにあなたは使うだろう:
integers.values().stream().mapToInt(i -> i).reduce(0, (x,y) -> x+y);
または
integers.values().stream().reduce(0, Integer::sum);
あなたはreduceメソッドを使うことができます:
long sum = result.stream().map(e -> e.getCreditAmount()).reduce(0L, (x, y) -> x + y);
または
long sum = result.stream().map(e -> e.getCreditAmount()).reduce(0L, Integer::sum);
整数のリストを合計するためにreduce()
を使うことができます。
int sum = integers.values().stream().reduce(0, Integer::sum);
整数のリストを追加するためにcollectメソッドを使うことができます。
List<Integer> list = Arrays.asList(2, 4, 5, 6);
int sum = list.stream().collect(Collectors.summingInt(Integer::intValue));
これはint
型の配列をまとめるための最短の方法です(long
配列LongStream
の場合、double
配列DoubleStream
の場合など)。ただし、すべてのプリミティブ整数型または浮動小数点型にStream
実装があるわけではありません。
IntStream.of(integers).sum();
整数のリストを宣言しました。
ArrayList<Integer> numberList = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5));
以下のさまざまな方法を使用してみてください。
mapToInt
を使用
int sum = numberList.stream().mapToInt(Integer::intValue).sum();
summarizingInt
を使用
int sum = numberList.stream().collect(Collectors.summarizingInt(Integer::intValue)).getSum();
reduce
を使用
int sum = numberList.stream().reduce(Integer::sum).get().intValue();