[Java] Object, equals(), hashCode()

2024. 8. 9. 08:57·Java
목차
  1. <Object에서 제공하는 equals 메소드>
  2. <Object가 제공하는 .hashCode()>
  3. 예제코드
반응형

자바 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
  1. <Object에서 제공하는 equals 메소드>
  2. <Object가 제공하는 .hashCode()>
  3. 예제코드
'Java' 카테고리의 다른 글
  • [Java] Date, SimpleDateFormat, Calendar
  • [Java] toString(), StringBuilder, StringTokenizer, Math, Wrapper
  • [Java] 예외처리
  • [Java] 익명 객체, 다중인터페이스
초보개발자J
초보개발자J
J의 코딩 노트초보개발자J 님의 블로그입니다.
초보개발자J
J의 코딩 노트
초보개발자J
전체
오늘
어제
  • 분류 전체보기 (126)
    • Java (49)
    • MySQL (10)
    • HTML, CSS (8)
    • JavaScript, jQuery, Ajax (12)
    • Spring (15)
    • Python (0)
    • Baekjoon [Java] (27)
    • Git (1)
    • Spring Boot (3)
    • Visual Studio Code (1)
    • 일상 (0)
    • 영어 (0)
반응형

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

hELLO· Designed By정상우.v4.5.3
초보개발자J
[Java] Object, equals(), hashCode()

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.