Java에서 문자열을 어떻게 비교합니까?


724

==내 프로그램 에서 연산자를 사용하여 지금까지 모든 문자열을 비교했습니다. 그러나 버그가 발생하여 그 중 하나가 .equals()대신 변경 되어 버그가 수정되었습니다.

==나쁜? 언제 사용해야합니까? 차이점이 뭐야?


12
또한 .equals () 메서드를 재정의하는 경우 .hashcode () 메서드를 재정의해야합니다. 그렇지 않으면 b / w equals 및 hashcode 등가 관계를 위반하게됩니다. 자세한 정보는 java doc을 참조하십시오.
Nageswaran

왜 내 설명에 대한 링크를 떠나 ==:이 객체에 수행하는 방식으로 작동 stackoverflow.com/a/19966154/2284641
요하네스 H.을

==java는 일반적으로 사용되는 문자열의 메모리 참조를 재사용하려고하는 String 풀을 가지고 있기 때문에 약간의 시간이 걸립니다. 그러나 ==객체가 값이 아니라 동일하다는 것을 비교합니다 .equals(). 사용하려는 올바른 사용법입니다.
James Oravec

미묘한 오류를 추적하고 Java String interning 프로세스의 복잡성을 연구하지 않는 한 ==를 사용하여 String이 동일한 지 테스트하지 마십시오. "12"=="1"+2False (아마)
Flight Odyssey

답변:


5560

== 참조 동등성을 테스트합니다 (동일한 오브젝트인지 여부).

.equals() 논리적으로 "동일한 지"값의 동등성을 테스트합니다.

Objects.equals ()null호출하기 전에 확인 .equals()하므로 필요하지 않습니다 (JDK7부터 사용 가능, Guava 에서도 사용 가능 ).

따라서 두 문자열의 값이 같은지 테스트하려면을 사용하는 것이 좋습니다 Objects.equals().

// These two have the same value
new String("test").equals("test") // --> true 

// ... but they are not the same object
new String("test") == "test" // --> false 

// ... neither are these
new String("test") == new String("test") // --> false 

// ... but these are because literals are interned by 
// the compiler and thus refer to the same object
"test" == "test" // --> true 

// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true

// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true

당신은 거의 항상 사용하고 싶습니다 Objects.equals(). 에서 드문 당신이 상황 을 알고 당신이 나왔습니다 거래 억류 된 문자열을, 당신은 할 수 사용 ==.

JLS 3.10.5 부터 문자열 리터럴 :

또한 문자열 리터럴은 항상 class 의 동일한 인스턴스를 나타냅니다 String. 이는 문자열 리터럴 또는보다 일반적으로 상수 표현식 ( §15.28 ) 의 값인 문자열이 메소드를 사용하여 고유 한 인스턴스를 공유하기 위해 " 인터 닝 "되기 때문 String.intern입니다.

JLS 3.10.5-1 에서도 비슷한 예를 찾을 수 있습니다 .

고려해야 할 다른 방법들

대소 문자를 무시하는 String.equalsIgnoreCase () 값 평등

String.contentEquals () 는의 내용 String과 임의 의 내용을 비교합니다 CharSequence(Java 1.5부터 사용 가능). 등식 비교를 수행하기 전에 StringBuffer 등을 문자열로 변환하지 않아도되지만 null 검사는 남겨 둡니다.


3
==가 참조 평등을 검사하면 왜 n == 5가 의미가 있습니까? 5는 변수가 아닙니다
Hrit Roy

2
@HritRoy 변수 == 을 확인하기 때문 입니다. 객체가있는 경우 객체를 참조하는 변수는 객체의 참조를 value갖습니다 . 따라서 두 변수를와 비교할 때 참조 를 비교합니다 ==. 와 같은 기본 데이터 유형을 비교할 때 int여전히 동일합니다. 유형의 변수 int는 정수를 값으로 갖습니다. 따라서을 int사용하여 두 값을 비교합니다 ==. int가 변수의 값이거나 마법의 숫자 라면 중요하지 않습니다. 또한 :참조 것도 있지만, 메모리를 참조하는 수가 없다.
akuzminykh

