首页 > 解决方案 > Java Comparator 不比较每个对象

问题描述

我对 Java 有一些复杂的情况Comparator。所以我有一个父节点,它有一个子节点列表。我想对这些孩子进行排序,从表面上看似乎很简单,但是当Comparator排序时它只检查某些对象与某些对象,然后我想它推断对象的位置,比如 if ais before dfis after d, bis befored哪个意思b是 before f

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

(请原谅劣质图)

在此处输入图像描述

很简单,我有一个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类,它首先检查节点是否是你的孩子,然后如果他们是你先去,反之亦然,然后按字母顺序排列。

    @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,所以它无法知道应该先出现。

标签: javacomparator

解决方案


您的订购违反了Comparator的合同:

实现者还必须确保关系是可传递的: ((compare(x, y)>0) && (compare(y, z)>0)) 意味着 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

由于 yourComparator不是 valid Comparator,因此可能会产生异常或意外结果。


推荐阅读