Сравнить две строки в Java с возможными значениями null

Я хочу сравнить две строки для равенства в Java, когда любой или оба могут быть null, поэтому я не могу просто позвонить .equals(). Каков наилучший способ?

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

Edit:

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

11 ответов


это то, что использует внутренний код Java (на другом compare методы):

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

начиная с Java 7 Вы можете использовать статический метод Objects.equals(Object, Object) выполнять равные проверки на двух объектах, не заботясь о том, что они null.

если оба объекта null вернет true, Если null а другой не вернется false. В противном случае он вернет результат вызова equals на первом объекте со вторым в качестве аргумента.


для этих случаев было бы лучше использовать Apache Commons StringUtils#равна, он уже обрабатывает пустые строки. Пример кода:

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

Если вы не хотите добавлять библиотеку, просто скопируйте исходный код на StringUtils#equals метод и применять его, когда вам это нужно.


для тех, кто на android, кто не может использовать объекты API 19.метод Equals(str1 выглядит следующим образом, стр2), есть это:

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

это null безопасно. Он редко должен использовать более дорогую строку.метод equals (), потому что идентичные строки на android почти всегда сравнивают true с операндом "==" благодаря строка пула Android, а проверки длины-быстрый способ отфильтровать большинство несоответствий.

Исходный Код:

/**
 * 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;
}

начиная с версии 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 безопасное сравнение строк.


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);
}

это то, что вы желали?


boolean compare(String str1, String str2) {
    if (str1 == null || str2 == null)
        return str1 == str2;

    return str1.equals(str2);
}

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

можно использовать java.util.Objects следующим образом.

public static boolean compare(String str1, String str2) {
    return Objects.equals(str1, str2);
}

сравните две строки, используя метод equals(-,-) и equalsIgnoreCase ( - , -) класса Apache Commons StringUtils.

StringUtils.равно ( -, -) :

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

хорошо, так что же означает "наилучшее возможное решение"?

Если вы имеете в виду наиболее читаемый, то все возможные решения в значительной степени эквивалентны для опытного программиста Java. Но ИМО наиболее читаемым является это

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

другими словами, скрыть реализацию внутри простого метода, который (в идеале) может быть встроен.

(вы также можете "out-source" в стороннюю служебную библиотеку ... если вы уже используете его в своем кодовая база.)


Если вы имеете в виду наиболее performant, то:

  1. наиболее эффективное решение зависит от платформы и контекста,
  2. одной из проблем" контекста " является относительная (динамическая) частота появления null аргументы
  3. это наверное не имеет значения, какой вариант быстрее ... поскольку разница, вероятно, слишком мала, чтобы изменить общую производительность приложения, и
  4. если это имеет значение, единственный способ выяснить, что является самым быстрым на вашей платформе, - попробовать обе версии и измерить разницу.