Java利用反射排序

  • 2019 年 10 月 5 日
  • 筆記

前言

Java為我們提供了幾種排序得方法,比如Arrays和Collections類,但是前提是數組或者集合中的元素都必須實現Comparable介面,基本的數據類型都已經實現了Comparable介面了,所以我們才能夠直接對基本類型的數組或者集合進行排序,比如Float和Integer類得源碼.

image.png

image.png

今天記錄一下對Comparable得使用和反射得使用.

先看一個Student類

image.png

我們要對他進行年齡排序,可以用冒泡進行排序,或者用選擇排序法

image.png

但是這不是主角,

而我們要用Comparable介面進行排序,所以先要實現它.並重寫compareTo方法,這個方法才是用來比較對象的,也就是this和傳入過來的obj進行比較,返回值代表:

>0    則this>obj,

=0    則this=obj

<0    則this<obj

image.png

其實我們可以這樣簡寫一下,原理是一樣的.

image.png

如果想降序呢?直接在前面加一個負號唄

image.png

直接調用Collections.sort(list)進行排序,是不是簡單多了呢

但是此時,Student多了個欄位money,我們要多money進行排序,但是我們又想保留年齡排序方式,那麼Comparable就不太合適了

Comparator

我們可以用Collections.sort第二個重載方法,他接收兩個參數,第一個是要排序的集合,第二個是Comparator介面.

他和Comparable不同之處在於Comparable對內,而Comparator對外.原理也是一樣.

其實Collections.sort的兩個重載方法都是調用List的sort方法,但是如果list.sort想傳null,則必須要求T(也就是這個類)必須實現了Comparable介面,不然他沒辦法排序.如果這個類不想實現Comparable介面,那就使用對外介面Comparator.

image.png

image.png

寫兩個不同欄位的排序方法.同樣,如果想降序,前面加一個負號就可以

image.png

但是!!!

此時又多了一個欄位身高height,我們又想對height進行排序,那是不是又要寫一個方法呢?顯然必須要寫,不寫怎麼排?但是往後越來越多的欄位加入,這麼做肯定不好.

那要怎麼做?

先分析一下,這種方法排序無非就是獲取某個欄位的值,然後相減返回,那我們可以封裝一下,利用反射獲取某個類的欄位值,先看程式碼.

image.png

在此,聲明了一個sort方法

參數list,代表要排序的集合,

參數fieldName,代表要排序的欄位

參數isDesc,是否降序

訪問private的欄位首先要對field調用setAccessible(true),否則會報錯.

因為這個欄位可能是不同類型,所以統一先轉成Double類型,之後調用intValue方法.

怎麼樣,是不是很簡單了呢?

流年有愛

歲月靜好