文字列比較の全体像
Javaでの文字列比較は「参照が同じか(==)」と「内容が同じか(equals)」の二軸があります。日常的に必要なのは内容比較です。さらに「大文字小文字を無視」「辞書順で並べる」「ユーザー向けの言語ルールで比べる」といった場面に応じて、equalsIgnoreCase、compareTo、Collator を使い分けます。まずは安全な基礎(null セーフ、前処理、等価と順序の違い)を体に入れましょう。
== と equals の違い(最重要ポイント)
参照の同一性(==)
== は「同じインスタンスか」を比べます。別々に作られた "OK" は内容が同じでも == は false になります。内容で比べたいときは equals を使います。
String a = new String("OK");
String b = new String("OK");
System.out.println(a == b); // false(参照が違う)
Java内容の同値性(equals)
equals は「文字列の内容が一致するか」を判定します。通常の内容比較はこれ一択です。
String a = "OK";
String b = "OK";
System.out.println(a.equals(b)); // true(内容が同じ)
Javanull セーフな書き方
左が null だと s.equals("OK") は NPE。非 null 側から呼ぶか、Objects.equals(a, b) を使うと安全です。
String s = null;
System.out.println("OK".equals(s)); // 安全
System.out.println(java.util.Objects.equals(s, "OK")); // どちらも安全
Java大文字小文字の扱いと前処理
equalsIgnoreCase で大小無視
ユーザー入力で「OK」と「ok」を同一視したいなら equalsIgnoreCase を使います。
System.out.println("OK".equalsIgnoreCase("ok")); // true
Java前後の空白・フォーマットの正規化
意図した比較の前に、trim() や toUpperCase() などで前処理すると「意味の比較」に近づきます。
String s = " ok ";
boolean match = "OK".equalsIgnoreCase(s.trim()); // 前後空白を除去して比較
JavaUnicode 正規化の注意
見た目は同じでも別コードポイント(例:合成文字)が存在します。厳密な比較が必要なら正規化します。
import java.text.Normalizer;
String n1 = Normalizer.normalize(s1, Normalizer.Form.NFC);
String n2 = Normalizer.normalize(s2, Normalizer.Form.NFC);
boolean same = n1.equals(n2);
Java辞書順・並び替え:compareTo と Collator
文字コード順の比較(compareTo)
compareTo は自然順(Unicode コードポイント順)で比較し、負・0・正を返します。ソートや二分探索の基本に使います。
System.out.println("Apple".compareTo("Banana")); // 負(Apple が先)
System.out.println("a".compareTo("A")); // 正/負はコードポイント依存
Java言語ルールの比較(Collator)
ユーザー向けの並び替えはロケールに従うべきです。Collator は大文字小文字・アクセントの扱いを言語ごとに調整できます。
import java.text.Collator;
import java.util.Locale;
Collator col = Collator.getInstance(Locale.JAPAN);
col.setStrength(Collator.PRIMARY); // 大文字小文字・濁点などを弱くする度合い
System.out.println(col.compare("ばなな", "バナナ")); // 見た目同等を同扱いにできる
JavacompareTo は機械的、Collator は人間に優しい——用途で使い分けます。
部分一致と位置指定の比較
startsWith / endsWith / contains
先頭・末尾・包含の判定は専用メソッドが明快で高速です。
String s = "hello world";
System.out.println(s.startsWith("he")); // true
System.out.println(s.endsWith("ld")); // true
System.out.println(s.contains("wo")); // true
JavaregionMatches で細かく比べる
開始位置や大文字小文字無視を指定して部分比較できます。
String s = "HelloWorld";
boolean ok = s.regionMatches(true, 0, "hello", 0, 5); // ignoreCase=true
System.out.println(ok); // true(先頭5文字、大小無視で一致)
Javaよくある落とし穴(重要ポイントの深掘り)
equals と compareTo の目的違い
equals は「同値判定」、compareTo は「順序付け」。ソートキーに equals を使わない、同値判定に compareTo の結果(0)を安易に流用しないこと。用途ごとに正しいAPIを選びます。
null と空文字の取り扱い
null と ""(空文字)は別物です。入力正規化で「nullなら空に置換」するか、契約として null 禁止を入口で弾く方針を決めましょう。
String normalize(String s) {
if (s == null || s.isBlank()) return "";
return s.trim();
}
Javaインターン化(intern)の誤用
"OK" リテラルはインターンされ、たまたま == が true になる場合があります。これに依存する設計は危険です。常に内容比較は equals を使います。
ロケール依存の大文字小文字
toUpperCase()/toLowerCase() はロケールで挙動が変わる場合があります。英語前提なら Locale.ENGLISH を指定、ユーザー向けなら対象ロケールを意識しましょう。
String k = "istanbul";
System.out.println(k.toUpperCase(Locale.ENGLISH)); // ISTANBUL
Java例題で身につける
例 1: null セーフな内容比較
static boolean isOk(String s) {
return java.util.Objects.equals(s, "OK"); // どちらかが null でも安全
}
Java例 2: 入力を正規化して大小無視の一致
static boolean matchCommand(String input, String expected) {
if (input == null) return false;
return expected.equalsIgnoreCase(input.trim());
}
Java例 3: ユーザー向けの並び替え
import java.text.Collator;
import java.util.*;
public class SortDemo {
public static void main(String[] args) {
var list = new ArrayList<>(List.of("ばなな", "Banana", "バナナ"));
Collator col = Collator.getInstance(Locale.JAPAN);
col.setStrength(Collator.PRIMARY);
list.sort(col);
System.out.println(list);
}
}
Java例 4: 部分比較でプレフィックス判定
static boolean startsWithIgnoreCase(String s, String prefix) {
if (s == null || prefix == null || prefix.length() > s.length()) return false;
return s.regionMatches(true, 0, prefix, 0, prefix.length());
}
Java仕上げのアドバイス(重要部分のまとめ)
文字列比較は「参照(==)ではなく内容(equals)」が基本。大小無視は equalsIgnoreCase、部分一致は startsWith/endsWith/contains、細かな部分比較は regionMatches。並び替えは機械的なら compareTo、人に優しい順序なら Collator。null セーフにし、必要なら空白やUnicodeを正規化して「意味の比較」に寄せる——この型が身につけば、入力処理も検索もソートも、意図どおりに動きます。
