Javaで文字列を比較する方法がいくつかあることに気付きました。
大文字小文字を区別する文字列で問題が発生するのを避けるために、equalsIgnoreCase
を使用する習慣がついたばかりです。
一方、他の人はすべてを大文字または小文字で渡すことを好みます。
私が立っている場所から(技術的には座っていても)、本当の違いは見られません。
誰かが一方の練習がもう一方の練習よりも優れているかどうかを知っていますか?もしそうなら、なぜですか?
比較前に両方の文字列を大文字に変換するよりも読みやすいため、equalsIgnoreCase
を使用します。 読みやすさはマイクロ最適化よりも優れています。
もっと読みやすいものは何ですか?
if (myString.toUpperCase().equals(myOtherString.toUpperCase())) {
または
if (myString.equalsIgnoreCase(myOtherString)) {
equalsIgnoreCase
の方が読みやすいことに同意できると思います。
equalsIgnoreCaseは、ロケール固有の違いに関する問題を回避します(例:トルコ語ロケールでは、2つの異なる大文字の「i」文字があります)。一方、Mapsはequals()メソッドのみを使用します。
しかし、後者の問題では、大文字または小文字のいずれかが渡されるという仮定を作成するため、呼び出し元を盲目的に信頼することはできません。そのため、メソッドの開始時にASSERT
ステートメントを含めて、入力が常に期待どおりの場合になるようにする必要があります。
どちらも優れていません。両方とも異なるシナリオで使用されます。
多くの場合、文字列の比較を行う必要がある場合、少なくとも1つの文字列をマッサージして比較しやすくします。これらの場合、比較する前に特定のケースに変換された文字列、トリミングされた文字列などが表示されます。
一方、2つの文字列をオンザフライで大文字と小文字を区別せずに比較したい場合は、equalsIgnoreCase
を自由に使用できます。ただし、多くのequalsIgnoreCase
が表示されている場合は、コードの匂いがする可能性があることに注意してください。
ユースケースに依存します。
1対1の文字列比較を行う場合、equalsIgnoreCaseはおそらく高速です。これは、文字列を反復処理するときに内部的に各文字を大文字にするだけなので(コードはJava.lang.Stringから)、大文字または小文字よりもわずかに高速です同じ比較を実行する前にそれらすべてを:
if (ignoreCase)
{
// If characters don't match but case may be ignored,
// try converting both characters to uppercase.
// If the results match, then the comparison scan should
// continue.
char u1 = Character.toUpperCase(c1);
char u2 = Character.toUpperCase(c2);
if (u1 == u2) {
continue;
}
// Unfortunately, conversion to uppercase does not work properly
// for the Georgian alphabet, which has strange rules about case
// conversion. So we need to make one last check before
// exiting.
if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
continue;
}
}
ただし、大文字と小文字を区別しない方法で、文字列(特に、すべて米国ラテン語/ ASCIIスペースにある文字列)でいっぱいのデータ構造に対してルックアップを実行する状況がある場合は、文字列をすばやくトリム/小文字に変換しますチェックして、HashSetやHashMapのようなものに入れてください。
これは、Listの各要素でequalsIgnoreCaseを呼び出すよりも優れています。これは、equalsIgnoreCase()のわずかなパフォーマンスの向上が、O(n)である配列に対してcontains()の修正バージョンを基本的に実行しているという事実によって相殺されるためです。事前に正規化された文字列を使用すると、O(1)で実行される単一のcontains()呼び出しで文字列のリスト全体をチェックできます。
jDK 8のequalsIgnoreCaseドキュメント
この文字列を別の文字列と比較し、大文字と小文字の考慮を無視します。 2つの文字列が同じ長さであり、2つの文字列内の対応する文字が大文字小文字を無視して等しい場合、2つの文字列は大文字小文字を無視して等しいと見なされます。
次の少なくとも1つが当てはまる場合、2つの文字c1とc2は大文字小文字を無視して同じと見なされます。
私の考え:
したがって、equalsIgnoreCaseを使用して、文字列を反復処理し(サイズ値が同じ場合のみ)、各文字を比較します。最悪の場合、パフォーマンスはO(3cn)になります(n =文字列のサイズ)。余分なスペースは使用しません。
ToUpper()を使用して、文字列が等しいかどうかを比較し、常に各文字列を1回ループし、すべての文字列を上位に変換してから、参照チェック(equals())で等価を実行します。これはtheta(2n + c)です。ただし、toUpperCase()を実行する場合、Javaは不変であるため、実際には2つの新しい文字列を作成する必要があります。
したがって、equalsIgnoreCaseはより効率的で読みやすいと言えます。
繰り返しますが、ユースケースを検討します。なぜなら、それが私にとって最終的な目的だからです。 toUpperアプローチは特定のユースケースで有効かもしれませんが、98%がequalsIgnoreCase()を使用しています。
この記事によると、パフォーマンスに関しては両方とも同じです。
http://www.params.me/2011/03/stringtolowercasestringtouppercase-vs.html
したがって、コードの可読性に基づいて決定します。場合によっては、オブジェクトを作成するために常に単一のメソッドに値を渡す場合はtoLowerCase()の方が適していますが、そうでない場合はequalsIgnoreCase()の方が理にかなっています。
英語のみの文字を使用している場合、toUpperCase()
を呼び出している場合は、比較を開始する前に必ずtoLowerCase()
または.equalsIgnoreCase()
を実行します複数回またはswitch
ステートメントを使用している場合。この方法では、大文字と小文字の変更操作を1回だけ行うため、より効率的です。
たとえば、工場出荷時のパターンでは:
public static SuperObject objectFactory(String objectName) {
switch(objectName.toUpperCase()) {
case "OBJECT1":
return new SubObject1();
break;
case "OBJECT2":
return new SubObject2();
break;
case "OBJECT3":
return new SubObject3();
break;
}
return null;
}
(switch
ステートメントを使用すると、if..else if..else
文字列比較用のブロック)