はじめに
JavaでListにデータが入っているか確認するとき、次のようなコードを思いつくかもしれません。
if (userList.size() > 0) {
// データが存在する場合の処理
}
一見すると問題なさそうですが、userListがnullだった場合、このコードはNullPointerExceptionを発生させてしまいます。
そこで、Javaの開発では次のような書き方を見かけることがあります。
if (!CollectionUtils.isEmpty(userList)) {
// データが存在する場合の処理
}
では、なぜわざわざCollectionUtils.isEmpty()を使うのでしょうか。
この記事では、
-
nullと「0件」の違い -
list.size() > 0の問題点 -
nullチェックを組み合わせる方法 -
CollectionUtils.isEmpty()の役割 - それぞれの書き方の違い
について、Java初心者向けに解説します。
対象読者
- Javaプログラミングを学び始めたばかりの初学者
-
Listなどのコレクションにおけるnullと「0件」の違いを知りたい方 - Javaのコードで
CollectionUtils.isEmpty()を見かけたものの、何をしているのか分からない方 -
list.size() > 0とCollectionUtils.isEmpty(list)の違いを知りたい方
1. まず知っておきたい「null」と「空」の違い
CollectionUtils.isEmpty()を理解するためには、まずnullと「空のリスト」の違いを理解しておく必要があります。
例えば、次の2つの変数を考えてみます。
List<String> userList = null;
これは、userListがリストそのものを参照していない状態です。
一方、こちらはどうでしょうか。
List<String> userList = new ArrayList<>();
こちらはリスト自体は存在しています。
ただし、中にデータが1件も入っていません。
つまり、
null
→ リストそのものが存在しない
空のリスト
→ リストは存在するが、要素が0件
という違いがあります。
この2つは似ているようで、Javaでは別の状態です。
2. list.size() > 0だけでは危険
リストにデータが存在するか確認するために、次のようなコードを書くことがあります。
List<String> userList = getUserList();
if (userList.size() > 0) {
System.out.println("データが存在します");
}
userListにデータが入っていれば問題なく動作します。
しかし、もしgetUserList()の戻り値がnullだったらどうなるでしょうか。
List<String> userList = null;
if (userList.size() > 0) {
// 処理
}
nullの変数に対して.size()を呼び出しているため、NullPointerExceptionが発生します。
java.lang.NullPointerException
Javaでは、nullを参照してメソッドを呼び出すことはできません。
例えば、次のようなコードも同様です。
userList.size();
userList.isEmpty();
userList.get(0);
userListがnullの場合、いずれもNullPointerExceptionの原因になります。
そのため、list.size() > 0は、対象のリストが絶対にnullにならないことが保証されている場合に使う必要があります。
3. nullチェックを追加する方法
では、nullの場合にもエラーにならないようにするにはどうすればよいでしょうか。
次のように書くことができます。
List<String> userList = getUserList();
if (userList != null && userList.size() > 0) {
System.out.println("データが存在します");
}
ここでは、
userList != null
でnullではないことを確認したあと、
userList.size() > 0
でデータが1件以上存在するか確認しています。
&&には**短絡評価(ショートサーキット)**という仕組みがあります。
左側の条件がfalseだった場合、右側の条件は評価されません。
そのため、
userList != null
がfalseなら、
userList.size() > 0
は実行されません。
結果として、NullPointerExceptionを防ぐことができます。
この書き方はJavaの標準的な書き方なので、CollectionUtilsを使わない場合にも覚えておくと便利です。
4. CollectionUtils.isEmpty()とは?
ここで登場するのがCollectionUtils.isEmpty()です。
例えば、Spring Frameworkを使用している場合は、次のように書けます。
import org.springframework.util.CollectionUtils;
List<String> userList = getUserList();
if (!CollectionUtils.isEmpty(userList)) {
System.out.println("データが存在します");
}
CollectionUtils.isEmpty()は、コレクションがnullまたは空であるかを判定するためのメソッドです。
つまり、
CollectionUtils.isEmpty(userList)
は、
userListはnullまたは空ですか?
という判定を行います。
そのため、次のような状態ではtrueになります。
userList == null
または、
userListの要素数が0
逆に、
!CollectionUtils.isEmpty(userList)
と!を付けると、
userListは空ではありませんか?
という意味になります。
つまり、
if (!CollectionUtils.isEmpty(userList)) {
System.out.println("データが存在します");
}
は、
userListがnullではなく、1件以上のデータが存在する場合に処理する
という意味になります。
5. CollectionUtils.isEmpty()の動きを理解する
CollectionUtils.isEmpty()の考え方はシンプルです。
イメージとしては、次のような処理です。
public static boolean isEmpty(Collection<?> collection) {
return collection == null || collection.isEmpty();
}
つまり、
- コレクションが
nullか確認する -
nullでなければ、空かどうか確認する
という処理をまとめて行っています。
例えば、次の3つを比較してみましょう。
nullの場合
List<String> userList = null;
CollectionUtils.isEmpty(userList);
結果は、
true
です。
空のリストの場合
List<String> userList = new ArrayList<>();
CollectionUtils.isEmpty(userList);
結果は、
true
です。
データが入っている場合
List<String> userList = new ArrayList<>();
userList.add("田中");
CollectionUtils.isEmpty(userList);
結果は、
false
です。
このように、nullと0件をまとめて「空」として判定できます。
6. !CollectionUtils.isEmpty()は何を意味する?
実務のコードでは、次の書き方をよく見かけます。
if (!CollectionUtils.isEmpty(userList)) {
// 処理
}
初心者の方は、!が付いていることで少し分かりにくく感じるかもしれません。
まず、
CollectionUtils.isEmpty(userList)
は、
「
userListは空ですか?」
という意味です。
その前に!を付けると、
!CollectionUtils.isEmpty(userList)
となり、
「
userListは空ではありませんか?」
という意味になります。
つまり、
if (!CollectionUtils.isEmpty(userList)) {
// 処理
}
は、
「
userListにデータが存在する場合に処理する」
と読み取ることができます。
コードを読むときは、次のように覚えておくと分かりやすいです。
CollectionUtils.isEmpty(list)
→ null または 0件
!CollectionUtils.isEmpty(list)
→ nullではなく、1件以上
7. 3つの書き方を比較する
ここまでの内容を整理すると、次のようになります。
| 書き方 |
nullの場合 |
0件の場合 | 1件以上の場合 |
|---|---|---|---|
list.size() > 0 |
NullPointerException |
false |
true |
list != null && !list.isEmpty() |
false |
false |
true |
!CollectionUtils.isEmpty(list) |
false |
false |
true |
例えば、
if (list.size() > 0) {
は短く書けますが、listがnullになる可能性がある場合は注意が必要です。
一方、
if (list != null && !list.isEmpty()) {
であれば、nullの場合にも安全に判定できます。
さらに、Spring FrameworkのCollectionUtilsを利用できる環境であれば、
if (!CollectionUtils.isEmpty(list)) {
と書くことで、同じ判定をより簡潔に表現できます。
8. CollectionUtils.isEmpty()を使うときの注意点
ここまで読むと、
「リストの判定には常に
CollectionUtils.isEmpty()を使えばいいのでは?」
と思うかもしれません。
しかし、必ずしもそうとは限りません。
例えば、プロジェクトによっては、
if (list != null && !list.isEmpty()) {
// 処理
}
という書き方をコーディング規約として採用している場合があります。
また、Spring Frameworkなどの外部ライブラリを使用していない場合は、SpringのCollectionUtilsを利用できないこともあります。
そのため、実際の開発では、
- プロジェクトのコーディング規約
- 使用しているフレームワークやライブラリ
- チーム内で統一されている書き方
などを確認することが大切です。
重要なのは、CollectionUtils.isEmpty()というメソッド名だけを覚えることではありません。
「nullと空のコレクションを安全に判定するための方法がある」ことを理解しておくことが大切です。
9. 実際のコードを読むときのポイント
例えば、既存のコードで次のような記述を見つけたとします。
if (!CollectionUtils.isEmpty(userList)) {
process(userList);
}
このコードを初めて見た場合、
「何をしているのだろう?」
と疑問に思うかもしれません。
この場合は、
CollectionUtils.isEmpty(userList)
が、
userListがnullまたは0件か?
を判定していると考えます。
そして先頭に!があるため、
userListが空ではない場合
にprocess(userList)を実行している、と読み解くことができます。
このように、既存コードを読むときは、
!CollectionUtils.isEmpty(...)
を見たら、
「データが存在する場合の処理だな」
と理解できるようになると、コードを読むのが少し楽になります。
さいごに
CollectionUtils.isEmpty()は、コレクションがnullまたは空であるかを判定するために利用できるメソッドです。
Javaでは、
null
と、
要素数が0のリスト
は異なる状態です。
そのため、単純に、
list.size() > 0
と書くと、listがnullだった場合にNullPointerExceptionが発生する可能性があります。
nullチェックを自分で行う場合は、
list != null && !list.isEmpty()
と書くことができます。
また、Spring FrameworkのCollectionUtilsを利用できる環境では、
!CollectionUtils.isEmpty(list)
と書くことで、
「
nullではなく、1件以上のデータが存在する」
ことを簡潔に表現できます。
実際の開発では、プロジェクトのルールや使用しているライブラリに合わせて書き方を選ぶことが重要です。
まずは、
CollectionUtils.isEmpty(list)
は、
「
nullまたは0件か?」
!CollectionUtils.isEmpty(list)
は、
「
nullではなく、1件以上あるか?」
と理解しておくと、既存のJavaコードを読むときにも役立ちます。