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

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

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



답변

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

.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 검사는 남겨 둡니다.


답변

==객체 참조를 .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


답변

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

.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()항상 사용하는 것이 좋습니다.


답변

==두 문자열 똑같은 오브젝트 경우 운전자 여부를 확인한다.

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


답변

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

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

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

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

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


답변

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"에 문자열 테이블에서 를 가리키는 새 참조가 표시 됩니다. 참고 문헌은 다르지만 내용은 동일합니다.


답변

그래, 나쁘다 …

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

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