Java Comparator 不比较每个对象

标签 java comparator

我在使用 Java Comparator 时遇到了一些问题。所以我有一个包含子节点列表的父节点。我想对这些 child 进行排序,从表面上看似乎很简单,但是当 Comparator 进行排序时,它只检查某些对象与某些对象,然后我想它会推断出对象的位置,因为如果ad之前,fd之后,b是在 d 之前,这意味着 bf 之前。

下面是我当前设置的示例。我有一个父节点 a 和 4 个子节点 belg。当我对这些 child 进行排序时,我希望顺序为 bgle,所以按字母排序并始终确保父节点排在第一位。

(请原谅画得不好)

enter image description here

很简单,我有一个 Node 类,它包含一个 ID,所以它是一个字母,然后是一个子节点列表。

public class Node {

    private char id;
    private Node parent;
    private List<Node> children = new ArrayList<>();


    public Node(char id) {
        this.id = id;
    }

    public void addChild(Node child) {
        this.children.add(child);
    }

    public List<Node> getChildren() {
        return children;
    }

    public char getId() {
        return id;
    }

    public void setParent(Node parent) {
        this.parent = parent;
    }

    public Node getParent() {
        return parent;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

    @Override
    public boolean equals(Object obj) {
        return ((Node) obj).getId() == this.id;
    }
}

然后我有 NodeComparator 类,它首先检查节点是否是您的 child ,然后如果是您先检查,反之亦然,然后按字母排序。

    @Override
    public int compare(Node o1, Node o2) {
        if (o1.getChildren().contains(o2)) {
            return -1;
        }

        if (o2.getChildren().contains(o1)) {
            return 1;
        }

        String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

        int firstNodeIndex = -10;
        int secondNodeIndex = -10;
        for (int i = 0; i < alphabet.length(); i++) {
            if (alphabet.charAt(i) == o1.getId()) {
                firstNodeIndex = i;
            }
            if (alphabet.charAt(i) == o2.getId()) {
                secondNodeIndex = i;
            }
        }
        if (firstNodeIndex > secondNodeIndex) {
            return 1;
        } else if (firstNodeIndex == secondNodeIndex) {
            return 0;
        }else {
            return -1;
        }
    }
}

问题是排序完成后会检查:

E against B
G against E
L against G

所以它从不检查 L 与 E,因此它无法知道哪个应该先出现。

最佳答案

您的订单违反了 Comparator 的契约(Contract):

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

compare('G','E') > 0 // since 'G' comes after 'E' in the alphabet

compare('E','L') > 0 // since 'E' is a child of 'L'

但是

compare('G','L') < 0 // since 'G' comes before 'L' in the alphabet

由于您的Comparator 不是有效的Comparator,它可能会产生异常或意外结果。

关于Java Comparator 不比较每个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53691564/

相关文章:

java - 如何在java中对ArrayList的ArrayList进行排序?

c++ - 具有结构键的 std::map 的高效比较器

java - Chromedriver 在 Jenkins (Linux) 上失败

Java3D 不会向我显示任何内容

SomeClass.class 的 Java 语法

java - 在 Java 中测试使用另一个比较器的比较器的最佳方法是什么?

java - Hibernate : org. hibernate.loader.MultipleBagFetchException: 无法同时获取多个包

java - 显示我的带宽连接

java - Comparator.comparing 使用嵌套对象的字段对列表进行排序

java - 我什么时候应该实现比较器?