inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

퀴즈 #9

equals() 와 getter의 차이

해결된 질문

432

최재영

작성한 질문수 24

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를 비교했을때 어느 방법이 성능면이나 이점이 있는지 알 수 있을까요 ?

java 객체지향

답변 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() 를 통해 문자열의 값인 "자바" 를 비교했기 때문에 원하는 결과가 나오게 된 거에요.

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

감사합니다.

자바를 처음 배울 때 이런 고민이 드는 게 정상일까요?

1

146

2

static이 뭐였는지 기억이 안나요 ㅜㅜ

0

119

2

Iterator (알 수 없음) 데이터 삭제 후 초기화 관련 문의

0

70

1

사고력 키우는 법이 어떤게 있나요?

0

93

2

getter setter

0

103

2

섹션9. 66 메소드 오버로딩 시 질문이 있습니다.

0

80

1

안녕하세요 갑자기 프로그램 에러가 떠서 안되네요

0

76

2

변수 이름짓는법

0

114

2

intelli J 실행오류

0

115

2

혹시 이건 수학적 사고가 부족한 걸까요?

0

152

2

영상이 재생이 안됩니다.

0

167

3

이중 반복문 (후반전) 오른쪽으로 치우친 별 쌓기에 질문이 있습니다.

0

117

2

응용이 어렵습니다.

0

206

2

IntelliJ가 보이지 않습니다.

0

186

3

JDK 버전 문의

0

129

2

BlackBox 파일 내에서 메소드 정의

0

136

1

동기화

0

121

2

Iterator 문의

0

105

1

코드 순서 문의

0

142

1

클래스 메소드

0

149

2

Quiz_05 관련 질문드립니다 !

0

118

2

다운로드가 안됩니다

0

165

2

다형성

0

120

2

HashMap

0

80

2