Development Tip

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

yourdevel 2020. 9. 29. 18:47
반응형

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


==지금까지 모든 문자열을 비교하기 위해 프로그램 에서 연산자를 사용하고 있습니다. 그러나 나는 버그를 만났고 그중 하나를 .equals()대신 변경 하여 버그를 수정했습니다.

==나쁜? 언제 사용해야하며 사용하지 않아야합니까? 차이점이 뭐야?


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

.equals() 값이 같은지 테스트합니다 (논리적으로 "동일"인지 여부).

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

String.contentEquals () 는의 내용 String을 임의의 내용과 비교합니다 CharSequence(Java 1.5부터 사용 가능).

결과적으로 두 문자열의 값이 같은지 테스트하려면을 사용하고 싶을 것입니다 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 에서도 찾을 수 있습니다 .


==개체 참조를 .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문자열을 잘 처리 하지만 .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 (Java 7에서)을 확인하는 것이 명확하지 않습니다.

System.out.print(Objects.equals(fooString1, "bar"));

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

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

때때로 ==다음과 같은 경우와 같이 String 값을 비교하는 환상을 제공합니다.

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")문에 대해 new String이 힙에 생성되고 해당 참조가에 제공 b되므로 bString 풀이 아닌 힙에 대한 참조가 제공됩니다.

이제는 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를 반환하고 equals는 true를 반환합니까? 음, 가능합니다. 같은 새 문자열을 만들 경우 String str = new String("Testing")당신은 캐시가 이미 동일한 내용을 갖는 문자열을 포함하는 경우에도 캐시에 새 문자열을 만드는 끝. 요컨대 "MyString" == new String("MyString")항상 거짓을 반환합니다.

Java는 또한 문자열에서 사용할 수있는 함수 intern ()에 대해 이야기하여 캐시의 일부로 만들 수 있으므로 "MyString" == new String("MyString").intern()true를 반환합니다.

참고 : == 연산자는 두 메모리 주소를 비교하기 때문에 같음보다 훨씬 빠르지 만 코드가 코드에서 새 String 인스턴스를 생성하지 않는지 확인해야합니다. 그렇지 않으면 버그가 발생합니다.


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, 각각의 하나는 새로운 참조를 가져옵니다 그 포인트 "foo"의 캐릭터 라인 테이블입니다. 참고 문헌은 다르지만 내용은 동일합니다.


그래, 나쁘다 ...

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

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


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


Java에는 Java가 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

나는 zacherates의 대답에 동의합니다.

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

zacherates 예에서 :

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

인턴하면 비 리터럴 문자열 평등은 true

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

==자바에서 객체 참조를 비교하며 객체에 대한 예외는 아닙니다 String.

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

String사용 하는 두 객체 의 비교가 인 ==것으로 판명 true되면 String객체가 인턴되었고 Java Virtual Machine에 동일한 인스턴스를 가리키는 여러 참조 가 있기 때문 입니다 String. 으로 평가 하는 사용 하는 String다른 String개체 와 동일한 내용을 포함하는 개체 를 비교할 것으로 기 대해서는 안됩니다 .==true


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

==두 개체 (PRIMITIVES에 대해 말하지 않음)가 SAME 개체 인스턴스를 가리키는 경우 true를 반환합니다. .equals()두 개체가 동일한 데이터를 포함하는 경우 true를 반환 equals()수스 ==자바

도움이 될 수 있습니다.


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

equals()메서드는 두 개체 내용 또는 상태 가 동일한 지 확인합니다.

분명히 ==더 빠르지 만 2 String가 동일한 텍스트를 보유하고 있는지 알려주고 싶다면 많은 경우에 잘못된 결과를 줄 수 있습니다 .

확실히 equals()방법을 사용 하는 것이 좋습니다.

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

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

When all is said and done, even if we have guarantee that the strings are interns, using the equals() method is still not that overhead that one might think, definitely the recommended way. If you want efficient reference check, then use enums where it is guaranteed by the language specification and implementation that the same enum value will be the same object (by reference).


If you're like me, when I first started using Java, I wanted to use the "==" operator to test whether two String instances were equal, but for better or worse, that's not the correct way to do it in Java.

In this tutorial I'll demonstrate several different ways to correctly compare Java strings, starting with the approach I use most of the time. At the end of this Java String comparison tutorial I'll also discuss why the "==" operator doesn't work when comparing Java strings.

