본문 바로가기
자바(Java)/자바기초

[자바기초.026] 문자열 비교하기(Comparing String)

by 긱펀 2024. 3. 24.
반응형

[자바기초.026] 문자열 비교하기(Comparing String)

 

1. 문자열이 같은지 비교 (String Equality)

  • equals() 메소드는 두 개의 객체(object)가 같은지 비교하는 명령어 이다.
  • 문자열(String)은 객체이기 때문에, 자바에서는 두 개의 문자열이 서로 같은지 비교할 때 equals() 메소드를 사용한다.
  • 특히, 문자열을 equals()메소드로 비교하게 되면 문자열의 음절 하나씩 같은지 비교하고 또한 음절의 순서도 비교한다. 그래서 자바에서는 문자열이 서로 같은지 정확하게 비교하려면 equals()메소드를 사용하는 것이 맞다.
  • 두 개의 객체를 비교하는 데에 연산자 == 을 사용하게 되면, ==은 두 개의 객체 변수가 같은 객체를 가리키고(refer)있는지 여부를 알려준다. 이렇게 하나의 객체를 가리키는 여러 변수들을 object references라고 부르고, 같은 객체에 대해 aliases 되었다고도 말한다.
  • 문자열 비교에 ==을 사용하면, 문자열의 음절 하나 하나를 비교하는게 아니라, 단순히 같은 객체를 가리키고 있는지만 비교하기 때문에 옳은 비교라고 할 수 없다.

 

 

[예제1] 위 내용의 실제 사례를 보기 위해 아래의 코드를 실행해 보세요.

1
2
3
4
5
6
7
8
9
10
public class Main {
  public static void main(String[] args) {
    String s1 = new String("Hello");
    String s2 = new String("Bye");
    String s3 = s2; // s3 is now an alias for s2
    System.out.println(s3);              // Bye
    System.out.println(s2 == s3);        // true
    System.out.println(s2.equals(s3));  // true
  }
}
cs

 

 

2. new 연산자로 만든 문자열의 비교 (Equality with new String)

  • 문자열 클래스를 이용해 문자열 객체를 new 연산자로 만들 수 있다.
  • 이렇게 new 연산자로 만든 두 개의 문자열 객체는, 비록 같은 문자열 데이터를 가지고 있어서도 ==로 비교하면 서로 다른 객체이기 때문에 false 가 나와버린다.
  • 그래서 new 연산자로 만든 두 개의 문자열 객체는 equals()메소드로 비교해야 문자열 데이터를 정확히 비교해서 원하는 값을 얻을 수 있다.

 

[예제2] 위 내용에 대한 실제 사례인 아래의 코드를 실행해 보세요.

1
2
3
4
5
6
7
8
public class Main {
  public static void main(String[] args) {
    String s1 = new String("Hello");
    String s2 = new String("Hello");
    System.out.println(s1 == s2);        // fasle
    System.out.println(s1.equals(s2));  // true
  }
}
cs

 

 

[요약]
Only use == with primitive types like int or to test if two strings (or objects) refer to the same object. Use equals(), not ==, with strings to test if they are equal letter by letter.

 

  • Note that you can also create Strings using string literals instead of new, like String s = "Hello"String literals behave a little differently because they are re-used if they already exist instead of creating a new object.But you should not see questions with string literals and == on the AP exam.

 

 

[유제1] 아래의 코드가 모두 실행된 이후에, 보기(A~C)중 true 인 것은?

1
2
3
4
String s1 = new String("hi");
String s2 = new String("bye");
String s3 = new String("hi");
s2 = s1;
cs

 

A. s1 == s2 && s1 == s3

B. s1 == s2 && s1.equals(s3)

C. s1 != s2 && s1.equals(s3)

 

 

[유제2] 아래의 코드가 모두 실행된 이후에, 보기(A~C)중 true 인 것은?

1
2
3
String s1 = new String("hi");
String s2 = new String("bye");
String s3 = new String("hi");
cs

 

A. s1 == s2 && s1 == s3

B. s2.equals(s3) && s1.equals(s3)

