Java错误:“比较方法违反了其总合同!”

我有这个代码:

package org.optimization.geneticAlgorithm; import org.optimization.geneticAlgorithm.selection.Pair; public abstract class Chromosome implements Comparable { public abstract double fitness(); public abstract Pair crossover(Chromosome parent); public abstract void mutation(); public int compareTo(Chromosome o) { int rv = 0; if (this.fitness() > o.fitness()) { rv = -1; } else if (this.fitness() < o.fitness()) { rv = 1; } return rv; } } 

每次我运行此代码时,我都会收到此错误:

 Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract! at java.util.ComparableTimSort.mergeHi(ComparableTimSort.java:835) at java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:453) at java.util.ComparableTimSort.mergeCollapse(ComparableTimSort.java:376) at java.util.ComparableTimSort.sort(ComparableTimSort.java:182) at java.util.ComparableTimSort.sort(ComparableTimSort.java:146) at java.util.Arrays.sort(Arrays.java:472) at java.util.Collections.sort(Collections.java:155) at org.optimization.geneticAlgorithm.GeneticAlgorithm.nextGeneration(GeneticAlgorithm.java:74) at org.optimization.geneticAlgorithm.GeneticAlgorithm.execute(GeneticAlgorithm.java:40) at test.newData.InferenceModel.main(InferenceModel.java:134) 

我使用OpenJDK7u3,当对象相等时我返回0。 有人可以向我解释这个错误吗?

如果您有任何NaN值,您可能会遇到这种情况:

例如:

 public class Test { public static void main(String[] args) { double a = Double.NaN; double b = Double.NaN; double c = 5; System.out.println(a < b); System.out.println(a > b); System.out.println(b < c); System.out.println(c < b); } } 

所有这些打印都是false 。 所以你最终可能会遇到两个非NaN值都被认为与NaN“相等”的情况,但是一个比另一个更大。 基本上,您应该弄清楚如何处理NaN值。 还要检查那确实是问题,当然......你真的想要NaN值来适应你的身体吗?

很可能你的健身function有两种方式:

  1. 在同一对象上调用时,它并不总是返回相同的值。
  2. 它可以返回NaNs。 如Jon Skeet所述,您的compareTo()在存在NaN时不可传递。

您可以使用Double.compare()重写比较函数:

 public int compareTo(Chromosome o) { return Double.compare(o.fitness(), this.fitness()); } 

这需要更少的代码并处理极端情况(NaN,负零等)。 当然,这些角落案件是否应该首先出现,由您来决定和解决。

您应该尝试添加if (this == o) return 0; 因为必须返回相同的对象。