Разница между методами String#equals и String#contentEquals

В чем разница между String#equals метод и String#contentEquals метод?

10 ответов

String#equals() не только сравнивает содержимое строки, но также проверяет, является ли другой объект также экземпляром String, String#contentEquals() сравнивает только содержимое (последовательность символов) и не проверяет, является ли другой объект также экземпляром String, Это может быть что угодно, только если это реализация CharSequence который охватывает ао String, StringBuilder, StringBuffer, CharBuffer, так далее.

Проще говоря: String.contentEquals() самый умный брат String.equals() потому что это может быть более свободным в реализации, чем String.equals() ,

Есть несколько причин, почему существует отдельный String.contentEquals() метод. Самая важная причина, я думаю, это:

  • equals метод должен быть рефлексивным. Это означает, что: x.equals(y) == y.equals(x), Это подразумевает, что aString.equals(aStringBuffer) должно быть таким же, как aStringBuffer.equals(aString), Это потребует от разработчиков Java API создания специальной реализации для строк в equals() метод StringBuffer, StringBuilder и CharSequence, а также. Это было бы беспорядок.

И вот тогда String.contentEquals приходит. Это автономный метод, который не должен следовать строгим требованиям и правилам для Object.equals, Таким образом, вы можете более свободно реализовать смысл "равного содержания". Это позволяет вам делать интеллектуальные сравнения, например, между StringBuffer и String.

И сказать, в чем именно разница:

  • String.contentEquals() можно сравнить содержимое String, StringBuilder, StringBuffer, CharSequence и все производные классы из них. Если параметр имеет тип String, то String.equals() быть казненным.

  • String.equals() сравнивает только строковые объекты. Все остальные типы объектов считаются не равными.

  • String.contentEquals() можно сравнить StringBuffer а также StringBuilder в интеллектуальном смысле. Это не вызывает тяжелый toString() метод, который копирует весь контент в новый объект String. Вместо этого он сравнивается с основным char[] массив, что здорово.

Этот ответ уже был опубликован dbw, но он удалил его, но у него были очень веские баллы для разницы при сравнении времени выполнения, какие исключения выбрасываются,

Если вы посмотрите на исходный код String#equals и String#contentEquals, то станет ясно, что существует два переопределенных метода для String#contentEquals тот, который берет StringBuilder и другие CharSequence,
Разница между ними,

  1. String#contentEquals скинет NPE, если заданный аргумент null но String#equals вернусь false
  2. String#equals сравнивает содержимое только тогда, когда предоставленный аргумент instance of String в противном случае он вернется false во всех остальных случаях, но с другой стороны String#contentEquals проверяет содержимое всех объектов, которые реализуют интерфейс CharSequence,
  3. Вы также можете настроить код так, чтобы String#contentEquals вернуть неправильный результат или результат, который вы хотите, переопределив equals метод аргумента передается как показано ниже, но вы не можете сделать эти настройки с String#equals,
    Ниже код всегда будет выдавать true пока s содержит любой string длиной 3 символа

        String s= new String("abc");// "abc";
        System.out.println(s.contentEquals(new CharSequence() 
        {
    
            @Override
            public CharSequence subSequence(int arg0, int arg1) {
                // TODO Auto-generated method stub
                return null;
            }
    
            @Override
            public int length() {
                // TODO Auto-generated method stub
                return 0;
            }
    
            @Override
            public char charAt(int arg0) {
                // TODO Auto-generated method stub
                return 0;
            }
    
    
            @Override
            public boolean equals(Object obj) 
            {
               return true;
            }
        }));
    
  4. String#contentEquals будет медленнее String#Equals в случае, когда аргумент предоставлен instance of String и длина обоих String то же самое, но содержимое не равно.
    Пример, если строка String s = "madam" а также String argPassed = "madan" затем s.contentEquals(argPassed) займет в два раза больше времени выполнения в этом случае по сравнению с s.equals(argPassed)

  5. Если длина содержимого не одинакова для обеих строк, то функция String#contentEquals будет иметь лучшую производительность, чем String#Equals почти во всех возможных случаях.

Еще один момент, чтобы добавить к его ответу

  1. String#contentEquals из String Объект также будет сравниваться с StringBuilder содержание и обеспечить соответствующий результат, а String#Equals вернусь false
  • String учебный класс equals(Object o) метод делает только String сравнение. Но contentEquals(CharSequence cs) проверки на классы расширяются AbstractStringBuilder т.е. StringBuffer, StringBuilder а также String класс также (Все они имеют тип CharSequence).

    String str = "stackru";
    StringBuilder builder = new StringBuilder(str);
    System.out.println(str.equals(builder));
    System.out.println(str.contentEquals(builder));
    

выход:

false
true

Выход первого stmt false так как builder не тип String так equals() возвращается false но contentEquals() проверяет содержимое всего типа, как StringBuilder, StringBuffer, String и, как содержание то же самое, следовательно, true,

  • contentEquals будет бросать NullPointerException если предоставленный аргумент null но equals() вернет false, потому что equals() проверяет instanceOf (if (anObject instance of String)) который возвращает false, если аргумент null,

contentEquals(CharSequence cs):

  • Позволяет проверить равенство заданного строкового значения любому экземпляру реализации интерфейса java.lang.CharacterSequence (например, CharBuffer, Segment, String, StringBuffer, StringBuilder)

equals(Object anObject):

  • Позволяет проверить равенство заданного строкового значения любому экземпляру типа java.lang.String только

RTFC:)

Поскольку чтение исходного кода - лучший способ понять его, я делюсь реализацией обоих методов (по состоянию на jdk 1.7.0_45)

