gpt4 book ai didi

java - CompareTo 比较方法违反了其一般契约

转载 作者:行者123 更新时间:2023-12-02 01:45:34 26 4
gpt4 key购买 nike

我想通过上次联系日期比较两个“收件人”,如果相同,则通过地址进行比较。这是我的代码:

public class RecipientComparator implements Comparator<Recipient> {
@Override
public int compare(Recipient o1, Recipient o2) {
if (o1.isDateLastContactNull() || o2.isDateLastContactNull()) {
if (o1.isDateLastContactNull() && o2.isDateLastContactNull()) {
return o1.getAddress().compareTo(o2.getAddress());
} else if (o1.isDateLastContactNull()) {
return -1;
} else if (o2.isDateLastContactNull()) {
return -1;
}
} else {
if (o1.getDateLastContact().equals(o2.getDateLastContact())) {
return o1.getAddress().compareTo(o2.getAddress());
} else
return o1.getDateLastContact().compareTo(o2.getDateLastContact());
}
return 0;
}
}

我总是遇到这个错误:

Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeHi(TimSort.java:899)
at java.util.TimSort.mergeAt(TimSort.java:516)
at java.util.TimSort.mergeCollapse(TimSort.java:439)
at java.util.TimSort.sort(TimSort.java:245)
at java.util.Arrays.sort(Arrays.java:1512)
at java.util.ArrayList.sort(ArrayList.java:1462)
at managers.RecipientManager.getAllRecipientFromAPI(RecipientManager.java:28)
at com.company.Main.main(Main.java:18)

我尝试过很多事情,但现在我不知道该怎么办。你能帮我吗?

接收者类别:

package recipientPackage;

import paramPackage.Param;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Recipient {
private String recipientID;
private String address;
private String status;
private int contactCount;
private Date dateLastContact;
Param param;
private String[] attributes = {"recipientID", "address", "status", "contactCount", "dateLastContact"};

Recipient(String[] recipientBrut, boolean isComeFromMailing) {
if (isComeFromMailing) {
createRecipientMailing(recipientBrut);
} else {
createRecipientSurvey(recipientBrut);
}
}

public void createRecipientMailing(String[] recipientBrut) {
this.setRecipientID(recipientBrut[0].substring(recipientBrut[0].indexOf(':') + 1).replaceAll("\"", ""));
this.setAddress(recipientBrut[1].substring(recipientBrut[1].indexOf(':') + 1).replaceAll("\"", ""));
this.setStatus(recipientBrut[3].substring(recipientBrut[3].indexOf(':') + 1).replaceAll("\"", ""));

try {
this.setDateLastContactForMailing(recipientBrut[5].substring(recipientBrut[5].indexOf(':') + 1).replaceAll("\"", ""));
this.setContactCount(Integer.parseInt(recipientBrut[4].substring(recipientBrut[4].indexOf(':') + 1).replaceAll("\"", "")));
} catch (IndexOutOfBoundsException e) {
this.setDateLastContactForMailing(null);
}catch (NumberFormatException e){
e.printStackTrace();
}
}

public void createRecipientSurvey(String[] recipientBrut) {
setAddress(recipientBrut[0]);
setStatus(recipientBrut[1]);
setDateLastContactForSurvey(recipientBrut[2]);
param.setParam_point_collecte(recipientBrut[5]);
param.setParam_langue(recipientBrut[6]);
param.setParam_semaine(recipientBrut[7]);
param.setParam_periode(recipientBrut[8]);
param.setParam_envoi(recipientBrut[9]);
param.setParam_type_visiteur(recipientBrut[10]);
param.setParam_saison(recipientBrut[11]);
}

private void setDateLastContactForMailing(String dateLastContact) {
if (dateLastContact != null) {
SimpleDateFormat formatter = new SimpleDateFormat("yyy-MM-dd'T'HH:mm:ss");
try {
this.dateLastContact = formatter.parse(dateLastContact);
} catch (ParseException e) {
e.printStackTrace();
}
} else
this.dateLastContact = null;

}

private void setDateLastContactForSurvey(String dateLastContact) {
if (!dateLastContact.equals("")) {
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
try {
this.dateLastContact = formatter.parse(dateLastContact);
} catch (ParseException ignored) {
}
} else
this.dateLastContact = null;

}
public Boolean isDateLastContactNull() {
return (dateLastContact == null);
}

public String getRecipientID() {
return recipientID;
}

public void setRecipientID(String recipientID) {
this.recipientID = recipientID;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

public String getStatus() {
return status;
}

public void setStatus(String status) {
this.status = status;
}

public int getContactCount() {
return contactCount;
}

public void setContactCount(int contactCount) {
this.contactCount = contactCount;
}

public Date getDateLastContact() {
return dateLastContact;
}

public void setDateLastContact(Date dateLastContact) {
this.dateLastContact = dateLastContact;
}

public String[] getAttributes() {
return attributes;
}

public void setAttributes(String[] attributes) {
this.attributes = attributes;
}
}

最佳答案

您违反了比较方法的约定,您的关系不具有传递性。 “实现者必须确保 sgn(compare(x, y)) == -sgn(compare(y, x)) 对于所有 xy

考虑一下:

public static void main(String[] args){
Recipient r1; // with isDateLastContactNull() == true;
Recipient r2; // with isDateLastContactNull() == false;
RecipientComparator rc = new RecipientComparator();

System.out.println(rc.compare(r1, r2)); // -1
System.out.println(rc.compare(r2, r1)); // -1
// both print -1 which is not transitive.
}

原因是因为这段代码:

if (o1.isDateLastContactNull() && o2.isDateLastContactNull()) {
// if both null, return comparison of addresses
return o1.getAddress().compareTo(o2.getAddress());
} else if (o1.isDateLastContactNull()) {
// if first null, return -1
return -1;
} else if (o2.isDateLastContactNull()) {
// if second null, also return -1 ?
return -1; // should probably be 1 instead
}

您可能应该返回1对于第二个条件。

<小时/>

契约(Contract)定义如下:

<强> int compare(T o1, T o2):

Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second. In the foregoing description, the notation sgn(expression) designates the mathematical signum function, which is defined to return one of -1, 0, or 1 according to whether the value of expression is negative, zero or positive.

The implementor must ensure that sgn(compare(x, y)) == -sgn(compare(y, x)) for all x and y. (This implies that compare(x, y) must throw an exception if and only if compare(y, x) throws an exception.)

The implementor must also ensure that the relation is transitive: ((compare(x, y) > 0) && (compare(y, z) > 0)) implies compare(x, z) > 0.

Finally, the implementor must ensure that compare(x, y) == 0 implies that sgn(compare(x, z)) == sgn(compare(y, z)) for all z.

It is generally the case, but not strictly required that (compare(x, y) == 0) == (x.equals(y)). Generally speaking, any comparator that violates this condition should clearly indicate this fact. The recommended language is "Note: this comparator imposes orderings that are inconsistent with equals."

关于java - CompareTo 比较方法违反了其一般契约,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53727573/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com