2つの異なるデータベースエンティティを表す2つのクラスがあります。彼らの関係は1:このようなデシベル、それは、クラス構造体で表現された何かでM:Javaの相互参照クラスでequals/hashCodeをオーバーライドすると、StackOverflowErrorが発生します。
public class Company {
private List<Employee> employees;
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
}
public class Employee {
private Company company;
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
}
は今、私はこれらのクラスの等号/のhashCodeをオーバーライドしたいです。私は次のテストを実行した場合
public class Company {
private List<Employee> employees;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((employees == null) ? 0 : employees.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;
Company other = (Company) obj;
if (employees == null) {
if (other.employees != null)
return false;
} else if (!employees.equals(other.employees))
return false;
return true;
}
}
public class Employee {
private Company company;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((company == null) ? 0 : company.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;
Employee other = (Employee) obj;
if (company == null) {
if (other.company != null)
return false;
} else if (!company.equals(other.company))
return false;
return true;
}
}
:Eclipseは私のために以下のコードを生成します
public class EqualsTest {
@Test
public void testEquals() {
Company company1 = new Company();
Employee employee1 = new Employee();
employee1.setCompany(company1);
company1.setEmployees(Arrays.asList(employee1));
Company company2 = new Company();
Employee employee2 = new Employee();
employee2.setCompany(company2);
company2.setEmployees(Arrays.asList(employee2));
assertThat(company1, is(company2));
}
}
を私はCompany1のとCompany2の両方が、従業員の同等のリストを持っているので、それを渡すことを期待しますが、それはStackOverflowErrorがで失敗します:
java.lang.StackOverflowError
at java.util.AbstractList$Itr.<init>(AbstractList.java:318)
at java.util.AbstractList$Itr.<init>(AbstractList.java:318)
at java.util.AbstractList$ListItr.<init>(AbstractList.java:377)
at java.util.AbstractList.listIterator(AbstractList.java:315)
at java.util.AbstractList.listIterator(AbstractList.java:284)
at java.util.AbstractList.equals(AbstractList.java:502)
at com.test.Company.equals(Company.java:37)
at com.test.Employee.equals(Employee.java:35)
at java.util.AbstractList.equals(AbstractList.java:507)
at com.test.Company.equals(Company.java:37)
at com.test.Employee.equals(Employee.java:35)
at java.util.AbstractList.equals(AbstractList.java:507)
at com.test.Company.equals(Company.java:37)
at com.test.Employee.equals(Employee.java:35)
...
私は、この失敗の理由はクラス内の相互参照であり、したがって/ hashCodeメソッドと等しいことを理解しています。しかし、無限再帰を避けるためにequals/hashCodeをどのように実装するべきですか?
ありがとう、MДΓΓБДLL。これらのクラスには他のフィールド(社名、従業員名などのsimle文字列)があり、equals/hashCodeメソッドに含まれています。問題の原因となっているものをクロスリファレンスと呼びます。 – parxier
その場合、Company#hashCode()およびCompany#equals()メソッドから会社の従業員を省略する必要があるようです。従業員は会社の定義することができますが、従業員によって定義される会社はありません。 –
名前が同じだが従業員の異なる2つの企業が同等になるというschteverの答えにコメントしたので、それは正しくありません。 – parxier