String # equals와 String # contentEquals 메소드의 차이점


답변:


171

String#equals()다른 객체도의 인스턴스의 경우 문자열의 내용뿐만 아니라 검사를 비교뿐만 아니라 String. String#contentEquals()뿐만 내용 (문자 시퀀스)를 비교 않는 하지 다른 객체가 인스턴스인지 확인 String. 그것의 구현으로이만큼 아무것도 할 수있다 CharSequenceAO 다루고있는 String, StringBuilder, StringBuffer, CharBuffer, 등


12
그렇다면 자바 스크립트 의 연산자 ==(contentEquals) 및 ===(equals) 와 비슷 합니까?
anestv

2
@anestv Java에서 ==연산자는 두 객체 의 내용 이 아닌 참조 만 비교하도록 허용 합니다.
Stephan

2
명확하게 말하면, Java의 == 연산자는 두 객체가 메모리에서 동일한 위치를 가리키는 지 또는 두 기본 유형 (바이트, 짧은, int, long, float, double, char, 부울)이 같은지 여부를 확인하는 데 사용됩니다.
La-comadreja

2
@Stephan은 ==언급 된 것은 JavaScript뿐입니다. Java에 대해서는 언급되지 않았습니다.
Olathe

@anestv,이 차이 (있는 ==자바 스크립트보다 훨씬 느슨한입니다 contentEquals예를 들어, 숫자를 터치하지 않습니다)하지만, 약 당신이있는 거 정확한 equals정확한 유형의 일치에 대한 검사 Strings (다른 클래스가 자신의 유형과 느슨한 수 있습니다 equals방법) .
Olathe

43

쉽게 구현하려면 : 의 구현이 더 자유롭기 때문에 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()a String, a StringBuilder, a StringBuffer, a CharSequence및 파생 된 모든 클래스의 내용을 비교할 수 있습니다 . 매개 변수가 String 유형 인 경우 String.equals()실행하십시오.

  • String.equals()String 객체 만 비교합니다. 다른 모든 객체 유형은 동일하지 않은 것으로 간주됩니다.

  • String.contentEquals()비교할 수 StringBufferStringBuilder지능적인 방법이다. 전체 내용을 새 String 객체로 복사 하는 heavy 메소드를 호출 하지 않습니다toString() . 대신 기본 char[]배열 과 비교하면 좋습니다.


31

이 답변은 이미 dbw 에 의해 게시 되었지만 삭제했지만 실행 시간을 비교하는 동안 차이점에 대해 매우 유효한 점이 있었으며 예외는 무엇인지,

소스 코드 String # equalsString # 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 는 3 자 길이의 문자 를 s포함하는 string항상 생성합니다.

        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#contentEqualsString#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(A)의 String객체도 비교 할 StringBuilder내용과 동안 적절한 결과를 제공 String#Equals의지의 수익을false

4
@dbw이 답변은 게시 한 답변에서 온 것입니다.
Prateek

@dbw 게다가 어쨌든 게시물을 삭제 한 이유는 무엇입니까?
MC 황제

14
  • String클래스 equals(Object o)메소드는 String비교 만합니다. 그러나 contentEquals(CharSequence cs)클래스에 대한 검사가 확장 AbstractStringBuilderStringBuffer, StringBuilderString(그들은 모두 유형입니다 또한 클래스 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.

  • contentEqualsequals ()가 instanceOf ( )를 검사 하여 인수가이면 false를 반환 하기 때문에 NullPointerException제공된 인수가 null있지만 equals()false를 반환 하면 throw 됩니다 .if (anObject instance of String)null

14

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

9

equals()그리고 contentEquals()두 가지 방법이 있습니다 String이 비교 클래스 stringsstring함께이 StringBuffer.

의 매개 변수 contentEquals()StringBufferString(charSequence)입니다. equals()둘을 비교하는 데 사용됩니다 stringscontentEquals()의 내용을 비교하는 데 사용됩니다 StringStringBuffer.

방법 contentEqualsequals있습니다

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

String # equals 는 Object를 인수로 사용하여 String 객체의 인스턴스인지 확인합니다. 인수 객체가 문자열 객체 인 경우 콘텐츠를 문자별로 비교합니다. 두 문자열 객체의 내용이 동일한 경우 true를 반환합니다.

String # contentEquals 는 CharSequence 인터페이스를 인수로 사용합니다. CharSequence는 i) String 클래스 또는 (ii) AbstractStringBuilder (StringBuffer의 상위 클래스, StringBuilder)를 사용하여 두 가지 방법으로 구현할 수 있습니다.

에서는 contentEquals () 의 길이는 임의의 객체 인스턴스 검사 전에 비교된다. 길이가 같으면 인수 객체가 AbstractStringBuilder의 인스턴스인지 확인합니다. 그것이 그렇다면 (즉 StringBuffer 또는 StringBuilder) 내용은 문자별로 검사됩니다. 인수가 String 객체의 인스턴스 인 경우 String # contentEquals에서 String # equals가 호출됩니다.

한마디로

String # equals 는 argument가 String 객체 인 경우 콘텐츠를 문자별로 비교합니다. 그리고 String # contentEquals 는 인수 객체가 CharSequence 인터페이스를 구현하는 경우 내용을 비교합니다.

String # contentEquals는 String # contentEquals가 내부적으로 String 객체에 대해 String # equals를 호출하는 것과 동일한 두 개의 길이의 문자열 내용을 비교하는 경우 속도가 느립니다.

콘텐츠 길이가 다른 객체 (예 : "abc"와 "abcd")를 비교하려고하면 String # contentEquals가 String # equals보다 빠릅니다. 객체 인스턴스 확인 전에 길이가 비교되기 때문입니다.


6

contentEquals()방법은 어떤 종류의 문자 시퀀스 StringStringBuffer, 등 의 내용이 동일 하다는 것을 확인합니다.


5

BTW, 차이점의 역사적인 이유는 String에 원래 수퍼 클래스가 없었기 때문에 String.equals ()는 String을 인수로 사용합니다. CharSequence가 String의 수퍼 클래스로 도입되었을 때, 모든 CharSequence 구현에서 작동하고 String에서 이미 사용중인 equals ()와 충돌하지 않는 자체 평등 테스트가 필요했습니다. 그래서 CharSequence.contentEquals ( )는 String에 의해 상속됩니다.

만약 CharSequence가 Java 1.0에 존재한다면, 우리는 CharSequence.equals () 만 가지고 있고 String은 단순히 그것을 구현할 것입니다.

아, 진화하는 언어의 기쁨 ...

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.