java - boolean equals(Object obj) 주소, String 비교

imjingu·2023년 8월 31일
0

개발공부

목록 보기
436/481

boolean equals(Object obj)
두 인스턴스가 동일한지 여부를 반환, 재정의하여 논리적으로 동일한 인스턴스임을 정의할 수 있음
equals() 메서드의 원래 기능은 두 인스턴스의 주소값을 비교하여 boolean 값(true / false) 을 반환해 주는 것
주소 값이 같다면 당연히같은 인스턴스지만 서로 다른 주소를 가질 때도 같은 인스턴스라고 정의할 수 있는 경우가 있음
따라서 물리적 동일성 (인스턴스의 메모리 주소가 같음)뿐 아니라 논리적 동일성(논리적으로 두 인스턴스가 같음)을 구현할 때도 equals()메서드를 재정의 하여 사용

package chapter20230831;
class Comp {
	String name;
	Comp(String name) {
		this.name = name;
	}
}
public class BooleanEquals {

	public static void main(String[] args) {
		
		Comp comp1 = new Comp("비교1");
		Comp comp2 = new Comp("비교2");
		System.out.println(comp1 == comp2); // false. 두 인스턴스의 주소 값은 다름
		System.out.println(comp1.equals(comp2)); // false. equals 메소드도 주소값을 비교
		
		// String, Integer 클래스의 equals() 메서드 재정의
		String str1 = new String("abc");
		String str2 = new String("abc");
		
		System.out.println(str1 == str2); // false. 두 스트링 인스턴스의 주소 값은 다름
		System.out.println(str1.equals(str2)); // true. String 클래스의 equals 메소드가 재정의 됨, 동일한 문자를 비교
		
		Integer i1 = new Integer(100);
		Integer i2 = new Integer(100);
		
		System.out.println(i1 == i2); // false. 두 정수 인스턴스의 주소 값은 다름
		System.out.println(i1.equals(i2)); // true integer 클래스의 equals 메소드가 재정의 됨, 동일한 숫자를 비교

	}

}

package chapter20230831;
class Student {
	int studentId; // 필드 만듬
	String studentName;
	
	public Student(int studentId, String studentName) { // 매개변수가 있는 생성자
		this.studentId = studentId;
		this.studentName = studentName;
	}

	@Override
	public String toString() {
		return studentId + "," + studentName;
	}

	@Override
	public boolean equals(Object obj) { // equals() 메서드 재정의, 학번이 같으면 같은 학생으로 재정의
		if(obj instanceof Student) { // 동일한 클래스의 객체이면
			Student std = (Student)obj; // Student 클래스로 형변환, 다운캐스팅
			if(this.studentId == std.studentId && this.studentName.equals(std.studentName)) { // 이 객체의 학번과 매개변수로 넘어온 객체의 학번이 같고,이 객체의 이름과 매개변수로 넘어온 이름이 같으면 true 반환
				return true;
			}
			else return false;
		}
		return false;
	}
	
	@Override
	public int hashCode() { // 해시코드 값으로 학번을 반환하도록 메서드 재정의
		return studentId; 
	}
	
	
	
}
public class test01 {

	public static void main(String[] args) {
		Student studentLee = new Student(100, "이상원");
		Student studentLee2 = studentLee; 
		Student studentSang = new Student(100, "라이언");
		/* 동일한 주소의 두 인스턴스 비교 */
		if(studentLee == studentLee2)
			System.out.println("studentLee와 studentLee2의 주소는 같습니다.");
		else
			System.out.println("studentLee와 studentLee2의 주소는 다릅니다.");
		// studentLee와 studentLee2는 주소는 같습니다.
		
		// 문자열의 비교
		if(studentLee.equals(studentLee2))
			System.out.println("studentLee와 studentLee2의 동일합니다.");
		else
			System.out.println("studentLee와 studentLee2의 동일하지 않습니다.");
		// studentLee와 studentLee2는 동일합니다.
		
		/* 2. 동일인이지만 인스턴스의 주소가 다른경우 */
		if(studentLee == studentSang)
			System.out.println("studentLee와 studentSang의 주소는 같습니다.");
		else
			System.out.println("studentLee와 studentSang의 주소는 다릅니다.");
		// studentLee와 studentSang의 주소는 다릅니다.
		
		if(studentLee.equals(studentSang))
			System.out.println("studentLee와 studentSang의 동일합니다.");
		else
			System.out.println("studentLee와 studentSang의 동일하지 않습니다.");
		// studentLee와 studentSang의 동일하지 않습니다.
		
		System.out.println("studentLee의 hashcode : " + studentLee.hashCode()); // studentLee의 hashcode : 100
		System.out.println("studentSang의 hashcode : " + studentSang.hashCode()); // studentSang의 hashcode : 100
		
		// hashCode()가 재정의 되어서, System.identityHashcode() 사용
		System.out.println("studentLee의 실제 주소값 : " + System.identityHashCode(studentLee)); // studentLee의 실제 주소값 : 1927950199
		System.out.println("studentSang의 실제 주소값 : " + System.identityHashCode(studentSang)); // studentSang의 실제 주소값 : 868693306
		

	}

}

String 클래스String을 선언하는 두 가지 방법.
1) 생성자의 매개변수로 문자열 생성.
String str1 = new String("abc");
new 예약어를 사용해서 객체를 생성하는 경우는 "abc" 문자열을 위한 메모리가 할당되고 새로운 객체가 생성.

2) 문자열 상수를 가르키는 방식.
String str3 = "abc";
생성자를 이용하지 않고 바로 문자열 상수를 가리키는 경우에는 기존에 만들어져 있던 문자열 상수의 메모리 값을 가르키게 됨.
프로그램에서 사용되는 상수 값을 저장하는 공간을 상수 풀 constant pool 이라고 함.

package chapter20230831;

public class test02 {
	    public static void main(String[] args) {
	        
	        String str1 = new String("abc"); // 생성자의 매개변수로 문자열 생성.
	        String str2 = new String("abc");

	        System.out.println(str1 == str2);    // false. 인스턴스가 매번 새로 생성되므로 str1과 str2는 주소 값이 다름.
	        System.out.println(str1.equals(str2)); // true. 문자열의 값은 같음.

	        String str3 = "abc"; // 상수 풀에 저장된 '주소' 값을 저장
	        String str4 = "abc";

	        System.out.println(str3 == str4);  //true. 문자열 abc는 상수 풀에 저장되어 있으므로 str3과 str4가 가르키는 주소 값이 같음.
	        System.out.println(str3.equals(str4)); //true.  문자열의 값도 같음.
	    }
	}

0개의 댓글