日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java compareto 返回值_Java comparable接口及compareTo返回值所决定的升序降序问题

發布時間:2024/3/26 java 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java compareto 返回值_Java comparable接口及compareTo返回值所决定的升序降序问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我們在學習java基礎的時候知道,基本數據類型數組可以直接調動Arrays類的靜態sort方法,然后輸出。

例如: int iArr[] = {1,2,4,6}; ?Arrays.sort(iArr); 然后利用for循環輸出..

但是如果我們是對象數組的話,則對象所在的類必須實現comparable接口,覆寫它的compareTo方法,并且要有不同的返回值,代表升序和降序。

但是會有一個疑問:為什么對象數組調用Arrays.sort 必須要實現comparable接口呢?而且compareTo的返回值到底代表什么意義呢,它又是如何決定數組的升序和降序的呢?

帶著這樣的疑問,我自己寫了一個很簡單的例子,然后進行調試,跟進源碼,終于發現的一點端倪,然后把我自己理解分享給大家

關于如何進入源碼,以及查看源碼中與變量有關的信息我的有一篇博客講到?補充?,有時間可以去看下。。

接下來上代碼://Test類 package TEST;

public class Test implements Comparable

{

int age = 0;

String Name;

public Test(int age, String name)

{

super();

this.age = age;

Name = name;

}

public int compareTo(Test o)

{

if (this.age > o.age)

return 1;

else return -1;

}

public String toString()

{

return age+Name;

}

}

//TestDemo類 package TEST;

import java.util.Arrays;

public class TestDemo

{

public static void main(String args[])

{

Test t[] = {

new Test(6, "paul"),

new Test(5, "ss"),

new Test(2, "kk"),

new Test(3, "tt"),

new Test(1, "ii")

};

Arrays.sort(t);

for (int i=0; i

{

System.out.println(t[i]);

}

}

}

接下來我們加入斷點進行調試

首先我們進入方法1:?Arrays.class中的sort()方法

public static void sort(Object[] a)

{

if (LegacyMergeSort.userRequested)

legacyMergeSort(a);

Else

ComparableTimSort.sort(a, 0, a.length, null, 0, 0);

}

接下來進入方法2:ComparableTimSort.class 的sort()方法

static void sort(Object[] a, int lo, int hi, Object[] work, int workBase, int workLen)

{

assert a != null && lo >= 0 && lo <= hi && hi <= a.length;

int nRemaining = hi - lo;

if (nRemaining < 2) return;

// Arrays of size 0 and 1 are always sorted

// If array is small, do a "mini-TimSort" with no merges

if (nRemaining < MIN_MERGE)

{

int initRunLen = countRunAndMakeAscending(a, lo, hi);

binarySort(a, lo, hi, lo + initRunLen);

return;

}

ComparableTimSort ts = new ComparableTimSort(a, work, workBase, workLen);

int minRun = minRunLength(nRemaining);

do {

// Identify next run

int runLen = countRunAndMakeAscending(a, lo, hi);

// If run is short, extend to min(minRun, nRemaining)

if (runLen < minRun)

{

int force = nRemaining <= minRun ? nRemaining : minRun;

binarySort(a, lo, lo + force, lo + runLen);

runLen = force;

}

// Push run onto pending-run stack, and maybe merge ts.pushRun(lo, runLen);

ts.mergeCollapse();

// Advance to find next run

lo += runLen; nRemaining -= runLen;

} while (nRemaining != 0);

// Merge all remaining runs to complete sort

assert lo == hi;

ts.mergeForceCollapse();

assert ts.stackSize == 1;

}

下一步進入:方法3:ComparableTimSort.class的countRunAndMakeAscending方法里面終于見到了我們的CompareTo方法

private static int countRunAndMakeAscending(Object[] a, int lo, int hi) {

assert lo < hi;

int runHi = lo + 1;

if (runHi == hi)

return 1;

// Find end of run, and reverse range if descending

if (((Comparable) a[runHi++]).compareTo(a[lo]) < 0) {

while (runHi < hi && ((Comparable) a[runHi]).compareTo(a[runHi - 1]) < 0)

runHi++;

//反轉對象數組的lo~runHi-1部分,該方法也在ComparableTimSort.class中

reverseRange(a, lo, runHi);

} else {

while (runHi < hi && ((Comparable) a[runHi]).compareTo(a[runHi - 1]) >= 0)

runHi++;

}

return runHi - lo;

}

這里你應該終于明白了為什么一定要實現comparable接口中的compareTo方法了吧。

如何你沒有實現,那么通過接口去找compareTo方法肯定會報錯啊(因為這時候找不到compareTo方法,未定義)

結合Test類中的compareTo方法,當this.age

所以進入while循環,直到?a[runHi]).compareTo(a[runHi - 1])>=0時結束循環,后反轉對象數組的lo~runHi-1部分

