在Java

时间:2018-12-12 10:29:39

标签: java

class Employee implements Comparable<Employee> {
    int id;
    String name;
    int age;

    Employee(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int compareTo(Employee employee) {
        /*if (age == employee.age)
            return 0;
        else if (age > employee.age)
            return 1;
        else
            return -1;*/
        return -1;
    }
}



public class TestSorting {
    public static void main(String args[]) {
        ArrayList<Employee> al = new ArrayList<Employee>();
        al.add(new Employee(101, "Peter", 23));
        al.add(new Employee(106, "Marry", 29));
        al.add(new Employee(105, "John", 21));
        //Before sorting
        for (Employee st : al) {
            System.out.println(st.id + " " + st.name + " " + st.age);
        }
        System.out.println("================");
        //After sorting
        Collections.sort(al);
        for (Employee st : al) {
            System.out.println(st.id + " " + st.name + " " + st.age);
        }
    }
}

我第一次覆盖方法compareTo

if (age == employee.age)
    return 0;
else if (age > employee.age)
    return 1;
else
    return -1;

结果是:

101 Peter 23
106 Marry 29
105 John 21
================
105 John 21
101 Peter 23
106 Marry 29

我第二次覆盖此方法,除了return -1外,什么都没有。我希望排序后的结果应与原始结果相同,但是反之则如此。当我在return 1方法中conpareTo时,结果与原始结果相同,这与我的预期不同。如果我在return -1方法中compareTo,那就是结果:

101 Peter 23
106 Marry 29
105 John 21
================
105 John 21
106 Marry 29
101 Peter 23

新更新:

让我思考return -1时什么也不应该发生的原因是。根据排序算法,在对数组进行排序时,我们可以这样做: 我们可以使用以下算法:

public class Test {
    public static void main(String[] args) {
        int[] arr = { 6, 9, 3, 5, 7, 1, 8 };
        System.out.println(Arrays.toString(arr));
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = i; j < arr.length; j++) {
                if (arr[i] > arr[j]) {
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
        System.out.println(Arrays.toString(arr));

    }
}

我认为Comparable的算法看起来像是这种算法。因此,当方法中的return -1时,this age总是小于that age;因此没有交换(就像arr[i] > arr[j]总是false,也没有交换)。并且当return 1时,意味着this age总是大于that age,因此存在交换(就像arr[i] > arr[j]总是true,并且存在交换),与原始序列相比,结果是具有相反顺序的数组。 如果我们将代码更改为:

for (int i = 0; i < arr.length - 1; i++) {
        for (int j = i; j < arr.length; j++) {
            if (true) {
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
    }

我们得到结果:

[6, 9, 3, 5, 7, 1, 8]
[8, 1, 7, 5, 3, 9, 6]

这就是为什么我认为方法return 1中的compareTo。我们应该将原始列表按倒序排列到列表中。但事实并非如此。当return -1

时我们才得到结果

2 个答案:

答案 0 :(得分:6)

  

我第二次重写此方法时,除了体内什么都没有   return -1 ...

这样做会违反Comparable的合同,即defined in the documentation。您是说一切都少于一切,这不可能是真的。

A < BB < A是一个悖论。

因此,期望顺序不变是错误的期望。当您违反Comparable的合同时,排序行为是不确定的。没有比其他任何结果都正确或正确的结果。

答案 1 :(得分:2)

@Michael的答案是正确的,让我加一个旁注。

Comparable<T>用于“自然秩序”;我不确定年龄是您排序人选的最相关顺序。

您可能想要的是

class Employee {
    int id;
    String name;
    int age;

    static public final Comparator<Employee> AGE_COMPARATOR =
        Comparator.comparing(Employee::getAge);

    static public final Comparator<Employee> NAME_COMPARATOR =
        Comparator.comparing(Employee::getName);

    static public final Comparator<Employee> SALARY_COMPARATOR =
        Comparator.comparing(Employee::getSalary);
}

现在您可以按Employee的任何属性对其进行排序,例如

Collections.sort(employeeList, Employee.AGE_COMPARATOR);