public boolean contentEquals(CharSequence cs) {
    if (value.length != cs.length())
        return false;
    // Argument is a StringBuffer, StringBuilder
    if (cs instanceof AbstractStringBuilder) {
        char v1[] = value;
        char v2[] = ((AbstractStringBuilder) cs).getValue();
        int i = 0;
        int n = value.length;
        while (n-- != 0) {
            if (v1[i] != v2[i])
                return false;
            i++;
        }
        return true;
    }
    // Argument is a String
    if (cs.equals(this))
        return true;
    // Argument is a generic CharSequence
    char v1[] = value;
    int i = 0;
    int n = value.length;
    while (n-- != 0) {
        if (v1[i] != cs.charAt(i))
            return false;
        i++;
    }
    return true;
}

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String) anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                        return false;
                i++;
            }
            return true;
        }
    }
    return false;
 }

Есть еще один метод String#contentEquals():

public boolean contentEquals(StringBuffer sb) {
    synchronized(sb) {
        return contentEquals((CharSequence)sb);
    }
}

equals() а также contentEquals() are two methods in String class to compare two strings а также string с StringBuffer,

Параметры contentEquals() являются StringBuffer а также String(charSequence), equals() используется для сравнения двух strings а также contentEquals() is used to compare the contents of String а также StringBuffer,

метод contentEquals а также equals являются

public boolean contentEquals(java.lang.StringBuffer);
public boolean contentEquals(java.lang.CharSequence);
public boolean equals(Object o)

Here is an code which describes both methods

public class compareString {
    public static void main(String[] args) {
        String str1 = "hello";    
        String str2 = "hello";

        StringBuffer sb1 = new StringBuffer("hello");
        StringBuffer sb2 = new StringBuffer("world");

        boolean result1 = str1.equals(str2);        // works nice and returns true
        System.out.println(" str1.equals(str2) - "+ result1);

        boolean result2 = str1.equals(sb1);         // works nice and returns false
        System.out.println(" str1.equals(sb1) - "+ result2);

        boolean result3 = str1.contentEquals(sb1);  // works nice and returns true
        System.out.println(" str1.contentEquals(sb1) - "+ result3);

        boolean result4 = str1.contentEquals(sb2);  // works nice and returns false
        System.out.println(" str1.contentEquals(sb2) - "+ result4);

        boolean result5 = str1.contentEquals(str2);  // works nice and returns true
        System.out.println(" str1.contentEquals(str2) - "+ result5);
    }
}

Выход:

 str1.equals(str2) - true
 str1.equals(sb1) - false
 str1.contentEquals(sb1) - true
 str1.contentEquals(sb2) - false
 str1.contentEquals(str2) - true

contentEquals() Метод проверяет, что содержимое одинаково между String, StringBufferи т. д. какая-то последовательность символов.

String#equals принимает Object в качестве аргумента и проверяет, является ли он экземпляром объекта String или нет. Если аргументом является объект String, он сравнивает содержимое символ за символом. Возвращает true, если содержимое обоих строковых объектов одинаково.

String # contentEquals принимает интерфейс CharSequence в качестве аргумента. CharSequence может быть реализован двумя способами: с помощью i) класса String или (ii) AbstractStringBuilder(родительский класс StringBuffer, StringBuilder)

В contentEquals() длина сравнивается перед проверкой любого экземпляра объекта. Если длина одинакова, то проверяется, является ли объект аргумента экземпляром AbstractStringBuilder или нет. Если это так (т.е. StringBuffer или StringBuilder), то содержимое проверяется посимвольно. Если аргумент является экземпляром объекта String, то String#equals вызывается из String#contentEquals.

Короче говоря,

String#equals сравнивает содержимое символ за символом в случае, если аргумент также является объектом String. И String#contentEquals сравнивает содержимое в случае, если аргумент объекта реализует интерфейс CharSequence.

String#contentEquals работает медленнее, если мы сравниваем два строковых содержимого одинаковой длины, так как String#contentEquals внутренне вызывает String#equals для объекта String.

Если мы попытаемся сравнить объекты с разной длиной содержимого (скажем, "abc" с "abcd"), то String#contentEquals быстрее, чем String # равно. Потому что длина сравнивается перед проверкой экземпляра объекта.

Кстати, историческая причина разницы в том, что String изначально не имел суперкласса, поэтому String.equals() принимает String в качестве аргумента. Когда CharSequence был представлен как суперкласс String, он нуждался в собственном тесте на равенство, который работал бы во всех реализациях CharSequence, и который не вступал бы в конфликт с equals (), уже используемым String... поэтому мы получили CharSequence.contentEquals(), который наследуется String.

Если бы CharSequence присутствовал в Java 1.0, мы, вероятно, имели бы только CharSequence.equals(), и String просто реализовал бы это.

Ах, радости развивающихся языков...

Большая разница в том, что equals () будет работать только с другой String, а contentEquals() будет работать с любой CharacterSequence (например, StringBuilder).

public class Test{
public static void main(String[] args)
{
    String str1 = "Hello";
    String str2 = new String("Hello");
    StringBuilder str3 = new StringBuilder(str1);
    System.out.println("str1.equals(str2): " + (str1.equals(str2)));
    System.out.println("str1.contentEquals(str2): " + (str1.contentEquals(str2)));
    System.out.println("str1.equals(str3): " + (str1.equals(str3)));
    System.out.println("str1.contentEquals(str3): " + (str1.contentEquals(str3)));
}}

выдаст вывод как

str1.equals (str2): верно

str1.contentEquals(str2): правда

str1.equals (str3): ложь

str1.contentEquals(str3): правда

Другие вопросы по тегам