JavaでCollection
(ListやSetなど)の中身が空かどうかを判定する場面は、日常的にあります。そのとき、あなたはisEmpty()
を使いますか?それともsize() == 0
でしょうか。
この2つは結果としては同じ動作になりますが、可読性、パフォーマンス、そしてコーディングのベストプラクティスという観点から見ると、明確な違いがあります。
この記事では、Javaにおけるコレクションの空判定にはなぜisEmpty()
を使うべきなのか、その理由と実務で役立つ知識を分かりやすく解説します。
Collectionの空判定方法:isEmpty()とsize()
JavaでCollection
(List、Set、Queueなど)の中身が空かどうかを調べるには、主に2つの方法があります。
// 方法1:isEmpty() を使う
if (collection.isEmpty()) {
// 空のときの処理
}
// 方法2:size() == 0 を使う
if (collection.size() == 0) {
// 空のときの処理
}
どちらの方法でも「コレクションが空であるかどうか」は正しく判定できます。ただし、実務においてはisEmpty()
の方が推奨されるケースがほとんどです。
なぜisEmpty()
が選ばれるのか?その理由は単なる好みではなく、コードの意図の明確さやパフォーマンス、チームでの統一性など、いくつかの重要な観点に基づいています。
なぜ isEmpty() を使うべきなのか?
collection.isEmpty()
と collection.size() == 0
は、どちらもコレクションが空かどうかを判定する方法ですが、実際の開発では isEmpty()
の使用が推奨されます。その理由は大きく分けて以下の3点です。
✅ 1. コードの意図が明確で読みやすい
isEmpty()
は「空であるかどうか」をそのまま表現しているため、一目で意味がわかりやすいというメリットがあります。
if (collection.isEmpty()) // 空であることを直感的に理解できる
一方、size() == 0
は比較演算を含むため、意図がやや間接的であり、特にJavaに不慣れな人には理解しづらいことがあります。コードレビューの際も、isEmpty()
の方が意図が伝わりやすく、メンテナンス性が向上します。
✅ 2. パフォーマンス面でより安全
isEmpty()
は、多くのコレクション実装で専用の内部状態を利用して高速に判定できるよう最適化されています。
対して size()
は、実装によっては内部の全要素をカウントするために走査処理が必要になる場合があり、特に大規模または非同期のコレクションでパフォーマンスのボトルネックとなる可能性があります。
例:ConcurrentLinkedQueue の場合
ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();
boolean isEmpty = queue.isEmpty(); // 高速(ヘッドノードの存在で判断)
boolean isZero = queue.size() == 0; // 全ノードを走査(O(n)のコスト)
ConcurrentLinkedQueue
はスレッドセーフを保つため、サイズをカウントするたびに全体を走査する必要があります。
Javadoc にも下記のように「現在の要素数を判定するにはO(n)トラバーサルが必要」と明記されています。
Beware that, unlike in most collections, this method is NOT a constant-time operation. Because of the asynchronous nature of these queues, determining the current number of elements requires an O(n) traversal. Additionally, if elements are added or removed during execution of this method, the returned result may be inaccurate. Thus, this method is typically not very useful in concurrent applications.
特に並列処理やリアルタイム性が求められるシステムでは、この違いが顕著な性能差となる場合があります。
✅ 3. コーディング規約やレビューで好まれる
多くの企業やチームの Java コーディングスタイルガイドでは、空判定には isEmpty()
を使用することが明示的に推奨されています。
実際のコードレビューでも「size() == 0
よりも isEmpty()
を使ってください」とフィードバックされることがよくあります。チーム全体のコード品質と統一感を保つうえでも、isEmpty()
を使うほうが望ましいと言えるでしょう。
nullチェックと組み合わせるパターン
実際の開発では、Collection
が null
の可能性がある場面も少なくありません。
そのため、「空かどうか」の判定と合わせて null
チェックを行うのが一般的です。
このような場合でも isEmpty()
を使うことで、読みやすく安全なコードを書くことができます。
if (collection == null || collection.isEmpty()) {
// nullまたは空の場合の処理
}
順序に注意することも大切です。先に isEmpty()
を呼ぶと null
の場合に NullPointerException
が発生するため、必ず null
チェックを先に行いましょう。
ユーティリティメソッドを活用することで、このような null 安全な処理をさらに簡潔に記述することも可能です。
たとえば、Apache Commons Collections を使えば、null
チェックと isEmpty()
の両方を1行で書けます。
import org.apache.commons.collections4.CollectionUtils;
if (CollectionUtils.isEmpty(collection)) {
// nullまたは空のときの処理
}
ユーティリティメソッドも活用することで、nullチェックと空判定を一貫したスタイルで書けるようになります。プロジェクトの方針に応じて使い分けると良いでしょう。
size() を使うべきケースはある?
もちろん、size()
にも役割はあります。
たとえば、コレクション内の要素数を表示したい、サイズに応じた条件分岐をしたい場合などにはsize()
が必要です。
// 要素数を条件に分岐
if (list.size() >= 5) {
// 要素が5件以上あるときの処理
}
// 要素数を表示
System.out.println("要素数: " + list.size());
このように、空かどうかだけを確認したい場合には isEmpty()
、サイズそのものに意味がある場合には size()
と、使い分けがポイントです。
「何を判断したいのか?」を明確にし、それに最も適したメソッドを選びましょう。
まとめ:空判定には isEmpty() を使おう
Javaでコレクションの空判定を行う際は、次の理由から isEmpty()
の使用が推奨されます。
- 読みやすく、意図が明確:空であることが直感的に伝わる
- パフォーマンスに優れる:一部の実装では
size()
より高速 - ベストプラクティスとして定着:多くのプロジェクトで推奨されている
空かどうかを確認したいだけなら、size() == 0
より isEmpty()
を選ぶべきです。
より明確で、安全で、効率的なコードを書くために、今後は isEmpty() を標準にしましょう。
この小さな選択の積み重ねが、保守性の高い高品質なJavaアプリケーションの構築につながります。