2行まとめ
- 文字列を単純に比較するなら、StringUtils.equals を Java標準APIのObjects.equals に置き換えましょう
- Javaのランタイムが6以下の場合は、同じcommons-langのStringsに置き換えましょう
Apache Commonsは便利なユーティティを提供をしてくれます
Javaアプリケーションを作るときに、さまざまなユーティリティを提供してくれる Apache commons があります。例えば commons-lang、commons-io など、Javaの標準APIだけでも組み合わせれば作れる機能ですが、これらを簡単に扱える機能を提供してくれます。
そんな便利なcommonsの機能も、Java言語仕様のバージョンアップに伴いcommonsの機能を使わなくても実現できるため非推奨になったものがあります。それがタイトルにもある StringUtils.equals() で、これが非推奨メソッドになりました。
StringUtils.equalsが生まれた経緯
StringUtils.equals(s1, s2) は、String型(CharSequence型)の2つを比較して同じ文字列ならtrueを返します。比較する際に s1やs2がnullのときにも気にせず比較できることです。これはかつて、2つの文字列オブジェクトを比較するときに
s1.equals(s2)
とすると、s1はnullだった場合、 NullPointerException がスローされてしまいます。そのため常にnullではないかをチェックするロジックが必要になります。
if (s1 != null) {
if (s1.equals(s2)) {
.....
}
} else {
....
}
これを毎回書くのはちょっと面倒ですね(´・ω・`)
そこで、commons-lang3のStringUtilsを使うと
StringUtils.equals(s1, s2)
これだけです。s1,s2がそれぞれnullであっても気にせず比較できますし、s1,s2が両方nullなら、両方ともnullなので同じである、と判断してtrueを返します。
非推奨メソッドの代替方法
このStringUtils.equalsは Commons-Lang3のバージョン3.18が2025/7/9にリリース
されてから非推奨になりました。
Java側の対応は結構昔からありまして、Java1.7から導入された Objects.equals で比較できます。なのでJavaランタイムのバージョンが余程古くない限り、文字列を比較するときには Commons-Lang3のStringUtilsを使う必要はありません。
サンプルコード
出力には Log4j2 を利用しています。
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class CommonsLang3Sample {
private static final Logger log = LogManager.getLogger(CommonsLang3Sample.class);
public void compare() {
String s1 = new String("abc");
String s2 = new String("abc");
log.info("s1:{}, s2:{}", System.identityHashCode(s1), System.identityHashCode(s2));
log.info("StringUtils:{}", StringUtils.equals(s1, s2));
log.info("Objects:{}", Objects.equals(s1, s2));
}
}
実行結果
12:38:04.854 [main] INFO commons_lang3_sample.CommonsLang3Sample - s1:1107024580, s2:1010856212
12:38:04.858 [main] INFO commons_lang3_sample.CommonsLang3Sample - StringUtils:true
12:38:04.858 [main] INFO commons_lang3_sample.CommonsLang3Sample - Objects:true
s1とs2は別のオブジェクトであることが確認できます。そのうえで、StringUtilsとObjectsの両方もtrueを返すことがわかりました。
ランタイムのバージョンが6以下の場合や、文字列比較の方法を変更したい場合
commons-lang3は最低でもJavaのバージョンは1.5から動作しますので、もしランタイムのバージョンが1.5ないしは1.6(6.0)の場合は、同じ Commons-lang3の Stringsを使います。1
このStringsには2つの比較モードがあり、大文字小文字の違いを区別するかを設定します。
| モード | 用途 |
|---|---|
| CS | Case Sesitive。大文字小文字の違いを区別する |
| CI | Case Insensitive。大文字小文字の違いを区別しない |
サンプルコード
import java.util.Objects;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class CommonsLang3Sample {
private static final Logger log = LogManager.getLogger(CommonsLang3Sample.class);
public void compare() {
String s1 = new String("abc");
String s2 = new String("ABC");
log.info("s1:{}, s2:{}", System.identityHashCode(s1), System.identityHashCode(s2));
log.info("StringUtils:{}", StringUtils.equals(s1, s2));
log.info("Objects:{}", Objects.equals(s1, s2));
log.info("CS:{}", Strings.CS.equals(s1, s2));
log.info("CI:{}", Strings.CI.equals(s1, s2));
}
}
実行結果
12:46:49.042 [main] INFO commons_lang3_sample.CommonsLang3Sample - s1:1107024580, s2:1010856212
12:46:49.046 [main] INFO commons_lang3_sample.CommonsLang3Sample - StringUtils:false
12:46:49.046 [main] INFO commons_lang3_sample.CommonsLang3Sample - Objects:false
12:46:49.046 [main] INFO commons_lang3_sample.CommonsLang3Sample - CS:false
12:46:49.046 [main] INFO commons_lang3_sample.CommonsLang3Sample - CI:true
CSモードのときはfalseで、CIモードのときはtrueになっていることがわかります。これはもちろん、s1とs2の文字列が完全に同じだった場合はtrueを返します。
まとめ
- 単純な文字列の比較なら、Objects.equals を使いましょう
- ランタイムバージョンが6以下の場合は、同じcommons-lang3の Strings.CS.equals を使いましょう
個人的な話
StringUtilsは、いろんなフレームワークやライブラリに独自実装していたり、特定バージョンのcommons-langを内包していたりと乱立するので、個人的にはStringUtilsはもう使わないでいい…という強めの意思があります。
-
commons-long3のStringsは、commons-lang3の3.18から作成された抽象クラスです。 ↩