718

==객체 참조를 .equals()테스트하고 문자열 값을 테스트합니다.

==Java가 동일한 인라인 문자열이 실제로 동일한 객체인지 확인하기 위해 일부 비하인드 스토리를 수행하기 때문에 때로는 값을 비교 하는 것처럼 보입니다 .

예를 들면 다음과 같습니다.

String fooString1 = new String("foo");
String fooString2 = new String("foo");

// Evaluates to false
fooString1 == fooString2;

// Evaluates to true
fooString1.equals(fooString2);

// Evaluates to true, because Java uses the same object
"bar" == "bar";

그러나 null을 조심하십시오!

==null문자열을 잘 처리 하지만 .equals()null 문자열에서 호출 하면 예외가 발생합니다.

String nullString1 = null;
String nullString2 = null;

// Evaluates to true
System.out.print(nullString1 == nullString2);

// Throws a NullPointerException
System.out.print(nullString1.equals(nullString2));

따라서 그것이 fooString1null 일 수 있다는 것을 알고 있다면 독자들에게

System.out.print(fooString1 != null && fooString1.equals("bar"));

다음은 더 짧지 만 null을 확인하는 것이 확실하지 않습니다.

System.out.print("bar".equals(fooString1));  // "bar" is never null
System.out.print(Objects.equals(fooString1, "bar"));  // Java 7 required

86
값을 비교 "=="처럼 가끔 보이는, - == 이렇게 항상 비교 값을! (그것은 단지 특정 값이 참조 일뿐입니다!)
aioobe

6
아아, isNullOrEmpty ()에 대한 정적 메소드가 없으며 연산자의 사용자 정의 오버로드가 없으므로 C # 또는 Python보다 Java 의이 부분이 복잡합니다. Java에는 확장 메소드가 없으므로 java.lang.String을 확장하는 고유 한 유틸리티를 작성할 수 없습니다. 권리? String을 서브 클래 싱하고 정적 유틸리티 메소드를 추가 한 다음 항상 MyString을 대신 사용하는 것에 대한 생각이 있습니까? 널 안전 비교를 수행하기위한 두 개의 매개 변수가있는 정적 메소드도 해당 서브 클래스에있는 것이 좋습니다.
Jon Coombs 2016 년

7
Groovy는 안전한 내비게이션 연산자 ( groovy.codehaus.org/… ) 로이 작업을 조금 더 쉽게 만듭니다 ?.. 그것은 nullString1?.equals(nullString2);완전히 null 문으로 변환 됩니다. 그러나 validString?.equals(nullString);여전히 예외가 발생 하면 도움이되지 않습니다 .
Charles Wood

5
자바에서 nullable 문자열을 비교하는 간단한 방법 : stackoverflow.com/questions/11271554/…
Vadzim

5
@JonCoombs Java는 서브 클래 싱 및 자체 메서드 생성을 지원합니다. 그러나 특정 이유로 인해 마지막으로 표시되는 클래스는 거의 없으며 String은 그 중 하나이므로 확장 할 수 없습니다. 우리는 다른 클래스를 만들고 거기에 유틸리티 클래스를 만들어 두 개의 문자열을 인수로 사용하여 논리를 구현할 수 있습니다. 또한 봄과 아파치와 같은 다른 라이브러리를 null 검사하기 위해 훌륭한 메소드 모음을 사용할 수 있습니다.
Panther

442

== 객체 참조를 비교합니다.

.equals() 문자열 값을 비교합니다.

때로는 ==다음과 같이 문자열 값을 비교하는 환상이 있습니다.

String a="Test";
String b="Test";
if(a==b) ===> true

이는 문자열 리터럴을 작성할 때 JVM이 먼저 문자열 풀에서 해당 리터럴을 검색하고 일치하는 항목을 찾으면 동일한 참조가 새 문자열에 제공되기 때문입니다. 이 때문에 우리는 다음을 얻습니다.

