인프런 커뮤니티 질문&답변

최재영님의 프로필 이미지
최재영

작성한 질문수

나도코딩의 자바 기본편 - 풀코스 (20시간)

퀴즈 #9

equals() 와 getter의 차이

해결된 질문

작성

·

357

0

 public class _Quiz_09 {
    public static void main(String[] args) {
        List<Student> list = new ArrayList<>();
        list.add(new Student("유재석","파이썬"));
        list.add(new Student("박명수","자바"));
        list.add(new Student("김종국","자바"));
        list.add(new Student("조세호","C"));
        list.add(new Student("서장훈","파이썬"));

        System.out.println("자바 자격증을 보유한 학생");
        System.out.println("========================");

        for (Student student : list) {
            if (student.getCertification() == "자바"){
                System.out.println(student.getName());
            }
        }


    }
}

class Student{
    private String name;
    private String certification;

    public Student(String name, String certification) {
        this.name = name;
        this.certification = certification;
    }

    public String getName() {
        return name;
    }

    public String getCertification() {
        return certification;
    }
}

저는 Student 클래스를 생성할 때 getter를 만들어서 getter로 자바 자격증을 찾는 로직을 짯는데

equals()와 getter를 비교했을때 어느 방법이 성능면이나 이점이 있는지 알 수 있을까요 ?

답변 1

1

나도코딩님의 프로필 이미지
나도코딩
지식공유자

안녕하세요?

먼저 퀴즈를 훌륭하게 잘 풀어주셨습니다. 현재 상태로 수행을 하면 원하는 결과도 잘 출력이 되고 있지요. 그런데 한 가지 문제가 있습니다. 바로 == 연산자인데요.

퀴즈 해설에서 제공해드린 아래 코드와 비교해서 getter 를 쓰신 것은 아주 잘 하셨습니다. certification 인스턴스 변수를 직접 접근하는 것보다는 getter 또는 setter 로 접근하는 것이 권장되니까요.

if (student.certification.equals("자바")) { 
   ...
}

하지만 다음과 같이 했을 때 경우에 따라 올바로 동작하지 않을 수도 있습니다.

if (student.getCertification() == "자바"){
    ...
}

자바에서 특히 문자열 비교를 할 때 == 연산자와 equals() 메소드를 주의해서 써야 하는데요. == 연산자는 해당 문자열이 위치하고 있는 메모리 주소가 같은지를 비교하는 것입니다. 반면에 equals() 메소드는 값(예: 자바)이 동일한지를 비교하는 거예요.

작성해주신 코드의 경우 "자바" 라는 문자열이 한 곳에 저장되어 있기 때문에 == 을 써도 true 라는 결과를 얻을 수 있게 됩니다. 제가 예시를 조금 간단하게 바꿔볼게요.

String s1 = "자바";
String s2 = "자바";

if (s1 == s2) { // true
    ...
} 

if (s1.equals(s1)) { // true
    ...
}

위 경우 두 if 문 모두 true 가 나오게 됩니다. s1 과 s2 는 "자바" 라는 문자열이 존재하는 메모리 공간을 동일하게 가리키기 때문이에요. "자바" 는 값이 같기 때문에 굳이 다른 메모리 공간에 둘 필요가 없지요. 하지만 코드를 다음과 같이 바꾸면 어떻게 될까요?

String s1 = new String("자바");
String s2 = new String("자바");

if (s1 == s2) { // false
    ...
} 

if (s1.equals(s1)) { // true
    ...
}

이번에는 == 연산자를 비교했을 때는 false 라는 결과가 나오게 됩니다. 우리가 명시적으로 new String() 을 통해 문자열을 만들게 되면 비록 문자열의 값이 같더라도 서로 다른 공간에 값이 저장되거든요.

일반적으로는

String s1 = new String("자바");

보다는

String s1 = "자바";

와 방식으로 문자열을 정의하기 때문에 == 를 써도 크게 문제가 되지 않는 것처럼 보일 수가 있습니다.

하지만 문자열은 다양하게 다뤄질 수 있어요.

가령 제가 예시를 다음과 같이 바꿔볼게요.

이번에는 프로그래밍 언어 이름 뒤에 "몇 급" 이라고 하는 급수도 추가가 되었습니다.

List<Student> list = new ArrayList<>();
list.add(new Student("유재석","파이썬 1급"));
list.add(new Student("박명수","자바 2급"));
list.add(new Student("김종국","자바 2급"));
list.add(new Student("조세호","C 2급"));
list.add(new Student("서장훈","파이썬 2급"));

그러면 "자바" 자격증을 보유한 학생을 찾기 위해서 "몇 급" 정보 부분을 제외하고 비교를 해야겠죠?

이때는 substring 을 이용해서 이렇게 할 수 있습니다.

먼저 질문자께서 작성하신 코드 기준으로 수정을 해보면 이렇게 되겠네요.

System.out.println("자바 자격증을 보유한 학생");
System.out.println("========================");

for (Student student : list) {
    String cert = student.getCertification();
    // 0 위치로부터 (문자열의 길이 - 3) 직전까지를 잘라내기 
    // 예: "자바 2급" -> "자바"
    cert = cert.substring(0, cert.length() - 3);
    if (cert == "자바"){
        System.out.println(student.getName());
    }
}

실행 결과는 어떻게 될까요?

(실행 결과)
자바 자격증을 보유한 학생
========================

분명 자바 자격증을 가진 학생은 2명이 있지만 결과가 올바로 출력되지 않았습니다.

== 연산자는 메모리 주소가 같은지를 비교한다고 했는데 우리가 비교하려는 "자바" 라는 문자열, 그리고 학생이 보유한 자격증 정보가 저장된 문자열인 "자바 2급" 을 "자바" 로 바꾸었을 때의 메모리 주소가 달라서 그런 것이죠.

코드를 이렇게 바꿔볼게요.

System.out.println("자바 자격증을 보유한 학생");
System.out.println("========================");

for (Student student : list) {
    String cert = student.getCertification();    
    cert = cert.substring(0, cert.length() - 3);
    if (cert.equals("자바")){ // 수정된 부분
        System.out.println(student.getName());
    }
}

이번에는 == 를 equals() 로 바꾸어보았더니

(실행 결과)
자바 자격증을 보유한 학생
========================
박명수
김종국

위와 같이 자바 자격증을 보유한 학생이 급수에 관계 없이 모두 올바로 출력된 것을 알 수 있습니다. 이번에는 equals() 를 통해 문자열의 값인 "자바" 를 비교했기 때문에 원하는 결과가 나오게 된 거에요.

문자열 비교는 굉장히 혼란스러울 수 있는 부분이기 때문에 설명을 다시 한번 천천히 곱씹어 보면서 이해하시면 좋겠습니다 😊

감사합니다.

최재영님의 프로필 이미지
최재영

작성한 질문수

질문하기