5월 12일 내용정리
int a=3;
int b=7;
a==b
와 같이 기본타입과 String타입에서는 재정의가 되어 있어 바로 내용비교가 가능하지만, 객체타입을 비교할때는 hashCode()와 equals()메서드를 모두 오버라이딩해줘야한다.
String str="홍길동";
String str02="홍길동";
String str01= new String("홍길동");
String타입은 hashCode(), equals() 오버라이딩 되어 있기때문에 str과 str02은 스택에 각각 다른곳에 생성 되지만 내용이 같아 힙에 있는 같은 주소의 객체를 가르킨다.
str01은 new연산자로 객체를 새로 생성하므로 주소값을 새로 부여받고 다른 객체로 인지한다.
중복확인
hashCode(), equals(),toString() ->Object클래스의 메서드
Object클래스의 메서드란 모든클래스에서 사용할수 있음(포함)
Object의 equal() 은 == 과 같다. 저장된 주소값을 비교한다.
동일객체(같은객체):hashCode()와 equals()메서드를 모두 오버라이딩 했을때 확인가능하다.
hashCode() ----true---> equals() ----true---> 같은객체
| |
false false
| |
다른객체 다른객체
package study_0512;
import java.util.*;
class Test{
int data;
Test(){}
Test(int data){
this.data=data;
}
}
class Test01{
int data;
Test01(){}
Test01(int data){
this.data=data;
}
@Override
public boolean equals(Object obj) { //Object 형이라 전부다 받는다는 의미
if(obj instanceof Test01) {
if(this.data==((Test01)obj).data) {
return true;
}
}
return false;
}
}
class Test02{
int data;
Test02(){}
Test02(int data){
this.data=data;
}
@Override
public boolean equals(Object obj) { //Object 형이라 전부다 받는다는 의미
if(obj instanceof Test02) {
if(this.data==((Test02)obj).data) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
// return data; // 방법1-직접데이터 넣기기
//return new Integer(data).hashCode(); //방법2
return Objects.hash(data); //
// Objects.hash(Object ... values)
// 매개변수 값에 따른 해쉬 값 리턴
// 동일매개변수 + 동일 순서 : 동일 해쉬
}
}
public class HashExam {
public static void main(String[] args) {
Test tHash = new Test();
System.out.println(tHash); //해시코드(객체를 저장하고있는 주소)를 출력함
Test t1= new Test(10);
Test t2= new Test(10);
System.out.println(t1==t2);//t1과 t2가 new로 객체를 새로 생성했기때문에 주소값이 따로 따로 생성되어 false
System.out.println(t1.equals(t2));//객체생성시 equals는 Object클래스의 메서드 이기때문에
//재정의 안하면 주소값을 비교하기 때문에 이것도 false
String s1="홍길동"; //String은 equals()가 재정의되어 있어 내용비교가능
String s2="홍길동"; //String은 equals()가 재정의되어 있어 내용비교가능
String s3=new String("홍길동");
String s4=new String("홍길동");
Integer i1= new Integer(30);
Integer i2= new Integer(30);
System.out.println(i1==i2); // 주소값 비교, new로 객체 새로생성해서 주소다름 false
System.out.println(i1.equals(i2));//Integer는 equals로 재정의되어 있어서 내용비교가능 true
//1.hashCode()와 equals() 모두 오버라이딩 안된 상태
Test t10 =new Test (3);
Test t20 =new Test (3);
System.out.println(t10==t20); //false
System.out.println(t10.equals(t20)); //false
Set<Test>hashExam = new HashSet<>();
hashExam.add(t10);
hashExam.add(t20);
System.out.println(hashExam.size());
//2.hashCode()는 오버라이딩 하고 equals()는 안함
Test01 t3 = new Test01(3);
Test01 t4 = new Test01(3);
System.out.println(t3==t4); //false
System.out.println(t3.equals(t4)); //true
System.out.println(t3.hashCode()+","+t4.hashCode());//hashCode 다름
Set<Test01>hashExam01 = new HashSet<>();
hashExam01.add(t3);
hashExam01.add(t4);
System.out.println(hashExam01.size()); //2개, 다른객체로 인식해서
//3.hashCode()와 equals()모두 오버라이딩 하기
Test02 t5 =new Test02(3);
Test02 t6 =new Test02(3);
System.out.println(t5==t6);//false
System.out.println(t5.equals(t6));//true
System.out.println(t5.hashCode()+","+t6.hashCode()); //hashCode 같음
Set<Test02>hashExam02 = new HashSet<>();
hashExam02.add(t5);
hashExam02.add(t6);
System.out.println(hashExam02.size());//1개 Set은 중복을 허용안해서 같은내용이라 1개로 합침
}
}