(a == b) ===> 참

                       String Pool
     b -----------------> "test" <-----------------a

그러나 ==다음과 같은 경우에는 실패합니다.

String a="test";
String b=new String("test");
if (a==b) ===> false

이 경우 new String("test")명령문에 대해 새 문자열이 힙에 작성되고 해당 참조가에 제공 b되므로 b문자열 풀이 아닌 힙에 대한 참조가 제공됩니다.

이제는 힙의 문자열을 가리키는 a동안 문자열 풀 b의 문자열을 가리 킵니다. 그로 인해 우리는 다음을 얻습니다.

if (a == b) ===> 거짓.

                String Pool
     "test" <-------------------- a

                   Heap
     "test" <-------------------- b

하지만 .equals()항상 두 경우 모두에서 진정한 제공하므로 문자열의 값을 비교 :

String a="Test";
String b="Test";
if(a.equals(b)) ===> true

String a="test";
String b=new String("test");
if(a.equals(b)) ===> true

따라서 .equals()항상 사용하는 것이 좋습니다.


3
.equals ()는 두 인스턴스를 비교하지만 equals는이를 비교하기 위해 구현됩니다. 그것은 toString의 출력을 비교하거나 비교하지 않을 수 있습니다.
Jacob

3
@Jacob 객체 클래스 .equals()메소드는 문자열 클래스 .equals()메소드가 컨텐츠 (문자)를 비교하기 위해 대체 되는 인스턴스 (참조 / 주소) 를 비교합니다.
Satyadev

1
문자열 풀과 Java 힙의 차이점 은 동일 하지 않으므로 잘 지적 하십시오. 문자열 풀에서 Java는 String객체 를 "캐시" 하여 String불변의 것으로 알려진 메모리 풋 프린트를 절약 하려고 시도 합니다 (여기서 올바르게 말하고 싶습니다). 또한 stackoverflow.com/questions/3052442/…를
Roland

1
이것이 내가 찾던 대답입니다.
Weezy

정말 좋은 답변입니다!
alwbtc


179

Java의 문자열은 변경할 수 없습니다. 즉, 문자열을 변경 / 수정하려고 할 때마다 새 인스턴스가 생성됩니다. 원래 문자열은 변경할 수 없습니다. 이러한 문자열 인스턴스를 캐시 할 수 있도록 수행되었습니다. 일반적인 프로그램에는 많은 문자열 참조가 포함되어 있으며 이러한 인스턴스를 캐싱하면 메모리 사용량이 줄어들고 프로그램 성능이 향상 될 수 있습니다.

문자열 비교에 == 연산자를 사용하면 문자열의 내용을 비교하는 것이 아니라 실제로 메모리 주소를 비교하는 것입니다. 둘 다 같으면 true를 반환하고 그렇지 않으면 false를 반환합니다. 문자열에서 같음은 문자열 내용을 비교합니다.

따라서 모든 문자열이 시스템에 캐시되어 있다면 어떻게 ==false를 반환하고 equal은 true를 반환합니까? 음, 가능합니다. 새 문자열 String str = new String("Testing")을 만들면 캐시에 이미 동일한 내용의 문자열이 포함되어 있어도 캐시에 새 문자열이 만들어집니다. 즉, "MyString" == new String("MyString")항상 거짓을 반환합니다.

Java는 또한 문자열에서 캐시의 일부로 사용하여 "MyString" == new String("MyString").intern()true를 리턴 하는 데 사용할 수있는 intern () 함수에 대해서도 설명합니다.

참고 : == 연산자는 두 개의 메모리 주소를 비교하기 때문에 동등보다 속도가 훨씬 빠르지 만 코드에서 코드에서 새 문자열 인스턴스를 만들지 않아야합니다. 그렇지 않으면 버그가 발생합니다.


147
String a = new String("foo");
String b = new String("foo");
System.out.println(a == b); // prints false
System.out.println(a.equals(b)); // prints true

이유를 이해해야합니다. ==비교는 참조 만 비교 하기 때문입니다 . 이 equals()방법은 내용을 문자별로 비교합니다.

