gpt4 book ai didi

java比较方法违反了它的一般契约

转载 作者:行者123 更新时间:2023-12-01 21:14:56 25 4
gpt4 key购买 nike

使用自定义比较器进行Collection.sort时,我收到java.lang.IllegalArgumentException:比较方法违反了其一般契约

我知道这是一个问题,因为该方法不可传递。在我的比较器中,调用了多个方法,并且我确定了违反此规则的代码段。但是我无法修复它,也无法看到它的问题。

private int compareInstancesBelowChangeNumberStructureElements(ISapInstance pInstance1,
ISapInstance pInstance2) {
// Sort algorithm below change number structure elements
String[] tokens1 = pInstance1.getName().asString().split(COMPOUND_NAME_DELIMITER_REGEX);
String[] tokens2 = pInstance2.getName().asString().split(COMPOUND_NAME_DELIMITER_REGEX);

if ((tokens1 == null) || (tokens2 == null)) {
return 0;
}

int minLength = tokens1.length;
if (tokens2.length < minLength) {
minLength = tokens2.length;
}

if (minLength < 3) {
return 0;
}

// Compare criterion 1: node name or assembly group name
int compareValue = tokens1[2].compareTo(tokens2[2]);
if ((compareValue == 0) && (minLength >= 4)) {
// Compare criterion 2: class name
compareValue = tokens1[3].compareTo(tokens2[3]);
if (compareValue == 0) {
// Compare criterion 3: pos var name or assembly position name
compareValue = tokens1[1].compareTo(tokens2[1]);
if (compareValue == 0) {
// Compare criterion 4: instance name
compareValue = tokens1[0].compareTo(tokens2[0]);
}
}
}
return compareValue;
}

最佳答案

如果 ISapInstance.getName() 的标记少于三个,则您的比较方法违反了传递性要求。

假设您有三个 ISapInstance 实例:

  • a - 名称包含三个标记元素
  • b - 名称包含两个标记元素
  • c - 名称包含三个 token 元素,其 token[2] 值与 a 的值不同

现在,如果您使用 ab 或使用 bc 调用比较方法,则比较方法对于两次调用都返回 0

为了满足传递性规则,如果使用 ac 调用比较方法,则还必须返回 0。但是,由于两者的名称都包含两个以上的标记,并且 token[2] 的值不同,如果按照描述的方式准备,它将返回与 0 不同的内容。

<小时/>

这三个实例也出现同样的问题:

(所有实例都具有相同的 token[2] 值)

  • a - 名称包含四个标记元素
  • b - 名称包含三个标记元素
  • c - 名称包含四个 token 元素,其 token[3] 值与 a 的值不同
<小时/>

要解决此问题,如果只有一个实例的 token 少于三个,或者第三个 token 相同且只有一个实例恰好有三个 token ,则比较器不得返回 0

例如:

private int compareInstancesBelowChangeNumberStructureElements(ISapInstance pInstance1,
ISapInstance pInstance2) {
// Sort algorithm below change number structure elements
String[] tokens1 = pInstance1.getName().asString().split(COMPOUND_NAME_DELIMITER_REGEX);
String[] tokens2 = pInstance2.getName().asString().split(COMPOUND_NAME_DELIMITER_REGEX);

if (tokens1.length < 3) {
return (tokens2.length < 3) ? 0 : -1;
} else if (tokens2.length < 3) {
return 1;
}
int minLength = tokens1.length;
if (tokens2.length < minLength) {
minLength = tokens2.length;
}

// Compare criterion 1: node name or assembly group name
int compareValue = tokens1[2].compareTo(tokens2[2]);
if (compareValue == 0) {
if (tokens1.length < 4) {
return (token2.length < 4) ? -1 : 0;
} else if (tokens2.length < 4) {
return 1;
} else {
// ... the remaining comparison operations
}
}
return compareValue;
}

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

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