equals()메서드 vs 등가비교연산자

태로미·2023년 9월 6일
0

JAVA

목록 보기
1/3
post-thumbnail




✍🏻개요


두 개의 대상의 데이터 혹은 주소값을 비교하고 싶을 때,
어떤 상황에서 어떤걸 사용하는게 더 정확할까?🤔







📌equals() 메서드


개념

  • Object 클래스의 메서드 중의 하나로서 객체를 비교할 때 주로 사용됨.
  • 두 인스턴스의 주소값을 비교하여 같은 인스턴스인지를 확인하고 같으면 true, 다르면 false의 boolean값을 리턴하는 메서드.
    • 여기서 주소 값을 비교했을 때 값이 같다면 당연히 같은 인스턴스.
public class equalTest {
    public static class Student {
		
        // 멤버변수
		String name;
        int studentNum;
        
		// 생성자
        public Student (String name, int studentNum) {
            this.name = name;
            this.studentNum = studentNum;
        }
    }

    public static void main(String[] args) {
        Student st1 = new Student("kim", 111);
        Student st2 = new Student("Lee", 222);
        Student st3 = st1;
		Student st4= new Student("kim", 111);

        System.out.println(st1.equals(st2));   // false
        System.out.println(st1.equals(st3));   // true
		System.out.println(st1.equals(st4));   // false
    }
}
  • Student 클래스를 임의로 생성함.
    • 이는 내가 만든 클래스이므로 이미 Object 클래스에 정의되어있는 equals() 메서드를 오버라이딩 하여 내 입맛대로 사용할 수 있음.
  • st1과 st4는 이름과 학번이 모두 동일한 학생, 이는 논리적으로 같은 학생임.
    • 그러나 각각 새로운 객체를 생성하여 값을 저장하였음.
    • 인스턴스의 주소가 다르므로 equals() 메서드 사용 시 false값 return.
  • st1과 st2는 명확하게 다른 인스턴스임을 알 수 있고,
    st3은 st1을 복사해온 것이므로 st1과 같은 주소값을 가짐.

오버라이딩

  • st1과 st4는 사실상 논리적으로 봤을 때 같은 학생.
  • 논리적으로 동일한 두 인스턴스는 같은 학생으로 처리해야 맞는 결과.
  • equals() 메서드를 오버라이딩하여 이런 경우도 프로그램상 같다고 판단할 수 있도록 구현해야 함.
@Override
public boolean equals(Object obj) {

	// 비교대상이 Student형이면
	if (obj instanceof Student) { 
	Student std = (Student)obj;

    if(this.studentNum == std.studentNum)
		// 학번이 같으면 같은 사람
		return true; 
    else
		return false;
 	 }

	return false;
}
public static void main(String[] args) {
	Student st1 = new Student("kim", 111);
	Student st2 = new Student("Lee", 222);
	Student st3 = st1;
	Student st4= new Student("kim", 111);
	
	System.out.println(st1.equals(st2));   // false
	System.out.println(st1.equals(st3));   // true
	System.out.println(st1.equals(st4));   // true
}
  • 논리적으로 동일한 학생일 경우 true의 값을 return할 수 있도록
    equals() 메서드를 재정의 했으므로, return값은 true.

String 클래스의 equals()

  • String 클래스에는 이미 equals() 메서드가 오버라이딩 되어 있음.
  • 인스턴스 주소값을 비교하지 않고,
    문자열의 내용을 비교하여 두 대상의 내용이 같으면 같다고 판단함.
public static void main(String[] args) {
	String str1 = "abc";
	String str2 = "abc";

	System.out.println(str1.equals(str2));  // true
}

Integer 클래스의 equals()

  • Integer 클래스에서도 equals() 메서드가 오버라이딩 되어 있어,
    인스턴스의 주소값이 아닌 변수에 할당된 값을 비교하여 판단함.
public static void main(String[] args) {
	Integer num1 = 100;
	Integer num2 = 100;

	System.out.println(num1.equals(num2));  // true
}






📌등가비교연산자


개념

  • 두 개의 피연산자를 비교하여 true 또는 false의 논리 값을 내는 비교연산자.
  • int, double, char, float 등과 같은 기본형 타입을 비교하는데 사용되며,
    비교하고자 하는 두 개의 대상의 주소값을 비교함.
    • null이 아닌 참조 값에 대해 두 개체 참조를 비교할 때는 사용하지 않음.
  • 참조 타입 변수들간의 비교연산은
    동일한 객체를 참조하는지, 다른 객체를 참조하는지 알아볼 때 사용됨.

String 클래스의 등가비교

String 변수 생성 방법

String str1 = "apple";                      // 리터럴
String str2 = new String("banana");         // new 연산자
  • str1은 리터럴(literal)을 사용하여 생성, str2는 new 연산자를 사용하여 생성.
  • 리터럴을 사용하게 되면 String Constant Pool이라는 영역에 존재하게 되고,
    new 연산자를 통해 생성하면, Heap영역에 존재하게 됨.
String str1 = "apple";
String str2 = new String("banana");
String str3 = str1;
String str4 = "apple";

System.out.println(str1 == str2);	  // false
System.out.println(str1 == str3);	  // true
System.out.println(str1 == str4);	  // true
  • String을 리터럴로 선언할 경우 내부적으로 String의 intern() 메서드가 호출,
    주어진 문자열이 String Constant Pool에 존재하는지 검색함.
  • 있다면 그 주소값을 반환, 없다면 String Constant Pool에 넣고 새로운 주소값을 반환.






📌차이점

  • 기본형 타입은 Call by Value 형태로, 대상에 주소값을 가지지 않음.
  • 클래스는 기본적으로 Call by Reference 형태로, 생성 시 주소값이 부여되며,
    String타입의 경우 클래스이므로 같은 값을 부여하더라도 주소값이 다름.

문자열 비교

등가비교연산자

String s1 = "apple";
String s2 = new String("apple");

if(s1 == s2) {
    System.out.println("두개의 값이 같음.");
} else {
    System.out.println("두개의 값이 같지 않음.");
}
  • ==는 객체가 같은지를 비교하지만 객체가 갖고 있는 문자열을 비교하진 않음.
  • 참조 타입 변수들간의 비교연산은 동일한 객체를 참조하는지,
    다른 객체를 참조하는지 알아볼 때 사용됨.
  • 참조 타입의 변수의 값은 Heap영역의 객체 주소이므로,
    결국 주소 값을 비교하는 것이 되어 다르다는 결론이 나온 것.
  • Java에서 문자열을 비교하려면,
    equals() 메서드를 활용하여 두 개의 값을 비교해주어야 함.

equals() 메서드

String s1 = "apple";
String s2 = new String("apple");

if(s1.equals(s2)) {
    System.out.println("두개의 값이 같음.");
} else {
    System.out.println("두개의 값이 같지 않음.");
}
  • String 클래스안에 있는 equals() 메서드 사용 시,
    두 비교대상의 주소 값이 아닌 데이터값을 비교하기 때문에
    어떻게 String을 생성하느냐에 따라 결과가 달라지지 않고 정확한 비교 가능.






💭마무리


이게 참~~또 은근 헷갈려서 알아보기 쉽게 포스팅을 해보았다ㅎㅎㅎ
포스팅을 하며 정리하다보니 확실히 좀 더 자세하게 깨닫게 되는 듯~~
앞으로는 문자열 자체만 비교할 때는 equals() 메서드를 사용하도록 하자😎







profile
Here And Now

0개의 댓글