ab에 대해 new를 호출하면 각각 "foo"에 문자열 테이블에서 를 가리키는 새 참조가 표시 됩니다. 참고 문헌은 다르지만 내용은 동일합니다.


128

그래, 나쁘다 ...

==두 문자열 참조가 정확히 동일한 객체임을 의미합니다. Java가 일종의 리터럴 테이블을 유지하기 때문에 이것이 사실이라고 들었을 수도 있지만, 항상 그런 것은 아닙니다. 일부 문자열은 다른 문자열 등으로 구성된 다른 방식으로로드되므로 두 개의 동일한 문자열이 동일한 위치에 저장되어 있다고 가정해서는 안됩니다.

Equals는 실제 비교를 수행합니다.


124

그렇습니다. ==문자열을 비교하는 것은 좋지 않습니다 (정의가 아닌 경우 실제로는 모든 객체). ==단지 객체 참조를 비교합니다. .equals()평등을 테스트합니다. 문자열의 경우 종종 동일하지만 발견 한 것처럼 항상 보장되는 것은 아닙니다.


118

Java에는 Java가 String 객체에 대한 메모리 할당을 관리하는 String 풀이 있습니다. Java의 문자열 풀 참조

==연산자를 사용하여 두 객체를 확인 (비교) 하면 주소 동등성을 문자열 풀과 비교합니다. 두 개의 String 객체가 동일한 주소 참조를 갖는 경우 true, 그렇지 않으면를 반환합니다 false. 그러나 두 String 객체의 내용을 비교하려면 equals메서드 를 재정의해야합니다 .

equals 실제로는 Object 클래스의 메서드이지만 String 클래스로 재정의되고 객체의 내용을 비교하는 새로운 정의가 제공됩니다.

Example:
    stringObjectOne.equals(stringObjectTwo);

그러나 String의 경우를 고려하십시오. 대소 문자를 구분하지 않으려면 String 클래스의 equalsIgnoreCase 메소드를 사용해야합니다.

보자 :

String one   = "HELLO"; 
String two   = "HELLO"; 
String three = new String("HELLO"); 
String four  = "hello"; 

one == two;   // TRUE
one == three; // FALSE
one == four;  // FALSE

one.equals(two);            // TRUE
one.equals(three);          // TRUE
one.equals(four);           // FALSE
one.equalsIgnoreCase(four); // TRUE

7
나는 이것이 큰 질문에 대한 늦은 대답이라는 것을 알았습니다. 기존 답변에 아직 언급되지 않은 내용을 물어볼 수 있습니까?
Mysticial

6
@Mysticial 그는 equalsIgnoreCase신선에 유익한 정보를 추가했습니다 .
AmitG

103

zacherates의 답변에 동의합니다.

그러나 당신이 할 수있는 것은 intern()문자가 아닌 문자열 을 호출 하는 것입니다.

zacherates 예제에서 :

// ... but they are not the same object
new String("test") == "test" ==> false 

리터럴이 아닌 문자열 동등성을 인턴하면 true다음과 같습니다.

new String("test").intern() == "test" ==> true 

8
이것은 일반적으로 좋은 생각이 아닙니다. 인턴은 비교적 비싸고 (역설적으로) JVM 메모리 사용량을 증가시키고 GC 비용을 증가시킬 수 있습니다. 대부분의 경우 ==문자열 비교에 사용하면 성능이 훨씬 뛰어납니다 .
Stephen C

101

==Java에서 객체 참조를 비교하지만 객체에 대한 예외는 아닙니다 String.

를 포함하여 객체의 실제 내용을 비교 String하려면 equals메소드 를 사용해야합니다 .

String사용하여 두 객체 의 비교가로 ==밝혀 졌다면, true이는 String객체가 인터 닝되어 있고 Java Virtual Machine이 동일한 인스턴스를 가리키는 여러 참조를 가지고 있기 때문 입니다 String. String다른 String객체 와 동일한 내용을 포함하는 하나의 객체를 ==로 평가하기 위해 사용 하는 것을 기 대해서는 안됩니다 true.