(ComparableTimSort.class)reverseRange(a, lo, runHi)的源碼如下:

private static void reverseRange(Object[] a, int lo, int hi) {

hi--;

while (lo < hi) {

Object t = a[lo];

a[lo++] = a[hi];

a[hi--] = t;

}

}

此時經過反轉后數組變為了 2, 5, 6, 3, 1(這里沒有寫name屬性),也就是前面3個對象是有序的,升序接下來我們就進入了下一個方法(ComparableTimSort.class)

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;

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;

}

}

我花了一點時間看了一下,就是C語言數據結構的二分排序法(也叫折半插入法,它是插入排序的一種改進版)

基本思想是:現將部分數組的部分元素變成一個有序的數組,后面的元素通過折半插入將它變成一個有序的數組。

例如前文:數組變成了2,5,6,3,1

則3插入前面有序的數組中,變成了 2,3,5,6,1

1在插入前面有序的數組中,變成了1,2,3,5,6

大家有時間可以去研究下。。這里不做詳細說明。到了這里方法基本都跟進并介紹完了

輸出結果:

1ii

2kk

3tt

5ss

6paul ?升序。

那如何是降序呢?

修改Test類中的compareTo方法:

public int compareTo(Test o)

{

if (this.age > o.age)

return -1;

return 1;

}

將返回值調換就行了,輸出結果:

6paul

5ss

3tt

2kk

1ii ? ?降序

關于compareTo方法的實現及返回值以下的組合,譬如:

public int compareTo(Test o)

{

if (o.age > this.age){

return 1;

return -1;

}

public int compareTo(Test o)

{

if (o.age > this.age)

return -1;

return 1;

}

那他們到底是升序還是降序呢?自己結合源碼可以去思考一下。

但是上面兩種不建議寫,因為容易混淆。推薦寫最上面兩種。。。

寫了這么多 總結一下:

//升序

public int compareTo(Test o)

{

if (this.age>o.age ){

return 1;

return -1;

}

//降序

public int compareTo(Test o)

{

if (this.age > o.age)

return -1;

return 1;

}

我自己記憶的方法是:

大于號 返回1,正乘正為正,所以升序(可以把>號想象為正)

大于號返回-1,正乘負為負,所以降序

提示非常重要的一點,compareTo中的方法一定要有至少兩個以上(其實兩個足夠)的返回值,而且一個返回值一定要小于0,另一個一定要大于或等于0。

否則排序不會成功。自己結合ComparableTimSort.class的countRunAndMakeAscending方法分析。

最后留一個問題:我們說可以按照年齡屬性進行降序升序排序,但比如有如下要求。

要求按照年齡大小升序排列,當年齡相同時,按照name屬性降序排列,這時候compareTo函數怎么寫呢?

大家可以去思考一下,這里我就不貼代碼出來了,相信大家看過前文,自己思考一下應該可以寫出來。

好了,這個博客寫了好多小時了,該結束了,現在是北京時間22:25。撤了,撤了,大家晚安。

2017/6/19/ 22:25 ---祥子

總結

以上是生活随笔為你收集整理的java compareto 返回值_Java comparable接口及compareTo返回值所决定的升序降序问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。