java.lang.IllegalArgumentException: 比较方法违反了它的一般契约!如何处理可能的空对象?

java.lang.IllegalArgumentException: Comparison method violates its general contract! How to handle possible null objects?

private Comparator<Entity> spriteSorter = new Comparator<Entity>() {
    public int compare(Entity e0, Entity e1) {
        if (e0 == null || e1 == null) return -1; //was 0
        if (e1.getY() < e0.getY()) return +1;
        if (e1.getY() > e0.getY()) return -1;
        return -1; //was 0
    }
};

看了很多关于这个的文章,还是不知道怎么解决这个小问题:

这是有效的核心:

if (e1.getY() < e0.getY()) return +1;
if (e1.getY() > e0.getY()) return -1;

但有时(我必须处理许多在一秒钟内经常从并发数组列表中添加和删除的实体)其中一个实体为空。因此我必须在这个比较器中检查它。 但是后来我违反了这个总契约,一旦两个对象之一为null。

知道如何解决这个问题吗?请帮忙! :)

如果使用 c.compare(null, null) 调用您的比较器,将比较 null < null,即使它们相等。此外,它打破了逆规则,即 sgn(compare(a, b)) == -sgn(compare(b, a)),即向后比较两个事物 returns 与向前比较相反。您可以简单地通过将 null 视为 "negative infinity," 来解决所有这些问题,这对所有非空 anull == null.

强制执行 null < a
public int compare(Entity l, Entity r) {
    if (Objects.equals(l, r)) return 0; // Handles normal and null equality
    else if(l == null) return -1; // Enforce null < a ∀ nonnull a
    else if(r == null) return +1; // Enforce a > null ∀ nonnull a
    else return Integer.compare(l.getY(), r.getY()); // Base comparison
}