99

.equals()함수가 구현되었다고 가정하면 클래스의 데이터를 비교합니다. ==포인터 위치 (메모리에서 객체의 위치)를 비교합니다.

==TALKING ABOUT PRIMITIVES가 아닌 두 개체가 모두 SAME 개체 인스턴스를 가리키는 경우 true를 반환합니다. .equals()두 객체가 동일한 데이터 Java를 포함하는 경우 true를 리턴합니다.equals()==

도움이 될 수 있습니다.


95

==2 개의 객체 (이 경우 문자열)가 메모리에서 동일한 객체를 참조하는지 여부에 따라 참조 동등성 검사를 수행합니다 .

equals()방법은 두 객체 의 내용 또는 상태 가 동일한 지 여부를 확인합니다 .

분명히 ==더 빠르지 만 2 String초가 같은 텍스트를 가지고 있는지 알고 싶다면 많은 경우에 잘못된 결과를 줄 수 있습니다 .

반드시 equals()방법을 사용 하는 것이 좋습니다.

성능에 대해 걱정하지 마십시오. 사용을 권장하는 것들 String.equals():

  1. String.equals()참조 등식에 대한 첫 번째 검사 구현 (을 사용 ==) 및 두 문자열이 참조별로 동일하면 추가 계산이 수행되지 않습니다!
  2. 두 문자열 참조가 동일하지 않으면 String.equals()다음으로 문자열 길이를 확인합니다. String클래스가 문자열의 길이를 저장 하므로 문자 또는 코드 포인트를 계산할 필요가 없기 때문에 이것은 빠른 작업 입니다. 길이가 다르면 추가 검사가 수행되지 않으므로 길이가 같을 수 없다는 것을 알고 있습니다.
  3. 우리가 이것을 멀리 얻었을 때만 2 문자열의 내용이 실제로 비교 될 것이고, 이것은 짧은 비교 일 것입니다 : 일치하지 않는 문자를 발견하면 (2 문자열의 동일한 위치에서) 모든 문자가 비교되는 것은 아닙니다 ) 문자는 더 이상 확인되지 않습니다.

모든 것이 말되고 끝났을 때, 우리가 문자열이 인턴임을 보장하더라도, 그 equals()방법을 사용하는 것은 여전히 ​​추천 된 방법으로 생각할 수있는 오버 헤드가 아닙니다. 효율적인 참조 확인을 원하면 언어 사양 및 구현에서 동일한 열거 형 값이 동일한 객체 (참조로)가 보장되는 열거 형을 사용하십시오.


2
Obviously == is faster실제로 다른 것보다 .equals(String)먼저 첫 번째 검사 ==를 구현 하므로 속도가 거의 동일하다고 말할 수 있습니다.
Razzle Shazl

