public class Company implements Comparable<Company> { private final String id; private final String officialName; public Company(final String id, final String officialName) { this.id = id; this.officialName = officialName; } public String getId() { return id; } public String getOfficialName() { return officialName; } @Override public int hashCode() { HashCodeBuilder builder = new HashCodeBuilder(17, 29); builder.append(this.getId()); builder.append(this.getOfficialName()); return builder.toHashCode(); } @Override public boolean equals(final Object obj) { if (obj == this) { return true; } if (!(obj instanceof Company)) { return false; } Company other = (Company) obj; EqualsBuilder builder = new EqualsBuilder(); builder.append(this.getId(), other.getId()); builder.append(this.getOfficialName(), other.getOfficialName()); return builder.isEquals(); } @Override public int compareTo(final Company obj) { CompareToBuilder builder = new CompareToBuilder(); builder.append(this.getOfficialName(), obj.getOfficialName()); builder.append(this.getId(), obj.getId()); return builder.toComparison(); } }
public class CompanyDetails extends Company { private final String marketingName; private final Double marketValue; public CompanyDetails(final String id, final String officialName, final String marketingName, final Double marketValue) { super(id, officialName); this.marketingName = marketingName; this.marketValue = marketValue; } public String getMarketingName() { return marketingName; } public Double getMarketValue() { return marketValue; } @Override public int hashCode() { HashCodeBuilder builder = new HashCodeBuilder(19, 31); builder.appendSuper(super.hashCode()); builder.append(this.getMarketingName()); return builder.toHashCode(); } @Override public boolean equals(final Object obj) { if (obj == this) { return true; } if (!(obj instanceof CompanyDetails)) { return false; } CompanyDetails other = (CompanyDetails) obj; EqualsBuilder builder = new EqualsBuilder(); builder.appendSuper(super.equals(obj)); builder.append(this.getMarketingName(), other.getMarketingName()); builder.append(this.getMarketValue(), other.getMarketValue()); return builder.isEquals(); } }
CompanyDetails c1 = new CompanyDetails("231412", "McDonalds Ltd", "McDonalds food factory", 120000.00); CompanyDetails c2 = new CompanyDetails("231412", "McDonalds Ltd", "McDonalds restaurants", 60000.00); Set<CompanyDetails> set1 = CompaniesFactory.createCompanies1(); set1.add(c1); set1.add(c2); Set<CompanyDetails> set2 = CompaniesFactory.createCompanies2(); set2.add(c1); set2.add(c2); Assert.assertEquals(set1.size(), set2.size());
这篇文章提到的问题很是广泛,可是常常被忽视。Comparable接口的问题实际是因为很差的约定和对使用的接口需求的错误理解形成的。做为一个Java开发人员或架构师,你应该特别注意这样的事情,并遵照良好的编码习惯和作法。 越大的项目,这种问题就越显得重要。这里我总结了一个使用Comparable接口的最佳实践,能够避免这个错误。html
Java的Comparable接口的设计和使用的最佳实践:java