Option 1: Java String comparison with the equals method Most of the time (maybe 95% of the time) I compare strings with the equals method of the Java String class, like this:

if (string1.equals(string2))

This String equals method looks at the two Java strings, and if they contain the exact same string of characters, they are considered equal.

Taking a look at a quick String comparison example with the equals method, if the following test were run, the two strings would not be considered equal because the characters are not the exactly the same (the case of the characters is different):

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.")
}

But, when the two strings contain the exact same string of characters, the equals method will return true, as in this example:

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.")
}

Option 2: String comparison with the equalsIgnoreCase method

In some string comparison tests you'll want to ignore whether the strings are uppercase or lowercase. When you want to test your strings for equality in this case-insensitive manner, use the equalsIgnoreCase method of the String class, like this:

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.")
 }

Option 3: Java String comparison with the compareTo method

There is also a third, less common way to compare Java strings, and that's with the String class compareTo method. If the two strings are exactly the same, the compareTo method will return a value of 0 (zero). Here's a quick example of what this String comparison approach looks like:

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.")
}

While I'm writing about this concept of equality in Java, it's important to note that the Java language includes an equals method in the base Java Object class. Whenever you're creating your own objects and you want to provide a means to see if two instances of your object are "equal", you should override (and implement) this equals method in your class (in the same way the Java language provides this equality/comparison behavior in the String equals method).

You may want to have a look at this ==, .equals(), compareTo(), and compare()


Function:

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

Test:

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

The == operator check if the two references point to the same object or not. .equals() check for the actual string content (value).

Note that the .equals() method belongs to class Object (super class of all classes). You need to override it as per you class requirement, but for String it is already implemented, and it checks whether two strings have the same value or not.

  • Case 1

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

    Reason: String literals created without null are stored in the String pool in the permgen area of heap. So both s1 and s2 point to same object in the pool.

  • Case 2

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

    Reason: If you create a String object using the new keyword a separate space is allocated to it on the heap.


== compares the reference value of objects whereas the equals() method present in the java.lang.String class compares the contents of the String object (to another object).


I think that when you define a String you define an object. So you need to use .equals(). When you use primitive data types you use == but with String (and any object) you must use .equals().


If the equals() method is present in the java.lang.Object class, and it is expected to check for the equivalence of the state of objects! That means, the contents of the objects. Whereas the == operator is expected to check the actual object instances are same or not.

Example

Consider two different reference variables, str1 and str2:

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

If you use the equals()

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

You will get the output as TRUE if you use ==.

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

Now you will get the FALSE as output, because both str1 and str2 are pointing to two different objects even though both of them share the same string content. It is because of new String() a new object is created every time.


Operator == is always meant for object reference comparison, whereas the String class .equals() method is overridden for content comparison:

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)

All objects are guaranteed to have a .equals() method since Object contains a method, .equals(), that returns a boolean. It is the subclass' job to override this method if a further defining definition is required. Without it (i.e. using ==) only memory addresses are checked between two objects for equality. String overrides this .equals() method and instead of using the memory address it returns the comparison of strings at the character level for equality.

A key note is that strings are stored in one lump pool so once a string is created it is forever stored in a program at the same address. Strings do not change, they are immutable. This is why it is a bad idea to use regular string concatenation if you have a serious of amount of string processing to do. Instead you would use the StringBuilder classes provided. Remember the pointers to this string can change and if you were interested to see if two pointers were the same == would be a fine way to go. Strings themselves do not.


You can also use the compareTo() method to compare two Strings. If the compareTo result is 0, then the two strings are equal, otherwise the strings being compared are not equal.

The == compares the references and does not compare the actual strings. If you did create every string using new String(somestring).intern() then you can use the == operator to compare two strings, otherwise equals() or compareTo methods can only be used.


In Java, when the “==” operator is used to compare 2 objects, it checks to see if the objects refer to the same place in memory. In other words, it checks to see if the 2 object names are basically references to the same memory location.

The Java String class actually overrides the default equals() implementation in the Object class – and it overrides the method so that it checks only the values of the strings, not their locations in memory. This means that if you call the equals() method to compare 2 String objects, then as long as the actual sequence of characters is equal, both objects are considered equal.

The == operator checks if the two strings are exactly the same object.

The .equals() method check if the two strings have the same value.

참고URL : https://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java

반응형