2
public boolean equals(Object anObject) { if (this == anObject) { return true; } ...
Razzle Shazl

82

나 같은 사람이라면 처음 Java를 사용하기 시작할 때 "=="연산자를 사용하여 두 개의 String 인스턴스가 같은지 테스트하고 싶었지만 더 좋든 나쁘 든 Java에서 올바른 방법이 아닙니다.

이 튜토리얼에서는 Java 문자열을 올바르게 비교하는 여러 가지 방법을 보여 드리겠습니다. 이 Java String 비교 자습서의 끝에서 Java 문자열을 비교할 때 "=="연산자가 작동하지 않는 이유에 대해서도 설명합니다.

옵션 1 : equals 메소드를 사용한 Java 문자열 비교 대부분의 경우 (시간의 95 %) 다음과 같이 Java String 클래스의 equals 메소드와 문자열을 비교합니다.

if (string1.equals(string2))

이 String equals 메소드는 두 개의 Java 문자열을 살펴보고 정확히 동일한 문자열을 포함하는 경우 동일한 것으로 간주됩니다.

equals 메소드를 사용하여 빠른 문자열 비교 예제를 살펴보면 다음 테스트를 실행하면 문자가 정확히 동일하지 않기 때문에 두 문자열이 동일하게 간주되지 않습니다 (문자의 경우가 다름).

String string1 = "foo";
String string2 = "FOO";

if (string1.equals(string2))
{
    // this line will not print because the
    // java string equals method returns false:
    System.out.println("The two strings are the same.")
}

그러나 두 문자열에 정확히 동일한 문자열이 포함되어 있으면 equals 메서드는 다음 예제와 같이 true를 반환합니다.

String string1 = "foo";
String string2 = "foo";

// test for equality with the java string equals method
if (string1.equals(string2))
{
    // this line WILL print
    System.out.println("The two strings are the same.")
}

옵션 2 : equalsIgnoreCase 메소드를 사용한 문자열 비교

일부 문자열 비교 테스트에서는 문자열이 대문자인지 소문자인지 무시하고 싶을 것입니다. 대소 문자를 구분하지 않는 방식으로 문자열이 동일한 지 테스트하려면 다음과 같이 String 클래스의 equalsIgnoreCase 메소드를 사용하십시오.

String string1 = "foo";
String string2 = "FOO";

 // java string compare while ignoring case
 if (string1.equalsIgnoreCase(string2))
 {
     // this line WILL print
     System.out.println("Ignoring case, the two strings are the same.")
 }

옵션 3 : compareTo 메소드를 사용한 Java 문자열 비교

Java 문자열을 비교하는 덜 일반적인 세 ​​번째 방법도 있으며 String 클래스 compareTo 메소드를 사용합니다. 두 문자열이 정확히 같은 경우 compareTo 메서드는 0 값을 반환합니다. 다음은이 문자열 비교 방식의 간단한 예입니다.

String string1 = "foo bar";
String string2 = "foo bar";

// java string compare example
if (string1.compareTo(string2) == 0)
{
    // this line WILL print
    System.out.println("The two strings are the same.")
}

Java에서 이러한 평등 개념에 대해 쓰고 있지만 Java 언어에는 기본 Java Object 클래스에 equals 메소드가 포함되어 있습니다. 자신의 객체를 만들 때 객체의 두 인스턴스가 "동일한"지 여부를 확인할 수있는 방법을 제공 할 때마다 클래스에서이 동일한 메소드를 재정의 (및 구현)해야합니다 (Java 언어와 동일한 방식으로). String equals 메소드에서의이 동등 / 비교 동작).

==, .equals (), compareTo () 및 compare ()를 살펴볼 수 있습니다.


5
문자열 리터럴의 경우 Like String string1 = "foo bar"; 문자열 string2 = "foo bar"; == 연산자를 사용하여 내용의 동등성을 테스트 할 수 있습니다.
JAVA

1
Google 앱에서 스크립트 "compareTo"는 가능하지 않습니다. 나는 instaed 시도이 그 작품 .... 유일한 솔루션이었다 "동일"
user3887038

77

함수:

public float simpleSimilarity(String u, String v) {
    String[] a = u.split(" ");
    String[] b = v.split(" ");

    long correct = 0;
    int minLen = Math.min(a.length, b.length);

    for (int i = 0; i < minLen; i++) {
        String aa = a[i];
        String bb = b[i];
        int minWordLength = Math.min(aa.length(), bb.length());

        for (int j = 0; j < minWordLength; j++) {
            if (aa.charAt(j) == bb.charAt(j)) {
                correct++;
            }
        }
    }

    return (float) (((double) correct) / Math.max(u.length(), v.length()));
}

테스트:

String a = "This is the first string.";

String b = "this is not 1st string!";

// for exact string comparison, use .equals

boolean exact = a.equals(b);

// For similarity check, there are libraries for this
// Here I'll try a simple example I wrote

float similarity = simple_similarity(a,b);

6
이것은 다른 답변과 어떻게 다릅니 까? 왜 그렇게 제안
합니까

