Подтвердить что ты не робот

Java: String: equalsIgnoreCase против переключения всего на верхний/нижний регистр

Мне пришло в голову, что существует несколько способов сравнения строк в Java.

Я только что привык к тому, что использовал equalsIgnoreCase, чтобы избежать проблем с строками, чувствительными к регистру.

Другие, с другой стороны, предпочитают передавать все в верхнем или нижнем регистре.

Откуда я стою (даже если технически я сижу), я не вижу реальной разницы.

Кто-нибудь знает, лучше ли одна практика, чем другая? И если да, то почему?

4b9b3361

Ответ 1

Используйте equalsIgnoreCase, потому что это более читаемо, чем преобразование обеих строк в верхний регистр перед сравнением. Микро-оптимизация удобочитаемости.

Что более читаемо?

if (myString.toUpperCase().equals(myOtherString.toUpperCase())) {

или

if (myString.equalsIgnoreCase(myOtherString)) {

Я думаю, мы все можем согласиться с тем, что equalsIgnoreCase более читаем.

Ответ 2

equalsIgnoreCase избегает проблем, связанных с различиями в локали (например, в турецком языке есть два разных прописных буквы "i" ). С другой стороны, Maps использует метод equals().

Ответ 3

Но проблема в последнем, когда вы принимаете предположение, которое передается в верхнем или нижнем регистре, вы не можете слепо доверять вызывающему. Поэтому вам нужно включить инструкцию ASSERT в начале метода, чтобы убедиться, что вход всегда в том случае, если вы ожидаете.

Ответ 4

Также не лучше, они оба используют свои приложения в разных сценариях.

Много раз, когда вам нужно проводить сопоставления строк, есть возможность массировать хотя бы одну из строк, чтобы упростить сравнение, и в этих случаях вы увидите строки, преобразованные в конкретный случай, обрезанные и т.д., прежде чем по сравнению.

Если, с другой стороны, вы просто хотите выполнить "безрезультатное" сравнение двух строк без учета регистра, то не стесняйтесь использовать equalsIgnoreCase, что его там для всех. Однако я бы предупредил, что если вы видите много equalsIgnoreCase, это может быть запах кода.

Ответ 5

Показатели производительности одинаковы в соответствии с этим постом:

http://www.params.me/2011/03/stringtolowercasestringtouppercase-vs.html

Итак, я бы решил, основываясь на читабельности кода, в некоторых случаях toLowerCase() было бы лучше, если бы я передавал значение всегда одному методу создания объектов, иначе equalsIgnoreCase() имеет больше смысла.

Ответ 6

Когда я работаю с английскими символами, я всегда запускаю toUpperCase() или toLowerCase(), прежде чем начинать выполнять сравнения, если я вызываю .equalsIgnoreCase() более одного раза, или если я 'используя оператор switch. Таким образом, он выполняет операцию изменения case только один раз, и, следовательно, более эффективен.

Например, в шаблоне factory:

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 блоков для сравнения строк)

Ответ 7

Это зависит от варианта использования.

Если вы выполняете сравнение строк с одним или несколькими, 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.

Это лучше, чем вызов equalsIgnoreCase для каждого элемента списка, потому что небольшое увеличение производительности equalsIgnoreCase() отменяется из-за того, что вы в основном делаете модифицированную версию contains() для массива, которая равна O (п). С предварительно нормированной строкой вы можете проверить весь список строк с помощью одного вызова contains(), который выполняется в O (1).