はじめに
Javaで条件分岐を書くときは、値を比べてtrueまたはfalseを得る比較演算子の理解が土台になります。その判定結果はif、else、while、forなどの制御構文に渡され、処理を続けるか、分岐するか、繰り返すかを決めます。
初心者がつまずきやすいのは、数値の比較とオブジェクトの比較を同じ感覚で扱ってしまう点です。そのため、==、!=、<、>、<=、>=の使い方に加えて、equals、compareTo、Comparatorの考え方まで一続きで整理するのが目安です。
- Java SE 21 / OpenJDK 21
- 標準ライブラリのみ使用
- Javaの比較演算子が返す
booleanの考え方 ==とequalsを混同しない判断基準- 数値、文字列、日付、配列で使うサンプルコードの読み方
NaNやnullで起こる注意点と対処法Comparatorで比較ルールを作る応用例
公式ドキュメントによれば、Javaの関係演算子や等価演算子はboolean値を返す式として定義されています。正確な仕様を確認したい場合は、Java Language SpecificationのRelational Operatorsと、Equality Operatorsが一次情報になります。
Javaの比較演算子とは
結論として、Javaの比較演算子は左右の値を比べ、条件式として使えるtrueまたはfalseを返するのがポイントです。最小のサンプルコードなら、int score = 80;に対してscore >= 60と書くことで、合格ライン以上かどうかを判定できます。
これらの比較演算子は、intやdoubleなどのプリミティブ型で特に素直に働きます。その結果をifの丸括弧内に置くと、条件が満たされた場合だけ処理を進められますし、ここがポイントです。
| 演算子 | 意味 | 主な対象 | 例 | 初心者向けの注意点 |
|---|---|---|---|---|
== | 等しい | 数値、真偽値、参照 | a == b | 参照型では同一オブジェクトかを見ます |
!= | 等しくない | 数値、真偽値、参照 | a != b | nullチェックでよく使います |
< | より小さい | 数値、文字 | a < b | 文字列には直接使えません |
> | より大きい | 数値、文字 | a > b | 境界値を含まない判定です |
<= | 以下 | 数値、文字 | a <= b | 上限や下限を含める条件に向きます |
>= | 以上 | 数値、文字 | a >= b | 合格点や年齢制限の判定で使います |
equals | 内容が等しい | Stringなど | s.equals(t) | nullの呼び出しに注意します |
compareTo | 大小関係を整数で返す | String、日付 | x.compareTo(y) | 戻り値の符号で前後を判断します |
基本的な比較演算子の概要
基本的に==と!=は等価性、<と>は大小関係、<=と>=は境界値を含む大小関係を扱います。この分類を押さえると、Javaの比較演算子を読むときに条件の意図を追いやすくなります。
その違いは、年齢、点数、在庫数、日付の順序など、判定したい対象の性質に合わせて選びますが、これは押さえたい点です。たとえば「60点以上」は>=、「60点より上」は>になり、1文字の違いで境界値の扱いが変わります。
これをコードレビューの観点で読む場合、条件式の記号だけでなく、仕様上の境界がどこにあるかを確認します。初心者向けの解説では、0、1、最大値、最小値のような端の値をサンプルコードに含めると、条件のズレを発見しやすくなるのが一般的です。
==(等しい)とは
==は左右が等しいかを判定する比較演算子です。数値なら値そのものを比べますが、Stringなどの参照型では同じオブジェクトを指しているかを調べるため、初心者は文字列比較で誤用しやすい箇所になります。
!=(等しくない)とは
!=は左右が等しくない場合にtrueを返します。そのため、value != nullのように、オブジェクトが存在するかを確認してからメソッドを呼ぶ流れでよく使われますし、これが一つの目安です。
<(より小さい)とは
<は左辺が右辺より小さい場合だけtrueになります。上限を超える前にループを止めるi < array.lengthの形は、Javaの配列処理で頻出します。
>(より大きい)とは
>は左辺が右辺より大きい場合にtrueを返するのが現実的です。一方、右辺と同じ値は含まれないため、「基準値以上」を判定したい場面では>=を選ぶ必要があります。
<=(以下)とは
<=は左辺が右辺以下であることを確かめます。たとえばage <= 12なら12を含むため、境界値を含める使い方として整理できると整理できます。
>=(以上)とは
>=は左辺が右辺以上のときにtrueになります。合格点、最小購入数、年齢条件など、下限を含めて判定する処理に向いた比較演算子です。
💡 Tips:<と>は境界値を含まず、<=と>=は境界値を含みます。条件式を読むときは、境界の値そのものが通るかを先に確認すると整理しやすくなると理解できます。
比較演算子の詳しい使い方
Javaの比較演算子の使い方は、単独の式として覚えるより、条件分岐やループの中で読むほうが身につきます。そのため、各サンプルコードでは変数を用意し、条件式がどの値を比べているかを明確にします。
具体的には、等価性、大小関係、範囲判定の順に見ると理解しやすくなると覚えるとよいでしょう。サンプルコードの直後には期待される出力を示すため、手元の環境で動かす際の目安として使えます。
サンプルコード1:==と!=の基本的な使用例
このサンプルコードでは、int型のaとbを使い、==と!=の結果を表示します。初心者向けの解説としては、同じ2変数でも演算子を変えるだけでbooleanの値が反転する点に注目すると考えられます。
結果: 期待される出力はa == b: falseとa != b: trueです。aは5、bは10なので、等しい判定は偽、等しくない判定は真になります。
サンプルコード2:<と>の応用的な使用例
<と>は、数値の大小関係をそのまま条件にできます。Javaの条件分岐では、点数、在庫、年齢、回数などを比べる場面が多く、比較演算子の使い方を理解しておくと判断式を短く書けると言えるでしょう。
結果: 期待される出力はaはbより小さいです。5 < 8はtrueですが、5 > 8はfalseになるため、後者のブロックは実行対象になりません。
これをリスト処理に広げると、各要素を順に取り出して条件に合う値だけを扱えます。Javaのコレクションを詳しく学ぶ場合は、Java List型完全ガイドも合わせて確認すると、ListとArrayListの関係を整理できます。
結果: 期待される出力は7は5より大きいと8は5より大きいです。for文がnumbersの要素を順に取り出し、number > 5を満たす値だけがprintlnに渡されます。
サンプルコード3:<=と>=を組み合わせた複雑な条件
範囲判定では、下限に>=、上限に<=を置く形がよく使われます。その条件を&&でつなぐと、「両方を満たす場合だけ真」という意味になるのが基本です。
結果: 期待される出力はxは1以上10以下の範囲にありますです。x >= 1とx <= 10がどちらもtrueになり、if側の処理が選ばれます。
比較演算子の応用例
Javaの比較演算子は数値だけでなく、文字列、オブジェクト、日付、配列処理の判断にも関わります。ただし、対象が参照型になると==だけでは内容比較にならないため、equalsやcompareToなどのメソッドを使い分けますが、覚えておくと役立つでしょう。
サンプルコード4:文字列の比較
文字列の比較では、==ではなくequalsで内容を比べるのが一般的です。大小関係や辞書順を扱う場合はcompareToを使い、戻り値が負、0、正のどれかで順序を判断します。詳細な戻り値や比較規則は、String.compareToの公式ドキュメントを参照できます。
結果: 期待される出力は、false、true、正の整数、0の順です。"Java"と"JAVA"は大文字小文字が異なるためequalsでは一致せず、compareToではUnicode値に基づく差が返ります。
サンプルコード5:オブジェクトの比較
オブジェクトの比較では、==が参照の同一性、equalsが内容の等価性を扱うと分けて考えます。この違いは、Javaのオーバーライド解説で扱うequalsの再定義ともつながりますし、ここを基本と考えるとよいでしょう。
結果: 期待される出力はfalseです。str1とstr2はどちらも"Hello"という内容を持ちますが、別々に生成されたStringオブジェクトを参照しています。
結果: 期待される出力はtrueです。Stringクラスは内容比較のためにequalsを実装しているため、別インスタンスでも文字列が同じなら真になります。
サンプルコード6:日付の比較
日付の比較では、単純な比較演算子よりも日付クラスのメソッドを使うのが自然です。Java 8以降ではjava.timeパッケージが標準的な選択肢になり、LocalDate、LocalDateTime、ZonedDateTimeなどを用途で選びますし、ここがポイントです。
Dateの年・月・日を整数で渡すコンストラクタは非推奨です。既存コードの読解目的に留め、新しいJavaコードではLocalDate.ofを選ぶと整理しやすくなります。結果: 期待される出力はdate1はdate2より前ですです。compareToは、呼び出し元が引数より前なら負の整数、同じなら0、後なら正の整数を返します。
現行の書き方ではLocalDateを使い、isBefore、isAfter、isEqualで判定します。公式APIの詳細はLocalDateの公式ドキュメントで確認できるのが目安です。
結果: 期待される出力はdate1はdate2より前ですです。LocalDate.of(2023, 9, 13)はLocalDate.of(2023, 9, 20)より前の日付なので、isBeforeがtrueになります。
サンプルコード7:配列の要素の比較
配列の要素を比較する場合は、同じ添字の値を取り出して比較演算子に渡します。配列全体が同じかを調べる処理と、要素ごとの一致を調べる処理は別物なので、目的を切り分ける必要があるのがポイントです。
結果: 期待される出力は、同じ添字の値が一致するかどうかを5行で示す内容です。array1[2]とarray2[2]、array1[3]とarray2[3]は一致し、それ以外は一致しません。
結果: 期待される表示は、0番目、1番目、4番目が不一致、2番目と3番目が一致という判定です。配列の長さが異なる可能性がある場合は、短いほうの長さに合わせる、または事前にarray1.length == array2.lengthを確認します。
注意点と対処法
比較演算子の注意点は、見た目は単純でも、対象の型によって結果の意味が変わるところにあります。特にNaN、null、参照型、境界値は、初心者のバグにつながりやすい論点です。そのため、条件式が期待どおりに動かないときは、値そのもの、型、nullの可能性、境界値の含み方を順番に確認するのが一般的です。エスケープ文字を含む文字列を比較する場合は、Javaエスケープ処理の解説も関連するのが基本です。
NaNの扱い
NaNはNot a Numberを表す特殊な浮動小数点値です。Javaではdoubleやfloatの計算で発生し、通常の数値比較とは異なる結果になります。
結果: 期待される出力はfalse、true、falseの順です。0.0 / 0.0で得られるNaNは通常の比較演算子では検出しにくいため、専用メソッドを使う必要があります。
結果: 期待される出力はtrueです。Double.isNaN(result)は、resultがNaNかどうかを直接判定します。
nullとの比較
nullは、参照がどのオブジェクトも指していない状態を表するのが現実的です。Javaではnullに対してメソッドを呼ぶとNullPointerExceptionが発生するため、比較演算子による事前確認が有効です。
結果: 期待される出力はtrueとfalseです。strにはnullが入っているため、str == nullは真、str != nullは偽になります。
その後にstr.length()のようなメソッドを呼ぶなら、if (str != null)で囲むか、Objects.requireNonNull、Optional、入力バリデーションなどを組み合わせます。アノテーションで@NonNullや@Nullableを示す設計に関心がある場合は、Javaアノテーションのガイドも参考になると整理できます。
Objects.equals(a, b)は、片方または両方がnullでも安全に等価性を判定できます。文字列だけでなく、参照型全般の比較で検討できます。比較演算子のカスタマイズ方法
Javaでは<や>などの比較演算子そのものをユーザー定義型向けにオーバーロードできません。その代わり、独自の並び順や比較ルールはComparator、Comparable、compare、compareToで表現すると理解できます。
結果: このコード自体は比較ルールを定義するクラスなので、単独ではコンソール出力を行いません。compareメソッドは、o1 % 2とo2 % 2の差を返し、偶数と奇数の順序を決める材料になります。
結果: 期待される出力は2、4、1、3、5の順です。o % 2は偶数で0、奇数で1になるため、昇順ソートでは偶数が先に並びます。
結果: 期待される出力は2、4、1、3、5の順です。ラムダ式でもCustomComparatorと同じ計算を渡しているため、奇偶による並び替えの結果は同じになります。
使い分けると、再利用する比較ルールはクラスや定数として切り出し、一度だけ使う短いルールはラムダ式にすると見通しがよくなります。うるう年のように条件式を組み合わせる判定では、Javaでうるう年を判定する解説も比較演算子の練習になると覚えるとよいでしょう。
💡 Tips:Comparatorの戻り値は、負なら左を先、0なら同等、正なら右を先にする判断材料です。大小比較の結果を直接返すより、Integer.compareを使うとオーバーフローを避けやすくなります。
まとめ
Javaの比較演算子は、条件分岐、ループ、入力チェック、コレクション処理の判断を支える構文です。==、!=、<、>、<=、>=は短い記号ですが、境界値や型の違いによって意味が変わります。
その中でも、数値は比較演算子、文字列やオブジェクトはequals、順序付けはcompareToやComparatorと整理すると、初心者でも判断を間違えにくくなると考えられます。サンプルコードを読む際は、比較対象、戻り値、条件が真になった後の処理をセットで追うのが効果的です。
ただし、NaNやnullは通常の値と同じ感覚で扱うと不具合につながります。Double.isNaN、Objects.equals、LocalDateの比較メソッドなど、標準APIを組み合わせることで、注意点を避けながら読みやすいJavaコードにできます。
比較演算子の使い方を身につけると、if文の条件、配列の走査、リストの抽出、日付の前後判定、独自ソートまで応用できると言えるでしょう。基礎の記号を正確に読む力が、より大きなJavaプログラムの理解につながります。
これらの判断を学習するときは、条件式だけを暗記するよりも、入力値と期待される分岐を並べて読むほうが定着します。その作業を繰り返すと、比較演算子の使い方だけでなく、サンプルコードに隠れた境界値の意図も見えやすくなるのが基本です。
その観点では、条件式を短く保つことも大切になります。複数の比較演算子を一行に詰め込むより、途中の判定をboolean変数へ分けると、初心者でも処理の流れを追いやすくなります。
一方、分割しすぎると変数が増えて読みにくくなる場合もあるのが目安です。判断基準は、条件名だけで仕様が伝わるか、同じ条件を複数箇所で再利用するか、テストしやすくなるかという点に置くと整理できます。
具体的には、年齢判定ならisAdult、範囲判定ならinRange、入力検証ならisValidのように名付けます。名前が条件の解説になれば、比較演算子の記号を読む負担を減らせますが、これは押さえたい点です。
ただし、==とequalsの違いは名前だけでは補えません。参照型を扱う処理では、比較したいものが同じインスタンスなのか、同じ内容なのかを先に決める必要があります。
この違いを曖昧にすると、文字列、ラッパークラス、独自クラスで結果が変わります。Javaの比較演算子を正しく使うには、値の種類と比較の目的をセットで確認する姿勢が欠かせません。
一般に、数値の境界値は仕様書や画面文言にも現れますし、これが一つの目安です。「未満」「以下」「超過」「以上」の言葉をコードへ移すときは、<、<=、>、>=のどれに対応するかを丁寧に合わせます。
その対応がずれると、ちょうど境界の値だけ誤判定されます。テストデータには境界の直前、境界そのもの、境界の直後を含めると、比較演算子の注意点を早い段階で発見できるのがポイントです。
同様に、日付の比較では時刻を含むかどうかが結果を左右します。日単位で判断したいならLocalDate、時刻まで含めたいならLocalDateTimeやInstantを選びます。
使い分けると、Javaの比較処理は読みやすくなるのが一般的です。数値は演算子、文字列はequals、順序はcompareTo、並び替えはComparatorという分担で考えると、応用例にも対応しやすくなります。
これらの基準は、初心者向けの小さなサンプルコードから業務規模のコードまで共通します。条件式が複雑になったときほど、比較対象、境界値、nullの可能性を順に確認すると、原因を切り分けやすくなるのが現実的です。
そのため、比較演算子を学ぶ目的は記号を覚えるだけではありません。条件を仕様どおりにコードへ落とし込み、読み手が意図を追える形に整えることまで含めて理解すると、Javaコードの品質が安定します。
これらの補足を踏まえると、比較演算子は単なる記号ではなく、仕様の言葉をプログラムへ変換するための道具になります。たとえば「18歳以上」「在庫が0より大きい」「締切日以前」という条件は、それぞれ境界値の扱いが異なるため、コードへ移す前に文言を分解すると整理できます。
その分解では、左辺に何を置くかも読みやすさに影響します。limit >= valueよりvalue <= limitのほうが自然に読める場面があり、チームで似た書き方をそろえると条件式の解説が少なく済みます。
ただし、定数を左に置く書き方が有効な場面もあると理解できます。null == valueのようなスタイルは好みが分かれますが、Javaでは代入式を条件に置けないため、可読性を優先してvalue == nullを選ぶ例も多く見られます。
このように、正しい比較演算子を選んだ後は、読み手が誤解しない順序で式を並べることが課題になります。条件式が文章として自然に読めると、サンプルコードから実際の処理へ移したときも保守しやすくなると覚えるとよいでしょう。
一方、複数条件を扱う場合は、&&と||の優先順位にも注意します。丸括弧を使って(age >= 20 && hasTicket) || isStaffのようにまとまりを示すと、比較演算子の結果がどの論理演算へ渡るかを読み取りやすくなります。
具体的には、条件が長いときほど否定を減らすと読みやすくなると考えられます。!(score < 60)よりscore >= 60のほうが意図を追いやすく、初心者向けの解説でも境界値の説明を短くできます。
そのほか、浮動小数点数の等価比較にも注意が必要です。計算誤差を含むdoubleを==で比べると期待と異なる場合があるため、差の絶対値が許容範囲内かをMath.absで見る設計が使われます。
これらの注意点は、比較演算子のサンプルコードをそのまま暗記するだけでは見落とされがちです。値の型、計算の過程、境界値、nullの可能性を合わせて読むことで、条件式の信頼性を高められますが、覚えておくと役立つでしょう。
同様に、Comparatorでは戻り値の符号を安定させることが大切になります。compare(a, b)とcompare(b, a)の関係が崩れると、ソート結果が不安定になるため、比較ルールは一貫した順序を返すように設計します。
そのため、複数フィールドの比較では、最初の条件で差が出たら返し、同じ場合だけ次の条件を見る形にすると言えるでしょう。thenComparingを使うと、この流れを標準APIの形で表現でき、比較演算子を手作業で並べるより意図が伝わります。
基本的に、条件式の品質はテストしやすさにも直結します。境界値、代表値、異常値を表にしてからサンプルコードを動かすと、比較演算子の使い方と期待される出力の対応を確認しやすくなるのが基本です。
こうした確認を習慣にすると、Javaの比較演算子は制御構文の部品としてだけでなく、仕様を正確に表す表現として扱えるようになります。小さな条件式を丁寧に書くことが、配列処理、日付判定、独自ソートなどの応用例にもつながります。
この整理は、コードを書いた後の見直しにも役立ちますし、ここを基本と考えるとよいでしょう。条件式を読み返すときは、左辺と右辺を入れ替えても意味が保てるか、境界値を含めるか、否定条件が多すぎないかを確認します。
その確認で違和感がある場合は、比較演算子を変えるだけでなく、変数名や処理の分割も見直します。if文の中身が長いほど、条件式そのものに説明力を持たせることが必要になるのが目安です。
一方、短い条件でも仕様が複雑な場合はコメントが助けになります。ただし、コメントは記号の説明ではなく、「なぜその境界値を含めるのか」「なぜequalsを使うのか」を補う形にすると価値が出ます。
具体的には、料金計算、年齢判定、期限判定、権限判定のように利用者へ影響する処理では、比較演算子の選択が結果に直結するのがポイントです。サンプルコードで小さく確認した考え方を、そのまま仕様確認へつなげることが大切です。
これらを踏まえると、Javaの比較演算子は初心者の段階で丁寧に身につけたい構文になります。記号の意味、型ごとの違い、標準APIとの使い分けを押さえることで、条件分岐の読み書きが安定します。
その積み重ねにより、単純なif文から、コレクションの抽出、日付の前後判定、カスタムソートまで同じ考え方で扱えますし、ここがポイントです。比較演算子の基礎を固めることは、Javaコード全体の理解を支える実践的な学習になります。
このとき、比較対象が外部入力なら、型変換の前後で条件を分けると安全に扱えます。文字列を数値へ変換してから>=で比べるのか、空文字や未入力を先に除外するのかを決めると、例外処理も読みやすくなるのが一般的です。
その判断は、サンプルコードを実際のフォーム処理やファイル読み込みへ広げるときに役立ちます。比較演算子の前に入力検証を置くことで、null、空文字、不正な数値形式を分けて対処できます。
一般に、条件式は短くても仕様の影響範囲が広い部分です。Javaで比較演算子を使う際は、期待される出力だけでなく、期待しない入力を受けた場合の分岐まで考えると、実用的なコードへ近づきますが、これは押さえたい点です。
この確認を自動テストへ移す場合は、正常値だけでなく、境界値、null相当の入力、NaNを生む計算を分けて用意します。比較演算子の使い方をテストデータで表現できると、仕様変更時の影響も追跡しやすくなります。
その際、条件式の左右を入れ替えた場合に意味が保てるかも確認するのが現実的です。小さな見直しでも、比較演算子の誤用を早く見つけられます。
境界値の表を残すと、後から条件の意図も追いやすくなります。
関連記事
- Java List型完全ガイド!初心者でもマスターできる7つのステップ
- Javaアノテーションの12選!初心者から上級者まで徹底ガイド
- Javaでうるう年を判定!初心者でも分かる9ステップ解説
- Javaエスケープ処理の10ステップマスターガイド
- Javaでマスターする!オーバーライドのたった7つのステップ
※本記事は実在のエンジニア複数名で構成される Japanシーモア編集部が、AI支援を活用して作成・校正・公開しています。


