1. 程式人生 > >java學習-排序及加密簽名時數據排序方式

java學習-排序及加密簽名時數據排序方式

poi elong while ips () sort this 基本數據 clas

排序有兩種,

基本數據類型的包裝類Integer, Float, Double,Long,Byte等都實現的Comparable接口,用於列表List或數組arrays的排序

Comparable<Integer>接口方法的實現,對象列表的升序降序接口

我們通過重寫改接口方法,可以對列表進行升序或降序排列。

public int compareTo(T o);

This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class‘s natural ordering

, and the class‘s compareTo method is referred to as its natural comparison method.

此接口對實現它的每個類的對象強加一個默認排序。這種排序被稱為類的自然排序,類的compareTo方法被稱為其自然比較方法。

Lists (and arrays) of objects that implement this interface can be sorted automatically by Collections.sort (and Arrays.sort).

只有實現的這個接口的對象list列表或array數組才可以使用sort方法讓列表或數組的元素被自動排序

只需要實現compareTo()方法即可

public int compareTo(){}這個比較方法,,
如果要將對象列表進行升序排序,則第i個元素和第i+1元素 要滿足a[i]>a[i+1] 返回1 a[i]<a[i+1] 返回-1 a[i]=a[i+1] 返回0

如果要將對象列表進行降序排序  要滿足 a[i]>a[i+1] 返回-1 a[i]<a[i+1] 返回1 a[i]=a[i+1] 返回0
Collections.sort方法實現的就是按照此比較的東西排列
升序(從小到大):
if(price < o.price){
    return -1;
}
if(price > o.price){
   return 1;
}
降序(從大到小):
if(price < o.price){
   return 1;
}
if(price > o.price){
   return -1;
}
技術分享圖片
    //將對象按價格進行升序排序
    @Override
    public int compareTo(flower o) {
        //首先比較price,如果price相同返回0
        if(price < o.price){
            return -1;
        }
        if(price > o.price){
            return 1;
        }
        
        return 0;
    }
技術分享圖片

為什麽升序 返回值為1時,是n的值要大於n+1的值,而返回值為-1時n的值要小於n+1呢?

這個要查看源碼才可以知道原理。(不好奇的可以不看哦^~^)

由於這個List.sort()這個排序方法時使用二分排序,源碼如下,

技術分享圖片 技術分享圖片
private static void binarySort(Object[] a, int lo, int hi, int start) {
        assert lo <= start && start <= hi;
        if (start == lo)
            start++;
        for ( ; start < hi; start++) {
            Comparable pivot = (Comparable) a[start];

            // Set left (and right) to the index where a[start] (pivot) belongs
            int left = lo;
            int right = start;
            assert left <= right;
            /*
             * Invariants:
             *   pivot >= all in [lo, left).
             *   pivot <  all in [right, start).
             */
            while (left < right) {
                int mid = (left + right) >>> 1;
                if (pivot.compareTo(a[mid]) < 0)
                    right = mid;
                else
                    left = mid + 1;
            }
            assert left == right;

            /*
             * The invariants still hold: pivot >= all in [lo, left) and
             * pivot < all in [left, start), so pivot belongs at left.  Note
             * that if there are elements equal to pivot, left points to the
             * first slot after them -- that‘s why this sort is stable.
             * Slide elements over to make room for pivot.
             */
            int n = start - left;  // The number of elements to move
            // Switch is just an optimization for arraycopy in default case
            switch (n) {
                case 2:  a[left + 2] = a[left + 1];
                case 1:  a[left + 1] = a[left];
                         break;
                default: System.arraycopy(a, left, a, left + 1, n);
            }
            a[left] = pivot;
        }
    }
技術分享圖片 技術分享圖片
            while (left < right) {
                int mid = (left + right) >>> 1;
                if (pivot.compareTo(a[mid]) < 0)
                    right = mid;
                else
                    left = mid + 1;
            }
技術分享圖片

這個值是和已排序的數據的中間的數據進行比較,provot.compareTo(a[mid])

註意看,上面的a[mid]是作為比較方法的參數。

當小於0,也就是值為-1時,是我們要插入的數據作為調用方,

小於0時,該數據插入到前面,

大於0時,數據插入到後面

思維慣性以為升序就是第一個元素比第二個元素小。obj1.compareTo(Object obj2)

即obj1=2是第一個元素,obj2=8是第二個元素

那麽我們升序時,如果obj1小於obj2,返回值為-1,則會將obj2插入到obj1前面,,排序前【2, 8】這樣排序完後卻變成了,,【8, 2】

這跟我們想要的升序數據不一樣,

原因是java的二分法進行比較了是,,obj2.compareTo(obj1),,與我們想的剛好相反,

所以我們返回的值取反就可以變成升序了,

如這個消費類,,只給出部分代碼

技術分享圖片
public class ConsumInfo implements Comparable<ConsumInfo> {
    public double price;
   public String name;
  public Consuminfo(double price, String name){
   this.price = price;
   this.name = name;
  } @Override public int compareTo(ConsumInfo o) { //首先比較price,如果price相同 if(price < o.price){ return -1; } if(price > o.price){ return 1; } return 0; } }
技術分享圖片 技術分享圖片
    ConsumInfo consumInfo1 = new ConsumInfo("consumInfo1", 400.0);
       ConsumInfo consumInfo2 = new ConsumInfo("consumInfo2", 200.0);
    List<ConsumInfo> list = new ArrayList<ConsumInfo>(); list.add(consumInfo1); list.add(consumInfo2);     System.out.println("排序前:");     for(ConsumInfo consumInfo : list ){ System.out.println(consumInfo); }     Collections.sort(list);//排序     System.out.println("排序後:");//排序後 for(ConsumInfo consumInfo :list){ System.out.println(consumInfo); }
技術分享圖片

控制臺輸出信息為:

排序前:
ConsumInfo [name=consumInfo1, price=400.0]
ConsumInfo [name=consumInfo2, price=200.0]
排序後:
ConsumInfo [name=consumInfo2, price=200.0]
ConsumInfo [name=consumInfo1, price=400.0]

上面是最簡單的兩個元素進行排序,

第一次,往已排序列表中插入第一個元素,即數組中只有一個已排好序的元素,a[0] = consumInfo1

第二次時,left為0,right為1,進入while循環中,

mid=0,privot=consumInfo2

即consumInfo2.comparTo(a[0])

當方法的返回值小於0時,consumInfo2會插入在consumInfo1之前,

大於0時,會在consumInfo1之後

進行比較時,consumInfo2.price<consumInfo1.price 返回值小於0,也就是consumInfo1的值比較大,插入在1之前

java學習-排序及加密簽名時數據排序方式