2
@Mark 차이점에 대한 질문 ==equals다른 솔루션에서 이미 답변을 받았지만, 문자열을 느슨하게 비교하는 다른 방법을 제공했습니다
Khaled.K

77

==운영자 확인 개의 참조는 같은 객체의 여부를 가리키면. .equals()실제 문자열 내용 (값)을 확인하십시오.

.equals()메소드는 클래스에 속합니다.Object (모든 클래스의 수퍼 클래스)에 . 클래스 요구 사항에 따라 재정의해야하지만 String의 경우 이미 구현되어 있으며 두 문자열의 값이 같은지 여부를 확인합니다.

  • 사례 1

    String s1 = "Stack Overflow";
    String s2 = "Stack Overflow";
    s1 == s2;      //true
    s1.equals(s2); //true

    이유 : 널없이 작성된 문자열 리터럴은 힙의 permgen 영역에있는 문자열 풀에 저장됩니다. 따라서 s1과 s2는 모두 풀의 동일한 객체를 가리 킵니다.

  • 사례 2

    String s1 = new String("Stack Overflow");
    String s2 = new String("Stack Overflow");
    s1 == s2;      //false
    s1.equals(s2); //true

    이유 : new키워드를 사용하여 문자열 오브젝트를 작성 하면 힙에 별도의 공간이 할당됩니다.


53

==클래스에 equals()존재 하는 메소드 가 객체 java.lang.String의 내용 String을 다른 객체 와 비교하는 반면 객체의 참조 값을 비교합니다 .


15
니트 까다로운 것은 아니지만의 equals()메소드 String는 실제로 String클래스가 아닌 클래스에 Object있습니다. 기본 equals()에이 Object내용이 동일한 지 비교하고, 기준이 동일 할 때 실제로 단지 true를 반환하지 않을 것입니다.
Jacob Schoen

1
@JacobSchoen : GrepCode가 다운되면 위의 링크가 더 이상 작동하지 않습니다. 여기에 등호 구현에 대한 대안은 다음과 같습니다 [인라인 링크 ( zgrepcode.com/java/openjdk/10.0.2/java.base/java/lang/... )
아만 딥 싱

50

나는 String당신이 정의 할 때 객체 를 정의한다고 생각 합니다. 따라서을 사용해야 .equals()합니다. 기본 데이터 형식을 사용 ==하지만 String(및 모든 개체 와 함께 ) 사용하는 경우 반드시 사용해야 .equals()합니다.


7
"char []"는 기본 데이터 유형이 아닙니다! "char"의 배열입니다. 그리고 배열 자체는 원시 데이터 유형이 아닙니다.
Christian

48

는 IF equals()방법은에 존재하는 java.lang.Object클래스, 객체의 상태의 동등성을 확인 할 것으로 예상된다! 즉, 객체의 내용을 의미합니다. 반면 ==연산자 확인 예상되는 실제 객체 인스턴스는 동일하거나 없다.

두 개의 상이한 기준 변수를 고려 str1하고 str2:

str1 = new String("abc");
str2 = new String("abc");

당신이 사용하는 경우 equals()

System.out.println((str1.equals(str2))?"TRUE":"FALSE");

TRUE사용하는 것처럼 출력을 얻습니다 ==.

System.out.println((str1==str2) ? "TRUE" : "FALSE");

지금 당신은 얻을 것이다 FALSE모두 있기 때문에, 출력으로 str1하고 str2둘 다 동일한 문자열의 내용을 공유하더라도 두 개의 서로 다른 객체를 가리키는. new String()매번 새로운 객체가 생성 되기 때문입니다 .


43

연산자 == 는 항상 객체 참조 비교를 위한 반면 String 클래스 .equals () 메소드는 내용 비교를 위해 재정의됩니다 .

String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1 == s2); // It prints false (reference comparison)
System.out.println(s1.equals(s2)); // It prints true (content comparison)

40

