Comparable and Comparator source code analysis

I. Introduction

  Inside the Java Collections Framework, a collection of various operations to a large extent are inseparable Comparable and Comparator, although the relationship between them and the collection is not displayed, but they can only maximize the power at the time of the collection inside. Here is the beginning of our analysis.

Second, the example

  Before the formal explanation Comparable and Comparator, we have an example to intuitive feel for their use.

  First, we defined the Person class  

Copy the code
class Person {
    String name;
    int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public String toString() {
        return "[name = " + name + ", age = " + age + "]";
    }
}
Copy the code

  Second, write test code, the code is as follows 

Copy the code
public class Test {
    public static void main(String[] args) {
        List<String> nameLists = new ArrayList<String>();
        nameLists.addAll(Arrays.asList("aa", "ab", "bc", "ba"));
        Collections.sort(nameLists);
        System.out.println(nameLists);
        
        List<Person> personLists = new ArrayList<Person>();
        personLists.addAll(Arrays.asList(new Person("leesf", 24), new Person("dyd", 24), new Person("ld", 0)));
        Collections.sort(personLists); // 出错
        System.out.println(personLists); } }
Copy the code

  Note: The above code is the same logic duplicate the same operation, but for List <String> does not complain, for List <Person> type of error will be, and why? To solve this problem, we need to explain today's hero Comparable && Comparator. If you know how to solve the Friends of the Park may also wish to look, start the analysis.

Third, source code analysis

  3.1 Comparable

  1. class inheritance 

public interface Comparable<T>

  Description: Comparable is a generic interface, very simple.

  2. compareTo method

public int compareTo(T o);

  Description: compareTo method constitutes the only effective method Comparable entire source code.

  3.2 Comparator

  1. class inheritance  

public interface Comparator<T>

  Description: Again, Comparator is a generic interface, very simple.

  2. compare methods 

int compare(T o1, T o2);

  Description: Comparator interface of a core method.

  3. equals method

boolean equals(Object obj);

  Description: This method is also an important way, but generally do not use, you can use the equals method (all objects inherited from Object) Object object directly.

  Other methods after adding JDK1.8 does not have an impact on our analysis, there are interested readers to read the source code for more details.

IV Solutions

  4.1 Analysis of the problem

  In our program, List <String> type can be compiled, but List <Person> type is not, and our guess is certainly an element type String, Person relationship. That being the case, we look at the definition of String in Java.

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence

  Description: We usually say the type String is final, can not be inherited, view the source code, it is indeed the case. String pay attention to see the interface implementation, intuition tells us Comparable <String> is very important, before we have analyzed the Comparable interface, since String implements this interface, then it is surely also realized compareTo method, fiddling, String's compareTo method is as follows:

Copy the code
public int compareTo (String anotherString) { 
    length // this object corresponding to a character string 
    int = LEN1 value.length; 
    // object parameter corresponding to the length of the string 
    int = LEN2 anotherString.value.length; 
    // get shorter-length the small 
    int = Math.min Lim (LEN1, LEN2); 
    // string underlying value is achieved for the type char [] array 
    // this character string object corresponds 
    char V1 [] = value; 
    // parameter object character string corresponding to 
    char V2 [] = anotherString.value; 
    
    int K = 0; 
    // two strings traverse 
    the while (K <Lim) { 
        char C1 V1 = [K]; 
        char C2 = V2 [K]; 
        // If not equal, it returns 
        IF (C1 = C2!) { 
            return C1 - C2; 
        } 
        // continue traversing 
        K ++; 
    }
    // string is a substring of another string 
    return LEN1 - LEN2; 
}
Copy the code

  Description: We can see the String method compareTo specific implementation. Character size comparison of the same index.

  After analyzing the String's compareTo method, and sorted according to the logic compareTo method, on how to sort of related to the specific algorithmic problems, we will analyze later. Ever since, we know where the problem before the sample program: Person class does not implement the Comparable interface.

  4.2. To solve the problem

  1. Modify the definition of our Person class is amended as follows:  

