件数カウントは「どれくらいあるか」を正確に言葉にする技
業務では「何件あるか?」を数える場面が本当に多いです。
今日の注文件数、エラー件数、未処理タスク件数、特定条件を満たすユーザー数…。
だからこそ、「件数カウント」を毎回 for 文で手書きするのではなく、
“安全で読みやすいカウントユーティリティ”としてパターン化しておくと、
コード全体がかなりスッキリして、バグも入りにくくなります。
一番基本:List の件数を数える
size と stream().count の違いを押さえる
一番シンプルな件数カウントは、List#size() です。
import java.util.List;
public class CountBasic {
public static void main(String[] args) {
List<String> names = List.of("山田", "佐藤", "鈴木");
int count = names.size();
System.out.println(count); // 3
}
}
Javasize() は「そのコレクションに何件入っているか」を返します。
これは「全部の件数」が欲しいときの基本形です。
一方、Stream を使うとこう書けます。
long count = names.stream().count();
Java結果は同じですが、count() は戻り値が long です。
「全部の件数」だけなら size() の方がシンプルですが、
後で条件付きカウントに発展させたいときは stream() ベースで書いておくと自然に拡張できます。
条件付き件数カウント:「◯◯なものだけ何件?」
例:スコアが 80 点以上の件数を数える
業務では「全部の件数」よりも、
「条件を満たすものだけ何件あるか?」の方が圧倒的に多いです。
import java.util.List;
public class CountWithCondition {
public static void main(String[] args) {
List<Integer> scores = List.of(70, 85, 90, 60);
long passedCount = scores.stream()
.filter(score -> score >= 80)
.count();
System.out.println(passedCount); // 2
}
}
Javaここでの重要ポイントは二つです。
一つ目は、filter で「条件を満たすものだけ」に絞り込んでから count() していること。
「条件付き件数カウント」は、基本的に「filter → count」の形になります。
二つ目は、戻り値が long であることです。
件数が int の範囲を超えることはあまりありませんが、
API としては long を返すのが標準になっています。
条件付き件数カウントをユーティリティ化する
「毎回 filter と count を書きたくない」を解消する
同じような条件付きカウントを何度も書くなら、
ユーティリティメソッドにしてしまうとスッキリします。
import java.util.Collection;
import java.util.function.Predicate;
public final class Counts {
private Counts() {}
public static <T> long count(
Collection<T> source,
Predicate<? super T> condition
) {
if (source == null || source.isEmpty()) {
return 0L;
}
return source.stream()
.filter(condition)
.count();
}
}
Java使い方はこうなります。
import java.util.List;
public class CountUtilSample {
public static void main(String[] args) {
List<Integer> scores = List.of(70, 85, 90, 60);
long passed = Counts.count(scores, s -> s >= 80);
long failed = Counts.count(scores, s -> s < 80);
System.out.println(passed); // 2
System.out.println(failed); // 2
}
}
Javaここでの重要ポイントは、
「Predicate<? super T> condition が“何を数えたいか”を表している」ことです。
Counts.count(scores, s -> s >= 80) と書けば、
「80 点以上の件数を数えているんだな」と一目で分かります。
条件をラムダで渡せるので、どんな業務ルールにも対応できます。
オブジェクト一覧から「特定条件を満たす件数」を数える
例:ユーザー一覧から「東京都在住ユーザー数」を数える
業務では、オブジェクトの特定のフィールドに基づいて件数を数えることが多いです。
class User {
private final String name;
private final String prefecture;
public User(String name, String prefecture) {
this.name = name;
this.prefecture = prefecture;
}
public String getName() { return name; }
public String getPrefecture() { return prefecture; }
}
Javaこれを使って、「東京都在住ユーザー数」を数えます。
import java.util.List;
public class UserCountSample {
public static void main(String[] args) {
List<User> users = List.of(
new User("山田", "東京都"),
new User("佐藤", "大阪府"),
new User("鈴木", "東京都")
);
long tokyoCount =
Counts.count(users, u -> "東京都".equals(u.getPrefecture()));
System.out.println(tokyoCount); // 2
}
}
Javaここでの重要ポイントは、
「業務ルール(東京都在住)が Predicate としてそのまま書かれている」ことです。
u -> "東京都".equals(u.getPrefecture()) というラムダが、
「都道府県が東京都であるユーザーだけを数える」という仕様を表現しています。
この形に慣れると、「何を数えているのか」がコードからすぐに読み取れるようになります。
グルーピングと組み合わせた「グループごとの件数」
例:都道府県ごとのユーザー数
件数カウントが本領を発揮するのは、「グルーピング」と組み合わせたときです。
例えば、「都道府県ごとのユーザー数」を出したい場合。
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
List<User> users = List.of(
new User("山田", "東京都"),
new User("佐藤", "大阪府"),
new User("鈴木", "東京都")
);
Map<String, Long> countByPref =
users.stream()
.collect(Collectors.groupingBy(
User::getPrefecture,
Collectors.counting()
));
System.out.println(countByPref); // {東京都=2, 大阪府=1}
Javaここでの重要ポイントは、
「groupingBy(キー, counting()) という一行が、
“キーごとの件数を数える”という仕様をそのまま表している」ことです。
「Map を用意して、キーがなければ 0 で入れて、1 足して…」という手作業をしなくてよくなり、
読みやすさと安全性が一気に上がります。
null を含むデータの件数カウント
「null も数えるか」「null を除外するか」を決める
現実のデータには null が混ざります。
件数カウントで大事なのは、「null をどう扱うか」を決めることです。
例えば、「null 以外の件数だけ数えたい」なら、こう書けます。
import java.util.Collection;
public final class Counts {
private Counts() {}
public static <T> long countNonNull(Collection<T> source) {
if (source == null || source.isEmpty()) {
return 0L;
}
return source.stream()
.filter(v -> v != null)
.count();
}
}
Java使い方はこうです。
import java.util.List;
public class NonNullCountSample {
public static void main(String[] args) {
List<String> names = List.of("山田", null, "佐藤");
long nonNullCount = Counts.countNonNull(names);
System.out.println(nonNullCount); // 2
}
}
Javaここでの重要ポイントは、
「null の扱いも“件数カウントのルール”の一部」だと意識することです。
「null も 1 件として数えるのか」「null は除外するのか」を、
ユーティリティ側で決めておくと、呼び出し側の迷いがなくなります。
「size でいいところ」と「count を使うべきところ」
ただの件数なのか、条件付きなのか
整理すると、こんな感覚を持てると実務で強いです。
全部の件数が欲しいだけなら、list.size() が一番シンプル。
条件付き件数が欲しいなら、stream().filter(...).count() の形が基本。
何度も出てくる条件付きカウントは、Counts.count(コレクション, 条件) のようなユーティリティにする。
グルーピングと組み合わせると、「◯◯ごとの件数」を一行で書ける。
「これは size でいいのか?」「条件付きか?」と一瞬立ち止まって考える癖がつくと、
件数カウントのコードがかなり整理されていきます。
まとめ:件数カウントユーティリティで身につけてほしい感覚
件数カウントは、
単に「何件あるかを数えるテクニック」ではなく、
「どんな条件で、何を“1件”とみなすかをコードに刻む作業」です。
全部の件数なら size()、条件付きなら filter → count という基本パターンを押さえる。Counts.count(コレクション, 条件) のようなユーティリティにして、「何を数えているか」をラムダで表現する。
グルーピング+counting() で、「◯◯ごとの件数」を一行で書けるようにする。
null を含む場合は、「null を数えるのか、除外するのか」をユーティリティ側で統一する。
あなたのコードのどこかに、
同じような for 文で if (...) count++ を繰り返している箇所があれば、
それを一度「件数カウントユーティリティ+Stream」に置き換えられないか眺めてみてください。
その小さな整理が、
「“何件あるか”を迷いなく、正確に言葉にできるエンジニア」への、
確かな一歩になります。
