본문 바로가기

IT/Programming Language

[Java] 동일성(identity)과 동등성(equality)

반응형

동일성(identity)과 동등성(equality)

동일성 (identity)

  • 비교 대상의 두 객체의 메모리 주소가 같음을 의미하는 것
  • 동일성은 동일하다는 뜻으로 두 개의 객체가 완전히 같은 경우를 의미
  • 자바에서 동일성은 비교연산자 == 로 확인

Number number1 = new Number(1);
Number number2 = number1;

System.out.println(number1 == number2); // true

동등성(equality)

  • 동등성은 비교 대상의 두 객체가 논리적으로 동일한 값을 나타내고 있는지를 검사
  • 동등성에서 두 객체의 메모리 주소는 중요하지 않음.
    즉, 동일함은 동등함을 보장하지만, 반대로 동등함은 동일함을 보장하지 않음
  • 자바에서 동등성을 비교하기 위해 equals 와 hashCode 를 오버라이드해야 함

class Number {
    //...

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        Number number1 = (Number) o;
        return number == number1.number;
    }

    @Override
    public int hashCode() {
        return Objects.hash(number);
    }
}
Number number1 = new Number(1);
Number number2 = new Number(1);

System.out.println(number1.equals(number2)); // true

 

 


문자열(String)을 비교하는 방법

  • 다른 언어와 다르게 Java는 ==로 문자열이 같은지 확인하지 않음
  • ==는 object가 동일한지를 체크하기 때문에 object가 갖고 있는 문자열이 동일하다는 것을 보장하지 않기 때문

 

1. equals()으로 문자열 비교

String 클래스는 equals()를 오버라이드하여 인자로 전달된 String의 문자열을 비교
간단히 코드를 보면 == 키워드로 객체가 갖다면 더 확인하지 않고 true를 리턴
객체가 다른 경우 인자가 String이라면 문자열을 비교하여 동일한지 결과를 리턴

// String.java
public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

 

대소문자 비교

문자열을 비교할 때 대소문자도 구분하여 비교
대소문자를 구분하지 않고 알파벳이 같은지만 보려면 equalsIgnoreCase()를 사용해야 함

 

주의 사항 (NullPointerException)

equals()를 사용하면서 주의할 점은 다음과 같이 str1이 null이라면 NullPointerException이 발생

String str1 = null;
String str2 = "World";
System.out.println("a.equals(b) : " + str1.equals(str2));

하지만 인자로 전달되는 객체는 null이라도 NullPointerException가 발생하지 않음

String str1 = "Hello";
String str2 = null;
System.out.println("a.equals(b) : " + str1.equals(str2));

NullPointerException이 발생하는 것에 대해서 신경쓰고 싶지 않다면(예외처리를 하고 싶지 않다면) Objects.equals()를 사용하여 두개의 객체를 비교할 수 있음

System.out.println("str1 == str2 ? " + Objects.equals(str1, str2));
System.out.println("str1 == str3 ? " + Objects.equals(str1, str3));

 

2. == 를 이용하여 문자열 비교

==를 이용하여 문자열을 비교하면 안됨
==는 객체가 같은지(객체의 Hashcode)를 비교하지만 객체가 갖고 있는 문자열이 같은지 비교하지 않음

 

3. compareTo()를 이용하여 문자열 비교

compareTo()는 두개의 문자열을 비교
두개의 문자열이 같은지 확인할 수 있는 equals()와 다르게 어떤 문자가 사전적인 순서로 앞에 있는지도 결과 값으로 리턴
compareTo()를 이용하면 리스트를 오름차순으로 정렬하거나 내림차순으로 정렬할 수 있음

리턴 값 (0, 음수, 양수의 int)

  • 0 : 두개의 문자열이 동일
  • 양수 : compareTo()를 호출하는 객체가 인자보다 사전적으로 순서가 앞설 때
  • 음수 : 인자가 객체보다 사전적으로 순서가 앞설 때
반응형