Разница между значениями String # equals и String # contentEquals

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

Ответ 1

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

Ответ 2

Проще говоря: 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. Это автономный метод, который не должен следовать строгим требованиям и правилам. strong > для Object.equals. Таким образом, вы можете реализовать чувство "равного содержания" более свободно. Это позволяет делать интеллектуальные сравнения между StringBuffer и String, например.

И чтобы сказать, в чем именно заключается разница:

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

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

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

Ответ 3

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

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

  • String#contentEquals выдаст NPE, если аргумент предоставлен null, но String#equals вернет false
  • String#equals сравнивает содержимое только в том случае, если аргумент instance of String, иначе он будет возвращать false во всех других случаях, а с другой стороны String#contentEquals проверяет содержимое всех объектов, реализующих интерфейс CharSequence.
  • Вы также можете настроить код так, чтобы 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;
            }
        }));
    
  • String#contentEquals будет медленнее, чем String#equals в том случае, если аргумент представлен instance of String, а длина обоих string одинакова, но содержимое не равно.
    Пример, если строка String s = "madam" и String argPassed = "madan", тогда s.contentEquals(argPassed) будет принимать почти двойное время выполнения в этом случае по сравнению с s.equals(argPassed)

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

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

  1. String#contentEquals объекта string также будет сравниваться с содержимым StringBuilder и предоставить соответствующий результат, в то время как String#equals вернет false

Ответ 4

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

Ответ 5

  • String класс equals(Object o) метод выполняет только сравнение String. Но contentEquals(CharSequence cs) проверяет классы extends AbstractStringBuilder i.e. StringBuffer, StringBuilder и String class также (все они имеют тип CharSequence).

    String str = "stackoverflow";
    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.

Ответ 6

equals() и contentEquals() - два метода в классе String для сравнения двух strings и String с StringBuffer.

Параметры contentEquals() равны StringBuffer и String(charSequence). equals() используется для сравнения двух strings и contentEquals() используется для сравнения содержимого String и StringBuffer.

Метод contentEquals и equals являются

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

Вот код, который описывает оба метода

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

Ответ 7

Проверка метода contentEquals() - это то же самое содержимое между String, StringBuffer и т.д., которое представляет собой последовательность char.

Ответ 8

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

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

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

Итак,

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

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

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

Ответ 9

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

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

А, радости эволюционирующих языков...

Ответ 10

Большая разница в том, что equals() будет работать только с другой строкой, а 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): true

str1.contentEquals(str2): true

str1.equals(str3): false

str1.contentEquals(str3): true