Collections.sort()不适用于所有成员

时间:2014-12-29 23:42:52

标签: java sorting java-7

我正在尝试使用Collections.sort()对列表进行排序,并注意到正在对所有成员进行排序:

这是我的输入,打印出.compareTo()内部和输出:

5 4 3 2 1     // Original
me = 4: o = 5 // A printout at each entry into .compareTo()
me = 3: o = 4
me = 3: o = 5
me = 2: o = 5
me = 2: o = 3
me = 1: o = 3
me = 1: o = 2
4 5 3 2 1     // Final output (1 should be at the beginning though)

我的排序规则是:

1<4
3<2
4<5

我的实施是:

        List<Task> tasks = new TaskList();
        Task.create(tasks); // creates a list 5 4 3 2 1 
        while (scan.hasNext()) {
            String line = scan.next();
            Task.rules.add(line); // address the rules such as "1<4"
        }
        System.out.println(tasks);
        Collections.sort(tasks);

compareTo()实现:

    @Override
    public int compareTo(Object arg0) {
        int me = id;
        int o = ((Task) arg0).id;
        System.out.println("me = " + me + ": o = " + o);
        for (String s : rules) { // rules is an array of strings "1<4" etc
            int left = Integer.valueOf(s.substring(0, 1));
            int right = Integer.valueOf(s.substring(2));
            char op = s.charAt(1);

            boolean meLeft = left == me;
            boolean oLeft = left == o;
            boolean meRight = right == me;
            boolean oRight = right == o;

            if (meLeft && oRight) {
                if (op == '<') { // me < other
                    return -1;
                } else
                    return 1;
            } else if (oLeft && meRight) {
                if (op == '<') {// other < me
                    return 1;
                } else {
                    return -1;
                }
            }
        }
        return 0;
    }

正如您从&#34; me = M,o = O&#34;在顶部,Collections.sort()没有遍历列表的所有成员!

我希望每位会员能够展示以下内容&#34; me&#34;所有其他成员&#34; o&#34;为了进行比较,我希望这个问题顶部的列表要长得多!我相信它的大小应该是N ^ 2 ......

1 个答案:

答案 0 :(得分:2)

您的compareTo方法会以两种方式破坏该方法的合约。

1)及物性表示如果x.compareTo(y) > 0y.compareTo(z) > 0x.compareTo(z) > 0。您的方法会因为5 > 44 > 1而导致此问题中断,但5>1不是您的规则之一。

2)compareTo还必须符合x.compareTo(y) == 0然后sgn(x.compareTo(z)) == sgn(y.compareTo(z))所有z的条件。您的方法会因为5.compareTo(1) == 0而导致此错误,而5.compareTo(4)1.compareTo(4)的符号相反。

如果您未达到compareTo的合同,sort的结果将无法预测。但是在你的情况下,我们可以看到发生了什么。因为4 < 5 = 3 < 2 = 1,所以按顺序排列4,5,3,2,1 。 (我使用=表示compareTo方法返回0)。该链中没有>个符号,因此没有理由继续排序。

如果您希望1来到前面,除了使compareTo方法符合上述两个条件之外,您还必须添加至少一个涉及[1,4,5]和[1,4,5]的内容的规则来自[2,3]的东西。只要没有这样的规则,最终1没有理由超过2和3。