我的课程Contact
包含字段firstName
,lastName
和emails
。我需要使用Collection.sort(...)
对它们进行排序,但我有一个例外:
java.lang.IllegalArgumentException:比较方法违反了其一般合同!
我的compareTo
方法:
@Override
public int compareTo(Contact another) {
int compareFirstName = 0;
if (this.getFirstName() != null && another.getFirstName() != null) {
compareFirstName = this.getFirstName().compareToIgnoreCase(
another.getFirstName());
if (compareFirstName == 0) {
int compareLastName = 0;
if (this.getLastName() != null && another.getLastName() != null) {
compareLastName = this.getLastName().compareToIgnoreCase(
another.getLastName());
if (compareLastName == 0) {
int compareEmail = 0;
if (this.getEmails() != null
&& another.getEmails() != null) {
compareEmail = this.getEmails()
.compareToIgnoreCase(another.getEmails());
return compareEmail;
} else {
return 0;
}
} else {
return compareLastName;
}
} else {
int compareEmail = 0;
if (this.getEmails() != null && another.getEmails() != null) {
compareEmail = this.getEmails().compareToIgnoreCase(
another.getEmails());
return compareEmail;
} else {
return 0;
}
}
} else {
return compareFirstName;
}
} else {
int compareLastName = 0;
if (this.getLastName() != null && another.getLastName() != null) {
compareLastName = this.getLastName().compareToIgnoreCase(
another.getLastName());
if (compareLastName == 0) {
int compareEmail = 0;
if (this.getEmails() != null && another.getEmails() != null) {
compareEmail = this.getEmails().compareToIgnoreCase(
another.getEmails());
return compareEmail;
} else {
return 0;
}
} else {
return compareLastName;
}
} else {
int compareEmail = 0;
if (this.getEmails() != null && another.getEmails() != null) {
compareEmail = this.getEmails().compareToIgnoreCase(
another.getEmails());
return compareEmail;
} else {
return 0;
}
}
}
}
请帮我在compareTo方法中找到错误。感谢。
答案 0 :(得分:3)
您的实施确实违反了合同。
假设您有3个联系人:
contact1 : First Name = "John", Last Name = "Doe", Email = "x@gmail.com"
contact2 : First Name = "John", Last Name = "Doe", Email = null
contact3 : First Name = "John", Last Name = null, Email = "y@gmail.com"
根据您的逻辑:
contact1.compareTo(contact2)返回0(因为它们具有相同的名字和姓氏) contact2.compareTo(contact3)也返回0(因为你只按名字比较) 但是contact1.compareTo(contact3)不会返回0(因为他们有不同的电子邮件)。
compareTo
必须是及时的。
解决此问题的方法是不要忽略仅在您要比较的其中一个联系人中为null的属性。例如,如果this.getLastName()== null&& another.getLastName()!= null,返回1(假设您要在非空姓后命名null
个姓)。