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. 문자열의 값도 같음.
}
}