자바 api
: 자바에서 기본적으로 제공하는 라이브러리
: 프로그램 개발에 자주 사용되는 클래스 및 인터페이스 모음
java.lang
: 자바 언어의 기본적인 클래스를 담고 있는 패키지
: import 하지 않고도 사용 가능
Object
: 자바의 최상위 부모 클래스
: extends 키워드가 없는 클래스는 부모가 Object 클래스이다
<Object에서 제공하는 equals 메소드>
- 매개변수로 Object 타입을 받기 때문에 모든 객체 타입을 다 매개값으로 보낼 수 있다
- Object가 제공하는 equals 메소드의 목적은 서로 다른 그릇의 주소값을 비교하여 물리적으로 동등 객체인지 여부를 반환한다(주소값 비교)
- 주로 하위 클래스에서 객체간의 논리적 동등비교를 위하여 재정의하여 사용한다
public boolean equals(Object o){
return this == o;
};
Object에서 제공하는 equals 메소드는 주소값을 비교하기 때문에
new B(),new B()로 객체 생성하여 비교하면 false를 반환
<Object가 제공하는 .hashCode()>
- 생성된 객체의 주소값을 정수화하여 호출한 곳으로 해당 정수를 반환하는 메소드
- 특정 클래스에서 equals를 재정의하여 논리적 동등비교를 하여도 hashCode()는 주소가 다르면 다른 값을 나타냄
- 물리적 주소값이 아닌 내부의 데이터값이 같으면 같은 값을 리턴하도록 재정의하여 사용할수도 있다
String은 이미 데이터가 같으면 같은 hashCode를 리턴하도록 hashCode가 재정의되어있으니 이를 활용하여 재정의할 수 있다(String에서 재정의된 내용은 ctrl 누른 상태에서 hashCode 클릭하면 확인 가능)
public int hashCode() {...};
*자바에서의 동등객체 기준
hashCode()의 결과가 동일하고(먼저 판별) Object의 equals() 메소드의 결과가 true인 경우 동등객체라 판별함
예제코드
1) extends 키워드가 없는 클래스는 부모가 Object 클래스이다
클래스 B는 A를 상속하고 있다.
클래스 A는 Object를 상속하고 있다.
public class A {
public String field01 = "A의 필드1";
public void methodA() {
System.out.println("A의 methodA 호출!");
}
}
public class B extends A {
public String fieldB = "B의 fieldB";
public int no; //고유번호
public B() {}
public B(int no) {
this.no = no;
}
public void methodB() {
System.out.println("B의 methodB 호출!");
}
}
2) Object는 모든 클래스의 조상이므로 모든 객체를 대입할 수 있다
public class B extends A {
public String fieldB = "B의 fieldB";
public int no; //고유번호
public B() {}
public B(int no) {
this.no = no;
}
public void methodB() {
System.out.println("B의 methodB 호출!");
}
public static void main(String[] args) {
B b = new B();
Object o = b; //b 안에 객체는 조상으로 Object 객체를 가지므로 자동형변환
String str = "sample";
o = str; //Object는 모든 클래스의 조상이므로 모든 객체를 대입할 수 있다
}
}
3)
Object가 제공하는 equals 메소드의 목적은 서로 다른 그릇의 주소값을 비교하여 물리적으로 동등 객체인지(주소값 비교) 여부를 반환하기 때문에 주로 하위 클래스에서 객체간의 논리적 동등비교를 위하여 재정의하여 사용한다
public class B extends A {
public String fieldB = "B의 fieldB";
public int no; //고유번호
public B() {}
public B(int no) {
this.no = no;
}
public void methodB() {
System.out.println("B의 methodB 호출!");
}
@Override
public boolean equals(Object o) {
//서로 다른 B 객체의 no 필드 값이 같으면 동등객체 true 리턴
if(o instanceof B) {
//o 매개변수에는 Object 타입이기 때문에 B의 no 필드 사용x -> B로 강제형변환
B b = (B)o;
if(no == b.no) {
return true;
}
}
return false;
}
}
public class Main01 {
public static void main(String[] args) {
B b = new B();
Object o = b;
String str = "sample";
Object o2 = b;
boolean result = o.equals(o2);
System.out.println("o.equals(o2) : "+result);
result = o.equals(b);
System.out.println("o.equals(b) : "+result);
result = str.equals(b);
System.out.println("str.equals(b) : "+result);
B b01 = new B(10);
B b02 = new B(10);
/*
Object에서 제공하는 equals 메소드는 주소값을 비교하기 때문에 new B(),new B()로
객체 생성하여 비교하면 false를 반환
*/
//equals 재정의 전에는 false 반환
result = b01.equals(b02);
System.out.println("b01.equals(b02) : " + result);
result = b01.equals(str);
System.out.println("b01.equals(str) : " + result); //false
}
}
실행결과)
o.equals(o2) : true o.equals(b) : true str.equals(b) : false b01.equals(b02) : true b01.equals(str) : false |
4) equals() 재정의하여 사용
public class Member {
public String id;
public int no;
public Member(String id) {
this.id = id;
}
public Member(String id,int no) {
this.id = id;
this.no = no;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Member) {
Member target = (Member)obj;
if(id.equals(target.id) && no == target.no) {
/*
비교하고자 하는 필드 id는 String(참조타입)이기 때문에
값의 비교를 위하여 .equals() 사용하여 비교
*/
return true;
}
}
return false;
}
}
public class EqualsExample {
public static void main(String[] args) {
Member obj1 = new Member("blue");
Member obj2 = new Member("blue");
Member obj3 = new Member("red");
if(obj1.equals(obj2)) {
System.out.println("obj1과 obj2는 동등합니다");
}else {
System.out.println("obj1과 obj2는 동등하지 않습니다");
}
if(obj1.equals(obj3)) {
System.out.println("obj1과 obj3는 동등합니다");
}else {
System.out.println("obj1과 obj3는 동등하지 않습니다");
}
}
}
실행결과)
obj1과 obj2는 동등합니다 obj1과 obj3는 동등하지 않습니다 |
5) String은 이미 데이터가 같으면 같은 hashCode를 리턴하도록 hashCode가 재정의 되어있다.
String str1 = new String("sample");
String str2 = new String("sample");
System.out.println(str1.hashCode());
System.out.println(str2.hashCode());
실행결과)
-909675094 -909675094 |
6) 각 두 객체의 id값과 no 값이 같으면 같은 hashCode를 반환할 수 있도록 hashCode 메소드를 재정의
public class Member {
public String id;
public int no;
public Member(String id) {
this.id = id;
}
public Member(String id,int no) {
this.id = id;
this.no = no;
}
@Override
public int hashCode() {
return no + id.hashCode();
}
public static void main(String[] args) {
Member m1 = new Member("홍길동",100);
Member m2 = new Member("홍길동",100);
System.out.println(m1.hashCode());
System.out.println(m2.hashCode());
}
}
실행결과)
54150162 54150162 |
7) 매개변수로 넘어온 Object의 phone 필드와 현재 객체의 phone 필드가 같고
매개변수로 넘어온 Object의 sno 필드와 현재 객체의 sno 필드가 같으면 true, 그외 false 반환
public class Student {
public String name;
public String sno;
public int age;
public String phone;
public String className;
public int classNo;
/*
sno가 같으면 같은 hashCode를 반환할 수 있도록 Object의 hashCode 메소드를 재정의
*/
/*
@Override
public int hashCode() {
return sno.hashCode();
}
*/
/* phone이 같으면 같은 hashCode 반환 */
/*
@Override
public int hashCode() {
return phone.hashCode();
}
*/
/* sno와 phone 데이터가 같은면 같은 hashCode를 반환 */
public int hashCode() {
return sno.hashCode() + phone.hashCode();
}
/* 매개변수로 넘어온 Object의 phone 필드와 현재 객체의 phone 필드가 같고
매개변수로 넘어온 Object의 sno 필드와 현재 객체의 sno 필드가 같으면 true, 그외 false
*/
@Override
public boolean equals(Object obj) {
if(obj instanceof Student) {
Student s = (Student)obj;
if(phone.equals(s.phone) && sno.equals(s.sno)) {
return true;
}
}
return false;
}
}
8) hashCode()와 equals()를 재정의하여 데이터값이 같은지 비교
public class Student2 {
private int no;
private String name;
public Student2(int no, String name) {
this.no = no;
this.name = name;
}
public int getNo() { return no; }
public String getName() { return name; }
@Override
public int hashCode() {
int hashCode = no + name.hashCode();
return hashCode;
}
@Override
public boolean equals(Object o) {
if(o instanceof Student2) {
Student2 s2 = (Student2)o;
if(name.equals(s2.name) && no == s2.no) {
return true;
}
}
return false;
}
}
public class HashCodeExample {
public static void main(String[] args) {
Student2 s1 = new Student2(1,"홍길동");
Student2 s2 = new Student2(1,"홍길동");
if(s1.hashCode() == s2.hashCode()) {
if(s1.equals(s2)) {
System.out.println("동등 객체입니다");
}else {
System.out.println("데이터가 다르므로 동등 객체가 아닙니다");
}
}else {
System.out.println("해시코드가 다르므로 동등 객체가 아닙니다");
}
}
}
실행결과)
동등 객체입니다 |
9) studentName이 같으면 동등 객체가 될 수 있도록 hashCode()와 equals()를 재정의
import java.util.HashSet;
public class Student3 {
private String studentName;
public Student3(String studentName) {
this.studentName = studentName;
}
public String getStudentName() {
return studentName;
}
@Override
public boolean equals(Object o) {
if(o instanceof Student3) {
Student3 s3 = (Student3)o;
if(studentName.equals(s3.studentName)) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
return studentName.hashCode();
}
public static void main(String[] args) {
//Student3을 저장하는 HashSet 생성
HashSet<Student3> hashSet = new HashSet<Student3>();
//Student3 저장
hashSet.add(new Student3("1"));
hashSet.add(new Student3("1")); //같은 학번이므로 중복 저장이 안됨
hashSet.add(new Student3("2"));
//저장된 Student3 수 출력
System.out.println("저장된 Student3 수:" + hashSet.size());
}
}
실행결과)
저장된 Student3 수:2 |
'Java' 카테고리의 다른 글
[Java] Date, SimpleDateFormat, Calendar (0) | 2024.08.13 |
---|---|
[Java] toString(), StringBuilder, StringTokenizer, Math, Wrapper (0) | 2024.08.10 |
[Java] 예외처리 (0) | 2024.08.08 |
[Java] 익명 객체, 다중인터페이스 (0) | 2024.08.07 |
[Java] 인터페이스 (0) | 2024.08.06 |