C. s1 != s3 && s1.equals(s3)

 

 

[유제3] 아래의 코드가 모두 실행된 이후에, 보기(A~C)중 true 인 것은?

1
2
3
String s1 = new String("hi");
String s2 = new String("bye");
String s3 = new String("hi");
cs

 

A. s1 == s3 && s1.equals(s3)

B. s2.equals(s3) && s1.equals(s3)

C. !(s1 == s2) && !(s1 == s3)

 

 

3. null 값 비교(Comparing with null)

null에 대한 아주 자세한 설명 링크: 클릭

 

  • boolean, int, double 같은 primitive types 에서 값이 없거나 초기상태를 표현하기 위해 false, 0, 0.0을 활용할 수 있다.
  • 그런데 주소값을 담고 있는 reference variable에 0을 넣는다면, 이는 주소값과 헷갈릴 수 있으므로 권장하지 않는다.
  • 따라서 reference variable에 담긴 데이터가 주소값이 없거나 초기상태인 것을 표현하기 위해 null을 사용한다.
  • 그리고 A &&  B 연산자 비교를 할 때, 앞에 부분 A에서 false가 되면, 뒤에 B는 굳이 비교하지 않아도 전체가 false가 되므로, B부분은 연산 처리를 하지 않는다. 이러한 것을 short-circuit evaluation 이라고 부른다.

 

[예제3] 아래 코드를 실행해 보면 NullPointerException 에러가 발생할 것이다. 변수 s에 "apple"을 넣어서 다시 실행해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Main {
  public static void main(String[] args) {
    String s = null;
    if (s.indexOf("a">= 0// error "NullPointerException"
    {
        System.out.println(s + " contains an a");
    }
    if (s != null && s.indexOf("a">= 0)
    {
        System.out.println(s + " contains an a");
    }
  }
}
cs

 

  • 위 코드에서, s값은 null이기 때문에 indexOf로 s에 접근을 하면 NullPointerException 에러가 발생한다. s는 아무것도 가르키지 않는 상태이기 때문에 접근할 수 없다.
  • 그리고 s!=null 이 false이기 때문에 && 뒤에 오는 부분은 연산 처리를 하지 않는다.

 

 

[유제4] 아래 코드의 실행 결과는 무엇인가요?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Main {
  public static void main(String[] args) {
    String s1 = null;
    String s2 = new String("hi");
    String s3 = new String("hi");
    String s4 = new String("bye");
    if (s1 == null)
    {
        s1 = s2;
    }
    if (s1 == s2)
    {
        System.out.println("s1 and s2 refer to the same object");
    }
    if (s2 == s3)
    {
        System.out.println("s2 and s3 refer to the same object");
    }
    if (s3 == s4)
    {
        System.out.println("s3 and s4 refer to the same object");
    }
    if (s1.equals(s2) && s2.equals(s3))
    {
        System.out.println("s1, s2, s3 are equal");
    }
  }
}
cs

 

A.

    s1 and s2 refer to the same object

    s1, s2, s3 are equal

 

B.

   s1 and s2 refer to the same object

   s2 and s3 refer to the same object

 

C.

   s1, s2, s3 are equal

 

D.

   s2 and s3 refer to the same object

   s3 and s4 refer to the same object

 

 

 

[전체 이론 요약]

1. Often classes have their own equals method, which can be used to determine whether two objects of the class are equivalent.
2. Two object references are considered aliases when they both reference the same object.
3. Object reference values can be compared, using == and !=, to identify aliases.
4. A reference value can be compared with null, using == or !=, to determine if the reference actually references an object.

 

 

 


 

[유제 정답은 아래 "더보기" 클릭]

더보기

[유제1 정답]

B

(s2 was set to refer to the same object as s1 and s1 and s3 have the same characters)

 

[유제2 정답]

 C

(s1 and s3 refer to different string objects but they contain the same characters "hi" in the same order)

 

[유제3 정답]

C

(All of the variables refer to different objects. But, s1.equals(s3) would be true since they have the same characters in the same order)

 

[유제4 정답]

A

728x90
반응형

댓글