Person implements Comparable<Person>

  2. implement compareTo method, and want to achieve our own logical comparison, as we want to first of all by age comparison (using ASC), if the same age, according to the ASCII order to compare the names. So we compareTo method to achieve the following: 

Copy the code
    int compareTo(Person anthor) {
        if (this.age < anthor.age)
            return -1;
        else if (this.age == anthor.age)
            return this.name.compareTo(anthor.name);
        else
            return 1;
    }
Copy the code

  Description: Ever since, the modified procedure is as follows:

  Person class code is as follows  

Copy the code
class Person implements Comparable<Person> {
    String name;
    int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public String toString() {
        return "[name = " + name + ", age = " + age + "]";
    }
    
    @Override
    public int compareTo(Person anthor) {
        if (this.age < anthor.age)
            return -1;
        else if (this.age == anthor.age)
            return this.name.compareTo(anthor.name);
        else
            return 1;
    }
}
Copy the code

  Test category code unchanged

  Results are as follows:

  [aa, ab, ba, bc]
  [[name = ld, age = 0], [name = dyd, age = 24], [name = leesf, age = 24]]

  Description: We can see the sort Person class is indeed in accordance with the logic defined in the compareTo method to sort. Thus, the error correction.

Fifth, the issues raised

  Comparable interface to solve the above problems before. But, if I do not want to sort of just logically, would like to follow a new set of logical order, as only compare to sort by name. At this point, we need to modify the method compare Comparable interface, adding a new comparison logic. After a long time, user and wish to use other logic to sort, then they have to re compareTo method to modify the inside of logic, can be done if judged by the flag, which is used to determine whether the user wants to use the comparison logic, this will cause cause code is very bloated and difficult to maintain. In this case, a better solution is to use Comparator interface.

  5.1 a comparison logic

  First age comparison (using ascending), if of the same age, then compared according to the ASCII sequence names.

  Then we can define a Comparator, specific code as follows: 

Copy the code
class ComparatorFirst implements Comparator<Person> {    
    public int compare(Person o1, Person o2) {
        if (o1.age < o2.age)
            return -1;
        else if (o1.age == o2.age)
            return o1.name.compareTo(o2.name);
        else 
            return 1;
    }    
}
Copy the code

  Test code modified as follows:

  将Collections.sort(personLists) 改成 Collections.sort(personLists, new ComparatorFirst());

  sort of two overloaded methods, the latter allows us to pass a custom comparator.

  Results are as follows:

  [aa, ab, ba, bc]
  [[name = ld, age = 0], [name = dyd, age = 24], [name = leesf, age = 24]]

  The results: We see the Comparable interface and use the results obtained in front of the same.

  5.2 Comparison of two logic

  Directly compared according to the ASCII order of names.

  Then we can define as follows comparator  

class ComparatorSecond implements Comparator<Person> {
    public int compare(Person o1, Person o2) {
        return o1.name.compareTo(o2.name);
    }    
}

  Test code modified as follows:

  将Collections.sort(personLists) 改成 Collections.sort(personLists, new ComparatorSecond());

  operation result:

  [aa, ab, ba, bc]
  [[name = dyd, age = 24], [name = ld, age = 0], [name = leesf, age = 24]]

  Description: We can see the comparison logic and a comparator logic is not the same, but also completed the user logic.

  We can also define more other comparator in accordance with our wishes, only we need to complete our logic can correct compareTo in.

  5.3 Comparator advantage

  From the above two examples we should be able to feel the Comparator comparator is more flexible than the Comparable interface, more friendly and complete a variety of user-defined comparison logic.

VI Summary

  Comparable analyzes and Comparator, mastered the use of different comparators in different scenarios, and use the difference to write this post after blog also both more clear. Thank you Friends of the Park Watch ~

Guess you like

Origin www.cnblogs.com/wzq-xf/p/11784617.html