web-dev-qa-db-ja.com

Java内の2つのオブジェクトを、可能なヌル値と比較します

どちらかまたは両方がnullになる可能性がある場合、Javaで2つの文字列が等しいかどうかを比較したいので、単純に.equals()を呼び出すことはできません。最善の方法は何ですか?

boolean compare(String str1, String str2) {
    ...
}

編集:

return ((str1 == str2) || (str1 != null && str1.equals(str2)));
141
priceline

これはJava内部コードが使用するものです(他のcompareメソッドで):

public static boolean compare(String str1, String str2) {
    return (str1 == null ? str2 == null : str1.equals(str2));
}
153
Eric

Java 7以降では、静的メソッド Objects.equals(Object, Object) を使用して、2つのオブジェクトがnullであることを気にせずに等しいチェックを実行できます。

両方のオブジェクトがnullである場合は、trueを返します。一方がnullであり、もう一方がそうでない場合は、falseを返します。それ以外の場合、最初のオブジェクトで equals を呼び出した結果を返します。

217
Mark Rotteveel

これらの場合、 Apache CommonsStringUtils#equals を使用する方が良いでしょう。すでにnull文字列を処理しています。コードサンプル:

public boolean compare(String s1, String s2) {
    return StringUtils.equals(s1, s2);
}

ライブラリを追加したくない場合は、StringUtils#equalsメソッドの ソースコード をコピーして、必要なときに適用してください。

38
Luiggi Mendoza

API 19のObjects.equals(str1、str2)を使用できないAndroidの場合、次のようになります。

Android.text.TextUtils.equals(str1, str2);

Nullセーフです。 Android上の同一の文字列は、ほとんどの場合、 Androidの文字列プーリング のおかげで、「==」オペランドと真を比較するため、より高価なstring.equals()メソッドを使用する必要はほとんどありません。長さチェックは、ほとんどの不一致を迅速に除外する方法です。

ソースコード:

/**
 * Returns true if a and b are equal, including if they are both null.
 * <p><i>Note: In platform versions 1.1 and earlier, this method only worked  well if
 * both the arguments were instances of String.</i></p>
 * @param a first CharSequence to check
 * @param b second CharSequence to check
 * @return true if a and b are equal
 */
public static boolean equals(CharSequence a, CharSequence b) {
    if (a == b) return true;
    int length;
    if (a != null && b != null && (length = a.length()) == b.length()) {
        if (a instanceof String && b instanceof String) {
            return a.equals(b);
        } else {
            for (int i = 0; i < length; i++) {
                if (a.charAt(i) != b.charAt(i)) return false;
            }
            return true;
        }
    }
    return false;
}
25
NameSpace

バージョン3.5以降、Apache Commons StringUtilsには次のメソッドがあります。

static int  compare(String str1, String str2)
static int  compare(String str1, String str2, boolean nullIsLess)
static int  compareIgnoreCase(String str1, String str2)
static int  compareIgnoreCase(String str1, String str2, boolean nullIsLess)

これらは、nullセーフな文字列比較を提供します。

7
phn

Apache Commons StringUtilsクラスのequals(-、-)およびequalsIgnoreCase(-、-)メソッドを使用して2つの文字列を比較します。

StringUtils.equals(-、-)

StringUtils.equals(null, null)   = true
StringUtils.equals(null, "abc")  = false
StringUtils.equals("abc", null)  = false
StringUtils.equals("abc", "abc") = true
StringUtils.equals("abc", "ABC") = false

StringUtils.equalsIgnoreCase(-、-)

StringUtils.equalsIgnoreCase(null, null)   = true
StringUtils.equalsIgnoreCase(null, "abc")  = false
StringUtils.equalsIgnoreCase("xyz", null)  = false
StringUtils.equalsIgnoreCase("xyz", "xyz") = true
StringUtils.equalsIgnoreCase("xyz", "XYZ") = true
3
Prashant Sahoo

Java 8:を使用する

private static Comparator<String> nullSafeStringComparator = Comparator
        .nullsFirst(String::compareToIgnoreCase); 

private static Comparator<Metadata> metadataComparator = Comparator
        .comparing(Metadata::getName, nullSafeStringComparator)
        .thenComparing(Metadata::getValue, nullSafeStringComparator);

public int compareTo(Metadata that) {
    return metadataComparator.compare(this, that);
}
2
TanvirChowdhury
boolean compare(String str1, String str2) {
    if(str1==null || str2==null) {
        //return false; if you assume null not equal to null
        return str1==str2;
    }
    return str1.equals(str2);
}

これはあなたが望んだものですか?

2
didxga

Java.util.Objectsは次のように使用できます。

public static boolean compare(String str1, String str2) {
    return Objects.equals(str1, str2);
}
1
boolean compare(String str1, String str2) {
    if (str1 == null || str2 == null)
        return str1 == str2;

    return str1.equals(str2);
}
1
Kierrow
boolean compare(String str1, String str2) {
  return (str1==null || str2==null) ? str1 == str2 : str1.equals(str2);
}
1
Sumit Singh

OK、それでは「最良の解決策」とはどういう意味ですか?

最も読みやすいという意味であれば、可能なすべてのソリューションは、経験豊富なJavaプログラマーにとってほぼ同等です。しかし、最も読みやすいIMOはこれです

 public boolean compareStringsOrNulls(String str1, String str2) {
     // Implement it how you like
 }

つまり、(理想的には)インライン化できる単純なメソッド内の実装を非表示にします。

(コードベースで既に使用している場合は、サードパーティのユーティリティライブラリに「アウトソース」することもできます。)


パフォーマンスが最も高い場合、次のとおりです。

  1. 最もパフォーマンスの高いソリューションは、プラットフォームとコンテキストに依存します。
  2. 「コンテキスト」の問題の1つは、null引数の相対(動的)発生頻度です。
  3. それおそらくどちらのバージョンが速いかは関係ありません...おそらく、アプリケーション全体のパフォーマンスに差をつけるには差が小さすぎるためです。
  4. それが問題になる場合、プラットフォーム上でどれが最も速いかを判断する唯一の方法は、両方のバージョンを試して、違いを測定することです。
0
Stephen C