If the self-implementing class involves intrinsic sorting, such as alphabetical sorting or numerical sorting or date sorting, it is strongly recommended to implement the Comparable
interface.
Classes that implement the Comparable
interface can work with many generic algorithms and collections. For example, if the elements in the list or array implement the Comparable
interface, you can directly call Collections.sort(list)
or Arrays.sort(array)
get the result when sorting.
general convention
JDK8
The specification of the interface is described in Document 1 as follows: compare and sort an object with the specified object, and return a negative number, zero and positive number to indicate less than, equal to and greater than the specified object, respectively. Thrown if the two compared objects are of different types .Comparable
ClassCastException
Assuming to sgn(expression)
represent a signum
function, only -1, 0, and 1 are returned. According to the returned result:
1. For any object x
and y
, sgn(x.compareTo(y)) == -sgn(y.compareTo(x))
2. For any object x
, y
and z
, if x.compareTo(y) > 0 && y.compareTo(z) > 0
, then x.compareTo(z) > 0
3. For any object x
, y
and z
, if x.compareTo(y) == 0
, then sgn(x.compareTo(z)) == sgn(y.compareTo(z))
4. Strongly recommended, but not required. Back x.compareTo(y) == 0
then .x.equals(y)
true
For rule 4, take a counter example:
public class BigDecimalDemo {
public static void main(String[] args) {
BigDecimal bigDecimal1 = new BigDecimal("4.0");
BigDecimal bigDecimal2 = new BigDecimal("4.00");
//return 0
System.out.println(bigDecimal1.compareTo(bigDecimal2));
//return false
System.out.println(bigDecimal1.equals(bigDecimal2));
}
}
interface usage
User
kind
package indi.latch.effective;
/**
* Title: User
* Description:
*
* @author lin.xu
* @date 2018/5/2
*/
public class User implements Comparable<User> {
private String name;
private int age;
private int sex;
private String phone;
public User() {
}
public User(String name, int age, int sex, String phone) {
this.name = name;
this.age = age;
this.sex = sex;
this.phone = phone;
}
//Getter & Setter
@Override
public int compareTo(User o) {
//先比较名字
int nameCompare = name.compareTo(o.getName());
if (0 != nameCompare) {
return nameCompare;
}
//后比较年龄
if (age != o.getAge()) {
return age - o.getAge();
}
return 0;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
", phone='" + phone + '\'' +
'}';
}
}
UserCompareDemo
kind
public class UserCompareDemo {
public static void main(String[] args) {
List<User> users = Lists.newArrayList(
new User("acd", 11, 0, "12345678901", null),
new User("abc", 10, 0, "12345678901", null)
);
Collections.sort(users);
System.out.println(users);
}
}
- output result
[User{name='abc', age=10, sex=0, phone='12345678901'}, User{name='acd', age=11, sex=0, phone='12345678901'}]