Javaのsumの使い方を完全ガイド!ラムダ式で合計を求める方法と注意点
生徒
「Javaでリストの合計値を簡単に求める方法ってありますか?」
先生
「ありますよ。ラムダ式とStream APIを使えば、sum()で一発で合計を出せます。」
生徒
「ループを書かなくてもいいんですか?どんな書き方をするんですか?」
先生
「では、IntStreamやmapToIntを使った書き方を例で見ていきましょう!」
1. Javaのsumメソッドとは?合計値を求めるための定番メソッド
Javaのsum()メソッドは、数値のリストや配列から合計を求めるために使われる定番のメソッドです。IntStreamやDoubleStreamなどと組み合わせて使います。ラムダ式を活用することで、従来のfor文よりも簡潔で読みやすいコードになります。
2. 基本の使い方:整数リストの合計を出す
まずはList<Integer>の合計値を求める基本の書き方を見てみましょう。mapToInt()でIntStreamに変換し、sum()で合計を求めます。
import java.util.Arrays;
import java.util.List;
public class SumExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(10, 20, 30, 40);
int total = numbers.stream()
.mapToInt(n -> n)
.sum();
System.out.println("合計: " + total);
}
}
このコードでは、ループを使わずに合計が求められています。
3. DoubleやLongなど他の型でも使える
sum()はmapToDouble()やmapToLong()と組み合わせることで、Double型やLong型のリストにも対応できます。
List<Double> prices = Arrays.asList(99.9, 49.5, 20.0);
double totalPrice = prices.stream()
.mapToDouble(d -> d)
.sum();
データ型に応じてmapToXxxを使い分けることが重要です。
4. オブジェクトのプロパティの合計を求める
sum()は数値型のリストだけでなく、オブジェクトのプロパティを合計する場面でも役立ちます。以下はProductクラスのpriceプロパティを合計する例です。
import java.util.Arrays;
import java.util.List;
public class ProductSumExample {
public static void main(String[] args) {
List<Product> products = Arrays.asList(
new Product("りんご", 100),
new Product("バナナ", 120),
new Product("みかん", 80)
);
int total = products.stream()
.mapToInt(Product::getPrice)
.sum();
System.out.println("合計金額: " + total);
}
}
class Product {
private String name;
private int price;
public Product(String name, int price) {
this.name = name;
this.price = price;
}
public int getPrice() { return price; }
}
ラムダ式とメソッド参照を使うことで、非常にスッキリした書き方になります。
5. 条件付きで合計を求めたいときの書き方
filter()と組み合わせることで、条件に一致する要素だけを合計することも可能です。例えば価格が100円以上の商品だけを合計する場合は以下のように書きます。
int over100Total = products.stream()
.filter(p -> p.getPrice() >= 100)
.mapToInt(Product::getPrice)
.sum();
条件指定と合計処理を1行で完結できるのはラムダ式の強みです。
6. 合計が0になるケースに注意しよう
sum()は、対象データが空の場合は自動的に0を返します。例外が発生しない点は便利ですが、「なぜ0なのか?」と混乱するケースもあるので注意が必要です。
意図的に「空だった場合の処理」を別途入れる場合は、count()やfindAny()と組み合わせるとよいでしょう。
7. reduceとの違いとsumの使い分け
sum()とよく似た機能にreduce()があります。合計を出すだけならsum()のほうが直感的ですが、複雑な集計を行いたい場合はreduce()の方が柔軟です。
例えば、複数の条件を同時に処理したいときや、合計以外の演算が必要なときはreduce()を選ぶ場面も出てきます。
8. ラムダ式とsumで効率的に合計を扱おう
Javaのsum()メソッドは、ラムダ式と組み合わせて使うことで、従来のfor文よりも効率的で簡潔に合計処理ができます。業務アプリケーションやデータ集計処理でも頻繁に使われる定石なので、しっかりと使い方を覚えておきましょう。
慣れないうちは少し難しく感じるかもしれませんが、mapToIntとsumの流れに慣れることで、データの操作力が格段にアップします。
まとめ
Javaのsumメソッドとラムダ式の組み合わせは、現代のJava開発において非常に重要な基本技術のひとつです。特にStream APIと併用することで、これまでfor文で繰り返し処理を記述していた合計算出ロジックを、より直感的で読みやすく、保守性の高いスタイルへと変化させることができます。合計値を求める処理は、数値リスト、オブジェクトリスト、条件付き合計、集計処理など多様なシーンで必ず登場するため、sumの挙動を深く理解することは、Javaプログラマーとしての基礎力を高める上でも非常に価値があります。
とくにStream APIでのmapToIntやmapToDoubleなどのメソッドは、対象データを効率よく数値型ストリームに変換できるため、処理の見通しが格段に良くなります。mapToIntを使えば、int型のストリームに変換され、sumメソッドで一気に合計値が算出でき、従来のような変数の初期化やループ内での加算処理を書く必要がありません。また、オブジェクトのプロパティを合計する場合にも、メソッド参照を用いることで、簡潔で可読性の高いコードへと改善できます。
また、sumメソッドの特性として、ストリームが空である場合、自動的に0を返すという動作があります。この挙動は便利である一方で、意図しない0が返ってくると混乱のもとになることもあります。そのため、空データを考慮する必要がある場合は、事前にcountで件数を確認したり、findAnyなどと組み合わせて条件を追加したりすることで、より意図の明確な実装が可能になります。
一方、より複雑な集計処理や条件を伴うロジックでは、reduceメソッドを使う選択肢もあります。sumは「合計を求める」ことに特化したメソッドであり、reduceはより自由度の高い計算処理を実現できます。用途によってsumとreduceをうまく使い分けることは、効率的なプログラムを作る上で欠かせない要素です。業務システムでは商品合計、売上計算、在庫集計などで頻繁にsumが利用されるため、その実践的な知識は大いに役立ちます。
ラムダ式とsumを使いこなせるようになると、Javaにおけるデータ処理の幅が大きく広がります。単なる合計計算にとどまらず、条件付きの合計、重複データを除いた合計、複数項目の集計など、多くのパターンに応用できるため、業務アプリケーションの中核となる数値処理を効率化できます。また、ラムダ式の理解が深まることで、mapやfilter、collectといった他のStream APIの活用にも自然と繋がり、全体的なコーディングスキルの向上にも貢献します。
サンプルプログラム:条件ごとに複数の合計値を同時に処理する例
import java.util.*;
import java.util.stream.*;
public class MultiSumExample {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(50, 120, 300, 80, 200);
int total = list.stream().mapToInt(n -> n).sum();
int over100 = list.stream().filter(n -> n >= 100).mapToInt(n -> n).sum();
int under100 = list.stream().filter(n -> n < 100).mapToInt(n -> n).sum();
System.out.println("全体の合計:" + total);
System.out.println("100以上の合計:" + over100);
System.out.println("100未満の合計:" + under100);
}
}
この例のように、同じリストを条件ごとに分岐させ、それぞれに対してsumを適用することで、業務アプリケーションで求められる複雑な集計処理にも柔軟に対応できます。mapToIntによる変換がスムーズに行えるため、各処理が見やすくまとまり、コード全体の意図も明確になります。
生徒
「sumメソッドって、思っていた以上にいろいろな場面で使えるんですね。ループを書かなくてもいいのがすごく便利で、これなら集計処理も簡単に書けそうです!」
先生
「そうなんです。Stream APIとラムダ式を組み合わせると、コードが驚くほど読みやすくなりますし、処理の意図も伝わりやすくなります。sumは特に使用頻度が高いので、まず最初に慣れておきたいメソッドですね。」
生徒
「条件ごとに合計を出す例も参考になりました。実務でも数値を扱う処理は多いので、今後のプログラムにも取り入れてみたいです。」
先生
「そうですね。sumを使いこなせるようになると、自然とreduceや他のStream APIにも触れやすくなるので、データ処理の幅が広がりますよ。どんどん実践して、自在に扱えるようになっていきましょう。」