关于Comparable接口compareTo()及Employee对象排序的技术问询
Provided Code
Employee Class
public class Employee implements Comparable<Employee> { private String name; private Integer id; @Override public String toString() { return "Employee [name=" + name + ", id=" + id + "]"; } public Employee(Integer id, String name) { this.name = name; this.id = id; } public String getName() { return name; } public Integer id() { return id; } public void setName(String name) { this.name = name; } public void setID(Integer id) { this.id = id; } @Override public int compareTo(Employee o) { System.out.println("The difference of this id and other id is..** " + id + " other id**" + o.id); System.out.println(this.id); System.out.println(o.id); return this.id - o.id; } }
Test Code
import java.util.List; import java.util.ArrayList; import java.util.Collections; public class ComparableDemo { public static void main(String args[]) { Employee e1 = new Employee(1, "lalit"); Employee e2 = new Employee(6, "rmit"); Employee e3 = new Employee(3, "zanjan"); Employee e4 = new Employee(11, "harjot"); List<Employee> empList = new ArrayList<Employee>(); empList.add(e1); empList.add(e2); empList.add(e3); empList.add(e4); Collections.sort(empList); System.out.println(empList); } }
Output
The difference of this id and other id is..** 6 other id**1 The difference of this id and other id is..** 3 other id**6 The difference of this id and other id is..** 3 other id**6 The difference of this id and other id is..** 3 other id**1 The difference of this id and other id is..** 11 other id**3 The difference of this id and other id is..** 11 other id**6 [Employee [name=lalit, id=1], Employee [name=zanjan, id=3], Employee [name=rmit, id=6], Employee [name=harjot, id=11]]
Question 1: Why is the first comparison between 6 and 1? How is 6 assigned to this.id?
Java's Collections.sort() uses the TimSort algorithm (since Java 7), a hybrid approach combining merge sort and insertion sort. Here's the breakdown:
- Your initial list is
[e1(id=1), e2(id=6), e3(id=3), e4(id=11)]. - TimSort starts by scanning the list to build initial "runs" (contiguous sorted sequences). To check if the first two elements are sorted, it calls
e2.compareTo(e1). - In this call,
e2is the object invoking the method, sothis.idis 6 (set viae2's constructor), ande1is the parametero, soo.idis 1. That's why you see the first output line comparing 6 and 1.
Question 2: Why are the second and third lines repeating the comparison between 3 and 6?
This ties into how TimSort inserts elements into existing sorted runs:
- After the first sorted run (
[e1, e2]), we need to inserte3(id=3)into this sequence. - First, TimSort compares
e3withe2(callinge3.compareTo(e2)), which generates the second output line. Since 3 < 6, the algorithm knows it needs to movee3forward. - The duplicate comparison comes from TimSort's internal implementation: when shifting elements (like moving
e2to make space fore3), the algorithm may re-trigger the same comparison to confirm the correct position. This is normal behavior for ensuring accurate insertion.
Question 3: What's the actual working principle of the compareTo() method?
The Comparable interface defines an object's natural ordering, and compareTo() is its core method:
- When you call
a.compareTo(b), it returns an integer that tells the sorting algorithm how to orderarelative tob:- A negative value:
ashould come beforeb - 0:
aandbhave the same sorting position - A positive value:
ashould come afterb
- A negative value:
- Sorting algorithms like TimSort repeatedly call
compareTo()to adjust element positions until the entire list follows the natural ordering defined by the method.
Question 4: How does the subtraction this.id - o.id enable sorting via Comparable?
This subtraction leverages integer arithmetic to directly map to the compareTo() return rules:
- If
this.id > o.id: The result is a positive number, telling the algorithmthisshould come aftero(ascending order) - If
this.id < o.id: The result is a negative number, telling the algorithmthisshould come beforeo - If
this.id == o.id: The result is 0, meaning the two objects are equal in terms of sorting - The sorting algorithm uses these return values to rearrange elements until the list is sorted in ascending order of
id.
Question 5: What values does this.id take, and how are they assigned?
During the sorting process, this.id takes the values 6, 3, and 11:
- 6 comes from
e2, assigned via its constructornew Employee(6, "rmit") - 3 comes from
e3, assigned vianew Employee(3, "zanjan") - 11 comes from
e4, assigned vianew Employee(11, "harjot")
You don't see this.id = 1 in the output because e1(id=1) is never the invoking object in a compareTo() call—it's always passed as the parameter o when other elements are compared against it. All id values are set once in the constructor, and only modified if you call the setID() method (which isn't done here).
内容的提问来源于stack exchange,提问作者Shivani Gupta

