>Java >java지도 시간 >Java에서 hashCode 및 equals 메소드의 올바른 사용

Java에서 hashCode 및 equals 메소드의 올바른 사용

高洛峰
高洛峰원래의
2016-12-16 10:25:341314검색

이번 글에서는 hashCode와 equals 메소드에 대한 제가 이해한 내용을 알려드리겠습니다. 기본 구현과 이를 올바르게 재정의하는 방법에 대해 설명하겠습니다. 또한 Apache Commons에서 제공하는 툴킷을 사용하여 구현해 보겠습니다.

디렉터리:

hashCode() 및 equals() 사용

기본 구현 재정의

Apache Commons Lang 패키지를 사용하여 hashCode 다시 작성 () 및 equals()

기억할 사항

ORM 사용 시 특히 주의할 사항

hashCode() 및 equals()는 Object 클래스에 정의되어 있으며, 이 클래스는 모든 Java 클래스의 기본 클래스이므로 모든 Java 클래스는 이 두 메서드를 상속합니다.


hashCode() 및 equals() 사용

hashCode() 메서드는 특정 개체의 고유한 정수를 가져오는 데 사용됩니다. 이 정수는 HashTable과 같은 구조에서 개체가 저장되는 위치를 결정하는 데 사용됩니다. 기본적으로 Object 클래스의 hashCode() 메서드는 이 객체가 저장된 메모리 주소의 번호를 반환합니다.

기본 구현 재정의

이 두 가지 방법을 재정의하지 않으면 문제가 거의 발생하지 않지만 프로그램에서 일부 개체의 기본 구현을 변경해야 하는 경우가 있습니다.

이 예제를 살펴보겠습니다. 간단한 Employee 클래스를 만들어 보겠습니다.

public class Employee
{
    private Integer id;
    private String firstname;
    private String lastName;
    private String department;
 
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getFirstname() {
        return firstname;
    }
    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public String getDepartment() {
        return department;
    }
    public void setDepartment(String department) {
        this.department = department;
    }
}

위의 Employee 클래스에는 몇 가지 매우 기본적인 속성과 getter 및 setter가 있습니다. 두 직원을 비교해야 하는 상황.

public class EqualsTest {
    public static void main(String[] args) {
        Employee e1 = new Employee();
        Employee e2 = new Employee();
 
        e1.setId(100);
        e2.setId(100);
        //Prints false in console
        System.out.println(e1.equals(e2));
    }
}

위 프로그램은 false를 출력할 것이라는 데는 의심의 여지가 없지만 사실 위의 두 개체는 직원을 나타냅니다. 실제 비즈니스 논리는 우리가 true를 반환하기를 원합니다.
이 목적을 달성하려면 같음 메서드를 재정의해야 합니다.

public boolean equals(Object o) {
        if(o == null)
        {
            return false;
        }
        if (o == this)
        {
           return true;
        }
        if (getClass() != o.getClass())
        {
            return false;
        }
        Employee e = (Employee) o;
        return (this.getId() == e.getId());
}

위 클래스에 이 메소드를 추가하면 EauqlsTest가 true를 출력합니다.
그럼 끝났나요? 아니, 다른 테스트 방법을 시도해 보겠습니다.

import java.util.HashSet;
import java.util.Set;
 
public class EqualsTest
{
    public static void main(String[] args)
    {
        Employee e1 = new Employee();
        Employee e2 = new Employee();
 
        e1.setId(100);
        e2.setId(100);
 
        //Prints 'true'
        System.out.println(e1.equals(e2));
 
        Set<Employee> employees = new HashSet<Employee>();
        employees.add(e1);
        employees.add(e2);
        //Prints two objects
        System.out.println(employees);
    }

위 프로그램은 두 가지 결과를 출력합니다. 두 직원 개체가 동일하면 true를 반환하는 경우 하나의 개체만 Set에 저장되어야 합니다. 문제는 무엇입니까?
두 번째로 중요한 메서드인 hashCode()를 잊어버렸습니다. JDK Javadoc에 명시된 대로 equals() 메서드를 재정의하는 경우 hashCode() 메서드도 재정의해야 합니다. 다음 메소드를 추가하면 프로그램이 올바르게 실행됩니다.

@Override
 public int hashCode()
 {
    final int PRIME = 31;
    int result = 1;
    result = PRIME * result + getId();
    return result;
 }

Eclipse나 다른 IDE를 사용하는 경우 IDE에서 잘 생성된 hashCode() 메서드와 equals() 메서드도 제공할 수 있습니다.

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
public class Employee
{
 private Integer id;
 private String firstname;
 private String lastName;
 private String department;
public Integer getId() {
    return id;
 }
 public void setId(Integer id) {
    this.id = id;
 }
 public String getFirstname() {
    return firstname;
 }
 public void setFirstname(String firstname) {
    this.firstname = firstname;
 }
 public String getLastName() {
    return lastName;
 }
 public void setLastName(String lastName) {
    this.lastName = lastName;
 }
 public String getDepartment() {
    return department;
 }
 public void setDepartment(String department) {
    this.department = department;
 }
@Override
 public int hashCode()
 {
    final int PRIME = 31;
    return new HashCodeBuilder(getId()%2==0?getId()+1:getId(), PRIME).
           toHashCode();
 }
@Override
 public boolean equals(Object o) {
    if (o == null)
       return false;
    if (o == this)
       return true;
    if (o.getClass() != getClass())
       return false;
    Employee e = (Employee) o;
       return new EqualsBuilder().
              append(getId(), e.getId()).
              isEquals();
    }
 }

기억할 사항

Java에서 hashCode 및 equals 메소드의 올바른 사용 hashCode() 및 equals() 메서드를 생성하는 데 개체의 동일한 속성이 사용되는지 확인하세요. 우리의 경우 직원 ID를 사용합니다.

eqauls 메소드는 일관성을 유지해야 합니다(객체가 수정되지 않은 경우 equals는 동일한 값을 반환해야 함)

a.equals(b)가 사용될 때마다 a.hashCode( )는 b와 동일해야 합니다. .hashCode()는 동일합니다.

둘 다 동시에 다시 작성해야 합니다.

ORM 사용 시 주의사항

ORM을 사용하여 일부 개체를 처리하는 경우 직접 참조하는 대신 hashCode() 및 equals() 개체에 getter 및 setter를 사용해야 합니다. 멤버변수. 때때로 ORM의 멤버 변수가 느리게 로드되기 때문에 이러한 변수는 getter 메서드가 호출될 때만 실제로 사용할 수 있습니다.

예를 들어 e1.id == e2.id를 사용하면 이 문제가 발생할 수 있지만 e1.getId() == e2.getId()를 사용하면 발생하지 않습니다. .

Java에서 hashCode 및 equals 메소드의 올바른 사용과 관련된 더 많은 기사를 보려면 PHP 중국어 웹사이트에 주목하세요!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.