자바 에 서 는 두 대상 이 같은 지 아 닌 지 를 어떻게 판단 합 니까?

43620 단어 Java자바
  • 두 대상 이 같다 는 것 을 어떻게 판단 하 는 지 이 문 제 는 실제로 equals 방법 과 hashcode 방법 에 대한 이해 로 볼 수 있다.다음 과 같은 몇 가지 점 에서 equals 와 hashCode 방법 을 이해 합 니 다.1.equals 의 역할 과=의 차이.2.hashcode 의 역할 및 equals 와 의 관계.

  • 1.equals 의 역할 및=의 차이.
    equals 는 두 대상 이 같은 지 아 닌 지 를 판단 하 는 데 사용 된다.equals 는 보통 두 대상 의 내용 이 같 는 지 비교 하 는 데 사용 되 며,==두 대상 의 주소 가 같 는 지 비교 하 는 데 사용 된다.equals 방법 은 기본적으로'=='Object 클래스 의 equals 방법 과 같 으 며,주소 가 같 으 면 대상 이 같다 고 판단 합 니 다.이것 은 우리 가 새로 만 든 모든 클래스 가 이퀄 스 를 복사 하 는 방법 이 없다 면 두 대상 이 같은 지 여 부 를 판단 할 때'==',즉 두 대상 의 주소 가 같은 지 여 부 를 판단 하 는 것 을 의미한다.Object 클래스 의 equals 방법 은 다음 과 같 습 니 다.
    public boolean equals(Object obj) {
            return (this == obj);
        }
    

    그러나 우리 의 실제 개발 에 서 는 두 대상 의 내용 이 같다 고 생각 할 때 두 대상 이 같 고 equals 는 true 로 돌아간다.대상 내용 이 다 르 면 false 로 돌아 갑 니 다.
  • 그래서 두 가지 상황 으로 요약 할 수 있 습 니 다.1.복사 되 지 않 은 equals 방법 은 equals 방법 으로 두 대상 을 비교 할 때==비교,즉 두 대상 의 주소 가 같 습 니까?주소 가 같 습 니 다.true 로 돌아 갑 니 다.주소 가 같 지 않 습 니 다.false 로 돌아 갑 니 다.2.클래스 복사 equals 방법 으로 두 대상 을 비교 할 때 복사 후의 판단 방식 을 취한 다.일반적으로,우 리 는 equals 를 다시 쓴다.두 대상 의 내용 이 같 으 면 equals 는 true 로 돌아 가 고,내용 이 같 지 않 으 면 false 로 돌아간다.예 를 들 어
  • public class EqualTest {
    public static void main(String[] args) {
    	Person p1 = new Person(10,"  ");
    	Person p2 = new Person(10,"  ");
    	System.out.println(p1.equals(p2));
    	}
    }
    class Person{
    	int age;
    	String name;
    	public Person(int age, String name) {
    		super();
    		this.age = age;
    		this.name = name;
    	}
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    }
    

    Person 이 equals 방법 을 복사 하지 않 으 면 기본적으로 Object 의 equals 를 사용 합 니 다.즉,두 대상(p1 과 p2)의 메모리 주 소 를 판단 합 니 다.p1 과 p2 는 메모리 주소 가 다 르 기 때문에 출력 결 과 는 false 입 니 다.우리 가 equals 방법 을 복사 하면?우 리 는 이름과 나이 가 같은 사람 이 같은 사람 이 라 고 생각한다.그러면 p1 과 p2 는 모두 10 세의 장 삼 을 나타 내 는데 이 두 대상 은 같 아야 한다.복사 한 equals 방법 은 다음 과 같 습 니 다.
    @Override
    public boolean equals(Object obj) {
    	if (this == obj)
    		return true;
    	if (obj == null)
    		return false;
    	if (getClass() != obj.getClass())
    		return false;
    	Person other = (Person) obj;
    	if (age != other.age)
    		return false;
    	if (name == null) {
    	if (other.name != null)
    		return false;
    	} else if (!name.equals(other.name))
    		return false;
    	return true;
    }
    

    마찬가지 로 상술 한 용례 를 집행 하여 얻 은 결 과 는 true 이다.BTW:equals 방법 이 true 로 돌아간다 면==역시 true 입 니까?꼭 트 루 는 아니 야.equals 가 true 로 돌아 갈 수 있 는 두 가지 가능성 이 있 습 니 다.하 나 는 두 대상 의 주소 가 같 고 하 나 는 두 대상 의 내용 이 같 습 니 다.내용 이 같 으 면 주소 가 다 를 수 있 기 때문에==비교 결 과 는 false 일 수 있 습 니 다.우 리 는 main 방법 에=에 대한 판단 을 더 하면 다음 과 같다.
    
    public static void main(String[] args) {
    	Person p1 = new Person(10,"  ");
    	Person p2 = new Person(10,"  ");
    	System.out.println(p1.equals(p2));
    	System.out.println(p1 == p2);
    }
    

    출력 결과 가 뚜렷 합 니 다.p1==p2 의 결 과 는 false 입 니 다.
    자바 에서 equals 에 대한 요 구 를 추가 합 니 다:
    
    1.    :  x.equals(y)   "true",  y.equals(x)      "true"。
    2.    :x.equals(x)     "true"。
    3.    :  x.equals(y)   "true",  y.equals(z)   "true",  z.equals(x)      "true"。
    4.    :  x.equals(y)   "true",  x y      ,     x.equals(y)   ,    "true"。
    5.    ,x.equals(null),     "false";x.equals( x       )     "false"。
    

    2.hashCode 의 역할 및 equals 와 의 관계.
    hashCode 의 역할 은 해시 코드 를 얻 는 것 이 고 해시 코드 라 고도 할 수 있 습 니 다.실제 반환 값 은 int 형 데이터 입 니 다.대상 이 해시 표 에 있 는 위 치 를 확인 하 는 데 사용 합 니 다.Object 에 hashcode 방법 이 있다 는 것 은 모든 종류 에 hashCode 방법 이 있다 는 것 을 의미한다.그러나 hashcode 는 특정한 종류의 산 목록 을 만 들 때 만 유용 합 니 다.hashcode 값 에 따라 대상 이 산 목록 에 있 는 위 치 를 확인 해 야 하지만 다른 경우 에는 소 용이 없습니다.자바 에 서 는 본질 적 으로 산 목록 류 에서 흔히 볼 수 있 는 HashMap,HashSet,HashTable 이 있 기 때문에 대상 이 산 목록 에서 사용 하지 않 는 다 면 hashCode 방법 을 복사 할 필요 가 없습니다.그러나 일반적인 상황 에서 우 리 는 hashCode 방법 을 복사 합 니 다.왜냐하면 누가 이 대상 이 더 이상 hashMap 등 이 나타 나 지 않 을 것 이 라 고 보장 할 수 있 습 니까?예 를 들 어 두 대상 이 equals 가 같 을 때 hashcode 는 반드시 같 지 않다.
    public class EqualTest {
    	public static void main(String[] args) {
    		Person p1 = new Person(10, "  ");
    		Person p2 = new Person(10, "  ");
    		System.out.println(
    		"p1.equals(p2)=" + p1.equals(p2) + ", p1.hashcode=" + p1.hashCode() + ", p2.hashcode=" + p2.hashCode());
    	}
    }
    class Person {
    	int age;
    	String name;
    	public Person(int age, String name) {
    		super();
    		this.age = age;
    		this.name = name;
    	}
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	@Override
    	public boolean equals(Object obj) {
    		if (this == obj)
    			return true;
    		if (obj == null)
    			return false;
    		if (getClass() != obj.getClass())
    			return false;
    		Person other = (Person) obj;
    		if (age != other.age)
    			return false;
    		if (name == null) {
    		if (other.name != null)
    			return false;
    		} else if (!name.equals(other.name))
    			return false;
    		return true;
    	}
    }
    

    Person 은 hashCode 를 복사 하 는 방법 이 없습니다.Object 의 기본 hashCode 를 사용 하여 이 루어 집 니 다.출력 결 과 는 다음 과 같 습 니 다.
    
    p1.equals(p2)=true, p1.hashcode=246688959, p2.hashcode=1457895203
    

    결 과 를 보면 equals 는 같 지만 p1 과 p2 의 hashcode 는 다르다.
    Person 이 산 목록 의 클래스 에 사용 된다 면,여 기 는 HashSet 로 테스트 합 니 다.
    public class EqualTest {
    	public static void main(String[] args) {
    		Person p1 = new Person(10, "  ");
    		Person p2 = new Person(10, "  ");
    		System.out.println(
    		"p1.equals(p2)=" + p1.equals(p2) + ", p1.hashcode=" + p1.hashCode() + ", p2.hashcode=" + p2.hashCode());
    		HashSet<Person> set = new HashSet<Person>();
    		set.add(p1);
    		set.add(p2);
    		System.out.println(set);
    	}
    }
    class Person {
    	int age;
    	String name;
    	public Person(int age, String name) {
    		super();
    		this.age = age;
    		this.name = name;
    	}
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	@Override
    	public boolean equals(Object obj) {
    		if (this == obj)
    			return true;
    		if (obj == null)
    			return false;
    		if (getClass() != obj.getClass())
    			return false;
    		Person other = (Person) obj;
    		if (age != other.age)
    			return false;
    		if (name == null) {
    		if (other.name != null)
    			return false;
    		} else if (!name.equals(other.name))
    			return false;
    		return true;
    	}
    	@Override
    	public String toString() {
    		return "Person [age=" + age + ", name=" + name + "]";
    	}
    }
    

    출력 결과
    p1.equals(p2)=true, p1.hashcode=246688959, p2.hashcode=1457895203
    [Person [age=10, name=  ], Person [age=10, name=  ]]
    

    p1 은 p2 의 equals 와 같 습 니 다.우 리 는 두 대상 이 같다 고 생각 합 니 다.그러나 이 두 대상 이 동시에 나타 나 면 hashSet 에 두 개의 똑 같은 요소 가 나타 나 지 않 습 니 다.그 문 제 는 어디 에 있 습 니까?
  • hashset 은 하나의 요 소 를 추가 할 때 다음 과 같은 판단 을 합 니 다.1.요 소 를 추가 한 hashcode 가 같 고 대상 equals 가 true 또는 대상==일 경우 같은 요소 라 고 생각 하고 새로운 요소 에 추가 하지 않 습 니 다.2.상기 조건 에 부합 되 지 않 으 면 새로운 요소 로 보고 set 에 추가 합 니 다.따라서 p1 과 p2equals 를 비교 할 때 는 같 지만 hashcode 는 다 르 기 때문에 set 에 추가 할 때 서로 다른 요소 라 고 생각 하기 때문에 p1 과 p2 가 동시에 set 에 있 는 상황 이 발생 합 니 다.

  • 과정:대상 을 HashSet 에 추가 할 때 HashSet 은 대상 의 hashcode 값 을 먼저 계산 하여 대상 이 가입 한 위 치 를 판단 하 는 동시에 가입 한 대상 의 hashcode 값 과 비교 합 니 다.일치 하 는 hashcode 가 없 으 면 Hashset 은 대상 이 중복 되 지 않 았 다 고 가정 합 니 다.그러나 같은 hashcode 값 의 대상 이 발견 되면 equals()방법 으로 hashcode 와 같은 대상 이 정말 같 는 지 확인 합 니 다.둘 이 같 으 면 Hashset 은 가입 에 성공 하지 못 합 니 다.
    우 리 는 개선 해서 hashcode 방법 을 복사 합 니 다.다음 과 같 습 니 다.
    
    class Person {
    	int age;
    	String name;
    	public Person(int age, String name) {
    		super();
    		this.age = age;
    		this.name = name;
    	}
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	@Override
    	public int hashCode() {
    		final int prime = 31;
    		int result = 1;
    		result = prime * result + age;
    		result = prime * result + ((name == null) ? 0 : name.hashCode());
    		return result;
    	}
    	@Override
    	public boolean equals(Object obj) {
    		if (this == obj)
    			return true;
    		if (obj == null)
    			return false;
    		if (getClass() != obj.getClass())
    			return false;
    		Person other = (Person) obj;
    		if (age != other.age)
    			return false;
    		if (name == null) {
    		if (other.name != null)
    			return false;
    		} else if (!name.equals(other.name))
    			return false;
    		return true;
    	}
    	@Override
    	public String toString() {
    		return "Person [age=" + age + ", name=" + name + "]";
    	}
    }
    

    결과 다시 실행:
    p1.equals(p2)=true, p1.hashcode=776160, p2.hashcode=776160
    [Person [age=10, name=  ]]
    

    그래서 set 에 Person 값 이 하나 밖 에 없 는 것 을 보 았 습 니 다.
  • 몇 가 지 를 보충 합 니 다.1.새로운 유형,특히 업무 와 관련 된 대상 유형 을 만 들 때 equals 방법 을 복사 하 는 것 이 좋 습 니 다.2.equals 방법 을 복사 할 때 hashCode 방법 을 복사 해 야 한 다 는 것 을 기억 하 세 요.누가 이 대상 이 반드시 hashMap 에 나타 나 지 않 을 것 이 라 고 보증 할 수 있 습 니까?eclipse 의 자동 코드 를 사용 하면 eclipse 에서 equals 와 hashCode 를 복사 하 는 것 을 발견 할 수 있 습 니 다.
  • 면접 에서 자주 묻 는 몇 가지 질문 을 인용 했다.1.두 대상 이 a.equals(b)==true 라면 a 와 b 는 같 습 니까?같 지만 주소 가 꼭 같은 것 은 아 닙 니 다.2.두 대상 이 hashcode 와 같다 면 두 대상 은 같 습 니까?반드시 같 지 않 고 두 대상 이 같 는 지 판단 하려 면 equals 가 true 인지 판단 해 야 한다.
  • hashcode()와 equals()의 관련 규정
  • 두 대상 이 같 으 면 hashcode 도 똑 같 을 것 이다
  • 두 대상 이 같 고 두 equals 와 hashcode()방법 에 대해 true
  • 를 되 돌려 줍 니 다.
  • 두 대상 이 같은 hashcode 값 은 그들 도 반드시 같은 것 은 아니다
  • 종합:equals 방법 이 덮어 쓰 이면 hashcode 방법 도 덮어 써 야 합 니 다
  • hsashcode()의 기본 행 위 는 쌓 인 대상 이 독특한 값 을 만 드 는 것 입 니 다.hashCode()를 다시 쓰 지 않 으 면 클 라 스 두 대상 이 어떻게 든 같 지 않 습 니 다(이 두 대상 이 같은 데 이 터 를 가리 키 더 라 도)
  • 좋은 웹페이지 즐겨찾기