.equals()Object에는 .equals()boolean을 반환하는 메서드가 포함되어 있으므로 모든 개체에 메서드 가 있어야합니다 . 추가 정의가 필요한 경우이 메소드를 대체하는 것이 서브 클래스의 작업입니다. 이를 사용하지 않으면 (즉, 사용 ==) 메모리 주소 만 두 개체간에 동일한 지 검사합니다. 문자열이 이것을 재정의합니다.equals() 메서드를 하고 메모리 주소를 사용하는 대신 동일한 문자 수준에서 문자열 비교를 반환합니다.

핵심은 문자열이 하나의 덩어리 풀에 저장되므로 문자열이 생성되면 동일한 주소의 프로그램에 영원히 저장된다는 것입니다. 문자열은 변경되지 않으며 변경할 수 없습니다. 따라서 많은 양의 문자열 처리가 필요한 경우 일반 문자열 연결을 사용하는 것이 좋지 않습니다. 대신 StringBuilder제공된 클래스를 사용합니다 . 이 문자열에 대한 포인터는 변경 ==될 수 있으며 두 개의 포인터가 동일한 지 확인하는 것이 좋습니다. 문자열 자체는 그렇지 않습니다.


2
"문자열이 생성되면 동일한 주소의 프로그램에 영원히 저장됩니다" -이것은 잘못된 것입니다. 컴파일 타임 상수 문자열 표현식 ( final String변수가 포함될 수 있음)과 프로그램에서 명시 적으로 인턴하는 문자열 만 "일괄 풀"에 저장됩니다. String다른 유형의 객체와 마찬가지로 더 이상 실제 참조가 없으면 다른 모든 객체는 가비지 수집 대상이됩니다. 또한 전체 interning 메커니즘이 작동하려면 불변성이 필요하지만 그렇지 않은 경우에는 이와 관련이 없습니다.
Ted Hopp

문자열 비교는 실제로 문자열의 내용을 비교하는 equalsIgnoreCase 메소드를 통해 수행됩니다. 그러나 == 부호는 참조 값을 확인하십시오. 이 경우 문자열 풀의 문자열 리터럴이 제대로 작동합니다. 문자열 s1 = 새 문자열 ( "a"); 문자열 s2 = 새로운 문자열 ( "a"); 이 경우 s1 == s2는 false이지만 s1.equals (s2)는 true입니다.
Shailendra Singh

39

compareTo()방법을 사용하여 두 문자열을 비교할 수도 있습니다 . compareTo 결과가 0이면 두 문자열이 같고, 그렇지 않으면 비교되는 문자열이 동일하지 않습니다.

==참조를 비교하고 실제 문자열을 비교하지 않습니다. 사용하여 모든 문자열을 new String(somestring).intern()만든 경우 ==연산자를 사용하여 두 문자열을 비교할 수 있습니다. 그렇지 않으면 equals () 또는 compareTo 메서드 만 사용할 수 있습니다.


35

Java에서는 "==" 연산자를 사용하여 두 객체를 비교할 때 객체가 메모리에서 동일한 위치를 참조하는지 확인합니다. 즉, 2 개의 객체 이름이 기본적으로 동일한 메모리 위치를 참조하는지 확인합니다.

Java String 클래스는 실제로 Object 클래스의 기본 equals () 구현을 재정의합니다.이 메서드는 메모리의 위치가 아닌 문자열 값만 확인하도록 메서드를 재정의합니다. 즉, equals () 메서드를 호출하여 2 개의 String 객체를 비교하는 경우 실제 문자 시퀀스가 ​​동일한 한 두 객체가 모두 동일한 것으로 간주됩니다.

그만큼 ==연산자 검사 두 문자열 정확히 동일한 오브젝트 인 경우.

.equals()방법은 두 문자열의 값이 같은지 확인합니다.


1
s가 null 인 경우 s.equals (s2)가 충돌하여 비교에 실패하므로 둘 중 하나가 null이 아닌 경우 물론 이것은 실제로 대답과 모순되지 않습니다. 단지 경고 일뿐입니다.
Jon Coombs 2012 년

1
아니요, 충돌하지 않으며 NullPointerException이 발생하여 비교가 발생하지 않습니다.
Bludzee
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.