1. The sequence
Comparable interface
public interface Comparable<T> {
public int compareTo(T o);
}
Copy the code
Now for a brief explanation of the comparaTo() method.
The comparaTo() method, which passes in another instance of the class and returns an int, is invoked each time to compare the incoming object with the Bunsen object. Swap the positions of the two instances in an array or collection if the int returned by == is a positive value (excluding zero), otherwise the positions remain the same.
The CompareTo method returns three results, 1,0, and -1, so what do they mean?
The first thing we need to know is that we are comparing this object (the current object) with the object being compared.
- Where 0 means that the two are equal
- -1 indicates that the current object is ranked before the object being compared
- 1 indicates that the current object is ranked after the object being compared
2. Why should we consider implementing the Comparable interface
Classes that implement the Comparable interface work well with collections or generic algorithms, and you can achieve great functionality for a fraction of the price.
A class that can easily be sorted in an array or collection if it implements the Comparable interface. The Comparable interface is used to implement object ordering. Suppose we have a class like this:
public class CompObj implements Comparable<CompObj> { private int age; private String name; public CompObj(int age, String name) { this.age = age; this.name = name; } public int getAge() { return age; } public String getName() { return name; } @override public int compareTo(@nonnull CompObj another) {return this.age - another. Age; }}Copy the code
Then we can sort them like this:
List<CompObj> list = ... ; // Initialize a list collections.sort (list); CompObj array[] =... ; // Initialize an array.sort (list); // Array sort, that's itCopy the code
General convention of the 3.compareTo method
- Implementers must ensure that all x and y satisfy SGN (x.compareTo(y)) == -sgn(y.compareTo(x))
- The implementer must ensure that the comparison is transitive
- The implementer must ensure that x.compareTo(y) == 0 implies that all z satisfy SGN (x.compareTo(z)) == SGN (y.compareTo(z))
- It is strongly recommended (x.compareTo(y) == 0) == (x.equals(y)), but not necessary
4. When should you consider implementing the Comparable interface
(1) The class you are writing is a value class. (2) There are obvious internal sorting relationships in the class, such as alphabetical sorting, numerical ordering or time, etc. (3) The former two are and relation.
5. How to implement the Comparable interface
We define a Person object and ask the Person to be sorted by age.
public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; }}Copy the code
We are not allowed to sort these objects directly, we must implement their Comparable interface:
public class Person implements Comparable<Person>{ private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public int compareTo(Person o) { if (this.age > o.age) return 1; else if (this.age < o.age) return -1; else return 0; } @Override public String toString() { return "name: " + name + " age: " + age; } public static void main(String[] args){ List<Person> list = new ArrayList<>(); list.add(new Person("John",18)); list.add(new Person("Marry",21)); list.add(new Person("Tom",20)); System.out.println("Before sort:"); printList(list); Collections.sort(list); System.out.println("After sort:"); printList(list); } public static void printList(List<Person> list){ for (Person p : list){ System.out.print(p + " / "); } System.out.println(); }} Before sort: name: John age: 18 / name: Marry age: 21 / name: Tom age: 20 / After sort: name: John age: 18 / name: Tom age: 20 / name: Marry age: 21 /Copy the code
For testing purposes, we override the toString method, and then call the collections.sort () method to sort the list. Now let’s focus on implementing the CompareTo method in the Comparable interface:
@Override
public int compareTo(Person o) {
if (this.age > o.age)
return 1;
else if (this.age < o.age)
return -1;
else return 0;
}
Copy the code
Age <o.age, returns -1, indicating that this comes before o. So the smaller number goes first. So what if we want to change it to descending order?
@Override
public int compareTo(Person o) {
if (this.age < o.age)
return 1;
else if (this.age > o.age)
return -1;
else return 0;
}
Copy the code
In fact, just change the comparison number.
For the Person class above, I might have the same age. If I wanted to continue sorting, I would sort name assuming the same age. So how does this work?
public class Person implements Comparable<Person>{ private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public int compareTo(Person o) { if (age > o.age) return 1; if (age < o.age) return -1; return name.compareTo(o.name); } @Override public String toString() { return "name: " + name + " age: " + age; } public static void main(String[] args){ List<Person> list = new ArrayList<>(); list.add(new Person("John",18)); list.add(new Person("Marry",21)); list.add(new Person("Tom",20)); list.add(new Person("Mark",20)); list.add(new Person("Ruby",20)); System.out.println("Before sort:"); printList(list); Collections.sort(list); System.out.println("After sort:"); printList(list); } public static void printList(List<Person> list){ for (Person p : list){ System.out.print(p + " / "); } System.out.println(); }} Before sort: name: John age: 18 / name: Marry age: 21 / name: Tom age: 20 / name: Mark age: 20 / name: Ruby age: 20 / After sort: name: John age: 18 / name: Mark age: 20 / name: Ruby age: 20 / name: Tom age: 20 / name: Marry age: 21 /Copy the code
We can see that Mark, Ruby and Tom sort by the letters in their names when age is the same. To achieve the effect we need, let’s look at how to achieve it in detail:
@Override public int compareTo(Person o) { if (age > o.age) return 1; if (age < o.age) return -1; // If the ages are equal, sort by name. return name.compareTo(o.name); }Copy the code
In effect, the name compare method is called when the ages are equal. Why is it possible to call compare directly here? Because strings are already set up for internal ordering in the system. This rimmer thinks ascending order, but what if you need to set descending order?
return -name.compareTo(o.name);
Copy the code
Change to its negative number. Upgrade again, if you add an ID attribute to the Person class, and ask that the Person class be first ordered by ID, then by age if the ID is the same, and then by name if the ID and age are the same.
public class Person implements Comparable<Person>{ private int id; private String name; private int age; public Person(int id,String name, int age) { this.id = id; this.name = name; this.age = age; } @Override public int compareTo(Person o) { if (id > o.id) return 1; if (id < o.id) return -1; If (age > o.age) return -1; if (age > o.age) return -1; if (age < o.age) return 1; // If id and age are equal, sort by name. return name.compareTo(o.name); } @Override public String toString() { return "id: " + id + " name: " + name + " age: " + age; } public static void main(String[] args){ List<Person> list = new ArrayList<>(); list.add(new Person(3,"John",18)); list.add(new Person(2,"Marry",21)); list.add(new Person(2,"Tom",20)); list.add(new Person(4,"Mark",20)); list.add(new Person(4,"Ruby",20)); System.out.println("Before sort:"); printList(list); Collections.sort(list); System.out.println("After sort:"); printList(list); } public static void printList(List<Person> list){ for (Person p : list){ System.out.print(p + " / "); } System.out.println(); }} Before sort: id: 3 name: John age: 18 / ID: 2 name: Marry age: 21 / ID: 2 name: Tom age: 20 / ID: 4 name: Mark age: 20 / id: 4 name: Ruby age: 20 / After sort: id: 2 name: Marry age: 21 / id: 2 name: Tom age: 20 / id: 3 name: John age: 18 / id: 4 name: Mark age: 20 / id: 4 name: Ruby age: 20 /Copy the code
We can see that the first order is sorted in ascending order by ID. When the IDS are the same, the order is sorted in descending order by age, such as Marry and Tom. If the IDS and ages are the same, the order is sorted in ascending order by name, such as Mark and Ruby.
The above example from bosses www.jianshu.com/p/f0d39ab40…
Requirements to implement Comparable:
(1) Symmetry is satisfied. If the object A.comparaTo(B) is greater than 0, then B.comparaTo(A) must be less than 0. (2) Meet the transitivity. That is, object A.comparaTo(B) is greater than 0, object B.comparaTo(Z) is greater than 0, object A.comparaTo(Z) must be greater than 0; (3) It is recommended that the comparaTo and equals() methods be identical. A.equals(B) = true (4) For classes that implement the Comparable interface, try not to inherit it and take a composite approach.
7. To summarize
Here are some tips on how to write a good CompareTo method:
- If the object has more than one field, start the comparison with the key field.
- You can recursively call the CompareTo method of a reference field for an object in turn
- Prior to java7, you could use the relational operators < and > to compare fields of integer primitive types, and the static methods Double.compare and Float.compare to compare fields of floating-point primitive types.
- Since Java 7, the static compare method has been added to all Java classes that box primitive types. Using the relational operators < and > in compareTo methods is tedious and error-prone, so it is no longer recommended.
// Comparator based on static compare method static Comparator<Object> hashCodeOrder = new Comparator<>() { public int compare(Object o1, Object o2) { return Integer.compare(o1.hashCode(), o2.hashCode()); }};Copy the code
- After java8, with the introduction of lamda expressions, the Compartor interface configured a set of comparison constructors that made comparator construction very streamlined.
// Comparator based on Comparator construction method
static Comparator<Object> hashCodeOrder =
Comparator.comparingInt(o -> o.hashCode());
Copy the code
In summary, whenever you implement a value class with reasonably ordered values, you should have that class implement the Comparable interface to make it easy to sort, search, and use examples in a comparison-based collection. Avoid using the “<” and “>” operators when comparing field values in implementations of compareTo methods. Instead, use the == static compare method == in the wrapper class or the build method == in the ==Comparator interface.
8. References
www.jianshu.com/p/f0d39ab40…
www.jianshu.com/p/0c0bcc457…
www.taodudu.cc/news/show-2…
Pay attention to the public account “Programmer interview”
Reply to “interview” to get interview package!!
This public account to share their own from programmer xiao Bai to experience spring recruitment autumn recruitment cut more than 10 offer interview written test experience, including [Java], [operating system], [computer network], [design mode], [data structure and algorithm], [Dacheng face by], [database] look forward to you join!!
1. Computer network —- Three times shake hands four times wave hands
2. Dream come true —– Project self-introduction
Here are the design patterns you asked for
4. Shocked! Check out this programmer interview manual!!
5. Teach you the interview “Profile” word for word
6. Nearly 30 interviews shared
7. Here are the free books you asked for