Java set sorting function for analysis, java set sorting Function

Source: Internet
Author: User

Java set sorting function for analysis, java set sorting Function

How does Java sort sets?

-This document sorts Student object sets as an example.
Java uses Collections. sort (List <Student> stuList) and Collections. sort (List <Student> stuList, Comparator c) to sort data.

Sort using the Collections. sort (List list) method:

Step 1: Make sure that the Student class implements the Comparable interface and overwrites the compareTo () method.

Step 2: Call the Collections. sort (List list) method for sorting.

1 public class Student implements Comparable <Student> {2 3 private int age; 4 5 public Student (int age) {6 this. age = age; 7} 8 9 public int getAge () {10 return age; 11} 12 13 @ Override14 public int compareTo (Student student) {// override compareTo Method 15 16 return (this. age <student. age )? -1: (this. age = student. age )? 0: 1); 17} 18 19 20 public static void main (String [] args) {21 List <Student> stuList = new ArrayList (); 22 stuList. add (new Student (5); 23 stuList. add (new Student (3); 24 stuList. add (new Student (7); 25 stuList. add (new Student (2); 26 stuList. add (new Student (4); 27 stuList. add (new Student (6); 28 stuList. add (new Student (1); 29 30 Collections. sort (stuList); // call the sorting method 31 32 for (Student student: stuList) {33 System. out. println (student. getAge (); 34} 35} 36}

Principle Analysis:

Step 1: The Collections class calls the List. sort (Comparator c) method, and the Comparator c is assigned null.

1     public static <T extends Comparable<? super T>> void sort(List<T> list) {2         list.sort(null);3     }

Step 2: the sort method in the List interface converts the stuList set to an array, sorts it using the Arrays. sort () method, and replaces each element in the stuList with the sorted element.

1    default void sort(Comparator<? super E> c) {2         Object[] a = this.toArray();3         Arrays.sort(a, (Comparator) c);4         ListIterator<E> i = this.listIterator();5         for (Object e : a) {6             i.next();7             i.set((E) e);8         }9     }

So where did I call the compareTo method?

Enter the Arrays. sort () method:

 1     public static <T> void sort(T[] a, Comparator<? super T> c) { 2         if (c == null) { 3             sort(a); 4         } else { 5             if (LegacyMergeSort.userRequested) 6                 legacyMergeSort(a, c); 7             else 8                 TimSort.sort(a, 0, a.length, c, null, 0, 0); 9         }10     }

No comparator is specified, so c = null is true. Execute the sort (a) method:

1 public static void sort(Object[] a) {2         if (LegacyMergeSort.userRequested)3             legacyMergeSort(a);4         else5             ComparableTimSort.sort(a, 0, a.length, null, 0, 0);6     }

The default value of LegacyMergeSort. userRequested is false, indicating whether to use the traditional Merge Sorting. The traditional Merge Sorting is the default sorting method before and after 1.5, and the ComparableTimSort. sort () method is executed by default. Unless the program requires the use of traditional Merge Sorting. The statement is as follows:

System.setProperty("java.util.Arrays.useLegacyMergeSort", "true"); 

So continue to read the ComparableTimSort. sort () method:

 1     static void sort(Object[] a, int lo, int hi, Object[] work, int workBase, int workLen) { 2         assert a != null && lo >= 0 && lo <= hi && hi <= a.length; 3  4         int nRemaining  = hi - lo; 5         if (nRemaining < 2) 6             return;  // Arrays of size 0 and 1 are always sorted 7  8         // If array is small, do a "mini-TimSort" with no merges 9         if (nRemaining < MIN_MERGE) {10             int initRunLen = countRunAndMakeAscending(a, lo, hi);11             binarySort(a, lo, hi, lo + initRunLen);12             return;13         }14 15         /**16          * March over the array once, left to right, finding natural runs,17          * extending short natural runs to minRun elements, and merging runs18          * to maintain stack invariant.19          */20         ComparableTimSort ts = new ComparableTimSort(a, work, workBase, workLen);21         int minRun = minRunLength(nRemaining);22         do {23             // Identify next run24             int runLen = countRunAndMakeAscending(a, lo, hi);25 26             // If run is short, extend to min(minRun, nRemaining)27             if (runLen < minRun) {28                 int force = nRemaining <= minRun ? nRemaining : minRun;29                 binarySort(a, lo, lo + force, lo + runLen);30                 runLen = force;31             }32 33             // Push run onto pending-run stack, and maybe merge34             ts.pushRun(lo, runLen);35             ts.mergeCollapse();36 37             // Advance to find next run38             lo += runLen;39             nRemaining -= runLen;40         } while (nRemaining != 0);41 42         // Merge all remaining runs to complete sort43         assert lo == hi;44         ts.mergeForceCollapse();45         assert ts.stackSize == 1;46     }

The nRemaining of line4 indicates the number of objects without sorting. If the number is smaller than 2 before the method is executed, no sorting is required.

If 2 <= nRemaining <= 32, that is, the initial value of MIN_MERGE, indicates that the array to be sorted is a small array, you can use the mini-TimSort Method for sorting. Otherwise, Merge Sorting is required.

Mini-TimSort sorting method: first find the first ascending sequence in the array starting from the subscript 0, or find the descending sequence and convert it to ascending order and then put it into the array, use this ascending array as the initial array, and insert each element into the initial array by means of binary sorting. Note: The compareTo () method we have rewritten is called here.

How to obtain the initial array:

 1     private static int countRunAndMakeAscending(Object[] a, int lo, int hi) { 2         assert lo < hi; 3         int runHi = lo + 1; 4         if (runHi == hi) 5             return 1; 6  7         // Find end of run, and reverse range if descending 8         if (((Comparable) a[runHi++]).compareTo(a[lo]) < 0) { // Descending 9             while (runHi < hi && ((Comparable) a[runHi]).compareTo(a[runHi - 1]) < 0)10                 runHi++;11             reverseRange(a, lo, runHi);12         } else {                              // Ascending13             while (runHi < hi && ((Comparable) a[runHi]).compareTo(a[runHi - 1]) >= 0)14                 runHi++;15         }16 17         return runHi - lo;18     }

According to the example in the program, a [1]. compareTo (a [0]) <0, so you can view a [2] In the next loop. compareTo (a [1]) <0, a [3]. compareTo (a [2]) <0 and so on. We found that a [2]. compareTo (a [1]) <0 is invalid, so the loop ends. The longest descending array obtained is a [] {5, 3}, and then the reverseRange () is called () method to sort it in ascending order as a [] {3, 5}, as the initial array, initRunLen = 2. Then perform a binary insert operation. The Code is as follows:

 1 private static void binarySort(Object[] a, int lo, int hi, int start) { 2         assert lo <= start && start <= hi; 3         if (start == lo) 4             start++; 5         for ( ; start < hi; start++) { 6             Comparable pivot = (Comparable) a[start]; 7  8             // Set left (and right) to the index where a[start] (pivot) belongs 9             int left = lo;10             int right = start;11             assert left <= right;12             /*13              * Invariants:14              *   pivot >= all in [lo, left).15              *   pivot <  all in [right, start).16              */17             while (left < right) {18                 int mid = (left + right) >>> 1;19                 if (pivot.compareTo(a[mid]) < 0)20                     right = mid;21                 else22                     left = mid + 1;23             }24             assert left == right;25 26             /*27              * The invariants still hold: pivot >= all in [lo, left) and28              * pivot < all in [left, start), so pivot belongs at left.  Note29              * that if there are elements equal to pivot, left points to the30              * first slot after them -- that's why this sort is stable.31              * Slide elements over to make room for pivot.32              */33             int n = start - left;  // The number of elements to move34             // Switch is just an optimization for arraycopy in default case35             switch (n) {36                 case 2:  a[left + 2] = a[left + 1];37                 case 1:  a[left + 1] = a[left];38                          break;39                 default: System.arraycopy(a, left, a, left + 1, n);40             }41             a[left] = pivot;42         }43     }

All the elements whose subscript is> = 2 in a loop are inserted to the appropriate position in the initial array through the binary method. In this way, the sorting function of the elements is completed by calling the compareTo () method.

Sort by using the Collections. sort (List list, Comparator c) method:

This method is used to pass in a comparator to compare the size of each element. This method requires no element to implement the Comparable interface, but requires an implementation class that implements the Comparator interface to instantiate a Comparator. Note that the Comparator here is an interface rather than a class. The anonymous internal class method is usually used here.

1 Collections.sort(stuList, new Comparator<Student>() {2             @Override3             public int compare(Student stu1, Student stu2) {4                 return (stu1.getAge() < stu2.getAge()) ? -1 : (stu1.getAge() == stu2.getAge() ? 0 : 1);5             }6         });

This method achieves sorting in the same way as the preceding method.

Call the Collections. sort () method first, pass in the set and comparator, the sort () method calls the sort method of List, and pass in the comparator. (Same as step 1) the code is as follows:

1     public static <T> void sort(List<T> list, Comparator<? super T> c) {2         list.sort(c);3     }

 

The sort () method in List calls the Arrays. sort () method to pass in Arrays and comparator. (Same as step 2)

1 default void sort(Comparator<? super E> c) {2     Object[] a = this.toArray();3     Arrays.sort(a, (Comparator) c);4     ListIterator<E> i = this.listIterator();5     for (Object e : a) {6         i.next();7         i.set((E) e);8     }9 }

The Arrays. sort method calls the TimSort. sort () method. The Code is as follows:

 1 public static <T> void sort(T[] a, Comparator<? super T> c) { 2         if (c == null) { 3             sort(a); 4         } else { 5             if (LegacyMergeSort.userRequested) 6                 legacyMergeSort(a, c); 7             else 8                 TimSort.sort(a, 0, a.length, c, null, 0, 0); 9         }10     }

LegacyMergeSort (a, c) and TimSort. in the sort () method, there is only one difference from method 1, that is, method 1 uses. compareTo (B) is compared, while comparator is used in method 2. compare (a, B.

 1 private static <T> int countRunAndMakeAscending(T[] a, int lo, int hi, 2                                                     Comparator<? super T> c) { 3         assert lo < hi; 4         int runHi = lo + 1; 5         if (runHi == hi) 6             return 1; 7  8         // Find end of run, and reverse range if descending 9         if (c.compare(a[runHi++], a[lo]) < 0) { // Descending10             while (runHi < hi && c.compare(a[runHi], a[runHi - 1]) < 0)11                 runHi++;12             reverseRange(a, lo, runHi);13         } else {                              // Ascending14             while (runHi < hi && c.compare(a[runHi], a[runHi - 1]) >= 0)15                 runHi++;16         }17 18         return runHi - lo;19     }

Summary:

1. collections. there are two methods to implement sort () sorting. One is to enable the element class to implement the Comparable interface and overwrite the compareTo () method, and the other is to Collecitons. the sort () method is used to pass in the comparator. It is usually passed in anonymously.

2. collections. sort () calls Arrays. sort by Sort (). In Java1.6 +, if the set size is <32, the Tim-sort algorithm is used. If the set size is greater than or equal to 32, the merge Sort is used.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.