이번 포스팅에서는 메소드 Apache Commons Lang 재정의
Apache Commons는 메소드
hashCode()
와 에 대한 이해를 간략하게 설명하겠습니다 equals()
. 기본 구현과 이를 올바르게 재정의하는 방법에 대해 이야기하고 싶습니다. 또한 Apache Common 패키지의 도우미 클래스를 사용하여 이러한 메서드를 구현하는 방법에 대해서도 쓸 것입니다. 이 게시물의 내용:
- 및 .
hashCode()
_equals()
- 기본 동작을 재정의합니다.
- Apache Commons Lang을 재정의
hashCode()
하고equals()
사용합니다. - 기억해야 할 중요한 것.
- ORM 사용 시 특별한 주의.
hashCode()
및 메소드는 Java 객체의 상위 클래스인 equals()
클래스에 정의되었습니다 . Object
따라서 모든 Java 객체는 이러한 메소드로부터 기본 구현을 상속합니다.
hashCode() 및 equals() 사용
이 방법은hashCode()
주어진 객체에 대한 고유한 정수 번호를 얻는 데 사용됩니다. 객체를 해시 테이블(버킷이라고도 함)에 데이터 구조로 저장해야 하는 경우 이 숫자를 사용하여 해당 테이블에서의 위치를 결정합니다. 기본적으로 객체에 대한 메서드는 hashCode()
객체가 저장된 메모리 위치의 번호를 반환합니다. equals()
이름에서 알 수 있듯이 이 메서드는 단순히 두 개체의 동등성을 확인하는 데 사용됩니다. 이 메서드의 기본 구현은 단순히 두 개체의 참조를 확인하여 동일한지 확인합니다.
기본 동작 재정의
클래스에서 이러한 메서드를 재정의하지 않는 한 모든 것이 잘 작동합니다. 그러나 때로는 애플리케이션이 일부 개체의 기본 동작을 변경해야 하는 경우도 있습니다. 가 있는 예를 들어보겠습니다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
에는 몇 가지 기본 속성과 접근자 메서드가 있습니다. 이제 클래스의 두 개체를 비교해야 하는 간단한 상황을 살펴보겠습니다 Employee
.
public class EqualsTest {
public static void main(String[] args) {
Employee e1 = new Employee();
Employee e2 = new Employee();
e1.setId(100);
e2.setId(100);
//Печатает false в консоли
System.out.println(e1.equals(e2));
}
}
위에 작성된 메서드가 "false"를 반환할 것이라고 추측하는 데에는 투시력이 필요하지 않습니다. 하지만 이 두 객체가 동일하다면 이것이 실제로 맞는 것일까요? 실시간 애플리케이션에서는 메서드가 true를 반환해야 합니다. equals()
올바른 동작을 달성하려면 아래와 같이 메소드를 재정의해야 합니다 .
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());
}
이 메소드를 클래스에 추가하면 Employee
동등성 확인이 "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);
//Печатает 'true'
System.out.println(e1.equals(e2));
Set employees = new HashSet();
employees.add(e1);
employees.add(e2);
//Печатает два an object
System.out.println(employees);
}
}
이 명령은 System.out.println(employee)
두 개체를 인쇄합니다. 두 개체가 동일하고 Set
고유한 개체만 포함된 경우 HashSet
내부에는 인스턴스가 하나만 있어야 합니다. 두 객체 모두 클래스의 동일한 인스턴스를 참조합니다 Employee
. 우리는 무엇을 놓쳤습니까? 우리는 두 번째 중요한 방법을 놓쳤습니다 hashCode()
. Java 문서에 따르면 method 를 재정의하면 equals()
method 를 재정의해야 합니다 hashCode()
. 그럼 우리 클래스에 다른 메서드를 추가해 보겠습니다 Employee
.
@Override
public int hashCode()
{
final int PRIME = 31;
int result = 1;
result = PRIME * result + getId();
return result;
}
이 메소드를 클래스에 한 번 추가하면 하나의 객체만 인쇄되므로 e1과 e2의 동등성을 확인하면 true로 나타납니다.
Apache Commons Lang 재정의 hashCode()
및 사용equals()
Apache Commons는 메소드 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();
}
}
반면에 코드 편집기 중 하나를 사용하면 몇 가지 멋진 구조를 불러올 수도 있습니다. 예를 들어, Eclipse IDE에서 class >> source > Geneating hashCode() and equals() ...를 마우스 오른쪽 버튼으로 클릭 하면 매우 멋진 구현이 생성됩니다. 기억해야 할 중요한 것.
hashCode()
및 및 를 모두 호출하려면 항상 동일한 객체 속성을 사용하십시오equals()
. 우리의 경우에는employee id
.- 메서드는
equals()
지속적이어야 합니다(객체가 변경되지 않은 경우 메서드는 동일한 값을 반환해야 함). - 는 언제나
a.equals(b)
와a.hashCode()
동일해야 합니다b.hashCode()
. - 한 가지 방법을 재정의하는 경우 두 번째 방법도 재정의해야 합니다.
ORM 사용 시 특별한 주의
ORM(ru.wikipedia.org/wiki/ORM)을 다루는 경우 항상 getter를 사용하고 필드 참조를 사용하지 마십시오hashCode()
. equals()
이는 ORM에서 때때로 필드가 지연 로드를 사용하여 로드되고 해당 getter가 호출될 때까지 액세스할 수 없기 때문입니다. 예를 들어, 우리 수업에서는 Employee
를 사용합니다 e1.id == e2.id
. d 필드가 지연 로딩을 사용하여 로드되는 것은 전적으로 가능합니다 i
. 필드 중 하나가 0이거나 null일 수 있으며 잘못된 동작이 발생합니다. 그러나 를 사용하면 e1.getId() == e2.getId()
지연 로딩을 사용하여 필드가 로드되었더라도 확신할 수 있습니다. getter를 호출하면 필드가 먼저 채워집니다. 이것이 hashCode()
및 메소드에 대해 내가 아는 전부입니다 equals()
. 이것이 어딘가에 누군가에게 도움이 되기를 바랍니다. 공부 잘 하시길 바랍니다!! ps. 이번이 처음으로 번역을 시도했습니다. 작가가 말하고자 하는 바에 최대한 가깝게 모든 것을 전달하려고 노력했습니다. 의견이 있으시면 댓글에 적어주세요. 엄격하게 판단하지 마세요 :-))) 원본 기사
GO TO FULL VERSION