arraylist java 排序_Java ArrayList排序方法详解
由于其功能性和靈活性,ArrayList是 Java 集合框架中使用最為普遍的集合類之一。ArrayList 是一種 List 實(shí)現(xiàn),它的內(nèi)部用一個(gè)動態(tài)數(shù)組來存儲元素,因此 ArrayList 能夠在添加和移除元素的時(shí)候進(jìn)行動態(tài)的擴(kuò)展和縮減。你可能已經(jīng)使用過 ArrayList,因此我將略過基礎(chǔ)部分。如果你對 ArrayList 還不熟悉,你可以參考它的?API 文檔,可以很容易理解在 ArrayList 上執(zhí)行基本的操作。In this post, I will discuss one of the most important operation on ArrayList that you will most likely require implementing during enterprise application development. It’s sorting the elements of an ArrayList.在這篇文章中,我將討論 ArrayList 中一種極其重要的操作,你很有可能需要在企業(yè)應(yīng)用開發(fā)中實(shí)現(xiàn)它。它就是 ArrayList 元素的排序。
排序字符串對象的 ArrayList
考慮一個(gè) ArrayList 存儲著以字符串形式存在的國名(country name),為了對這個(gè) ArrayList 進(jìn)行排序,你需要調(diào)用 Collections.sort()方法,傳遞由國名構(gòu)成的 ArrayList 對象。這種方法將按照自然順序(按字母升序)對元素(國名)進(jìn)行排序。讓我們?yōu)榇藖韺懸欢未a。SortArrayListAscendingDescending.java
在上面的類中,我們在構(gòu)造器中初始化了一個(gè) ArrayList 對象。在 sortAscending()方法中,我們調(diào)用了 Collections.sort()方法,并傳遞這個(gè)初始化的 ArrayList對象為參數(shù),返回排序后的 ArrayList。在 sortDescending()方法中,我們調(diào)用重載的 Collections.sort()方法讓其按照降序?qū)υ嘏判?#xff0c;這個(gè)版本的 Collections.sort()接收ArrayList對象作為第一個(gè)參數(shù),一個(gè)由 Collections.reverseOrder()方法返回的 Comparator 對象作為第二個(gè)參數(shù)。我們將會在稍后講解 Comparator。為了測試排序功能,我們將寫一段測試代碼。SortArrayListAscendingDescendingTest.java
在上面的測試代碼中,我們創(chuàng)建一個(gè) ArrayList 對象,并添加了 5 個(gè)字符串對象代表 5 個(gè)國家的名字。然后我們調(diào)用 getArrayList()、sortAscending()和 sortDescending()方法,并打印這些方法返回的 ArrayList 對象。輸出如下:
到目前為止,所要排序的 ArrayList 元素都是非常簡單的,我們僅僅只是調(diào)用 Collections.sort()方法并傳遞了需要排序的 ArrayList 對象作為參數(shù)。但是更多的是你會遇到一些復(fù)雜的情景下對 ArrayList 進(jìn)行排序。Collections.sort() 方法對 ArrayList 的元素或者任何其他 List 的實(shí)現(xiàn)提供的可比較的元素進(jìn)行排序,這意味著這些元素的類需要實(shí)現(xiàn) java.lang 包中的 Comparable 接口。正如 String 類實(shí)現(xiàn)了 Comparable 接口,我們就可以對由國名構(gòu)成的 ArrayList 排序。有些其他的標(biāo)準(zhǔn) Java 類實(shí)現(xiàn)了 Comparable 接口,包括原始的包裝類,例如 Integer、Short、Double、Float、Boolean、BigInteger、BigDecimal、File 和 Date 類都實(shí)現(xiàn)了 Comparable 接口。
使用Comparable排序ArrayList
Comparable 是帶有單一?compareTo()方法的接口。一個(gè)實(shí)現(xiàn)了 Comparable 接口的類對象可以與其它同類型的對象進(jìn)行比較,實(shí)現(xiàn) Comparable 接口的類需要重寫 compareTo()方法,這個(gè)方法接收一個(gè)同類型的對象,并實(shí)現(xiàn)這個(gè)對象和傳遞給方法的另一個(gè)對象比較的邏輯。compareTo()方法返回Int類型的比較結(jié)果,分別代表下面的含義:正值表示當(dāng)前對象比傳遞給 comPareTO()的對象大負(fù)值表示當(dāng)前對象比傳遞給 comPareTO()的對象小零表示兩個(gè)對象相等讓我們來舉一個(gè)例子,JobCandidate 類的對象保存在 ArrayList 中并準(zhǔn)備對其進(jìn)行排序。JobCandidate 類有三個(gè)成員變量:字符串類型的姓名和性別、整型的年齡。我們想要對保存在 ArrayList 中的 JobCandidate 對象按照年齡進(jìn)行排序。因此我們要讓 JobCandidate 類實(shí)現(xiàn) Comparable 接口并重寫 compareTo()方法。The code of the JobCandidate class is this.JobCandidate類的代碼如下:JobCandidate.java
在上面 JobCandidate 類被重寫的 compareTo()方法中,我們實(shí)現(xiàn)了基于年齡的比較邏輯。我見過很多程序員將(this.getAge() – candidate.getAge())作為返回的比較結(jié)果。盡管使用這種 return 語句看上去似乎很吸引人,并且也不會對我們的例子造成影響,我的建議是遠(yuǎn)離這種語句。想象一下,比較整數(shù)值,其中有一個(gè)或者兩個(gè)都是負(fù)數(shù)的結(jié)果。這會導(dǎo)致一些錯(cuò)誤,讓你的程序行為不定,而且更重要的是,這樣的錯(cuò)誤是很細(xì)微的,尤其是在大型的企業(yè)應(yīng)用中很難檢測出來。下面我們將寫一個(gè)輔助類,為委托方對包含了 JobCandidate 元素的 ArrayList 對象進(jìn)行排序。JobCandidateSorter.java
在 JobCandidateSorter 類中,我們初始化了一個(gè) ArrayList 對象,委托方將通過構(gòu)造函數(shù)實(shí)例化 JobCandidateSorter 。然后我們編寫了 getSortedJobCandidateByAge()方法,在這個(gè)方法中,我們調(diào)用 Collections.sort()并傳遞已經(jīng)初始化了的 ArrayList 為參數(shù),最后返回排序后的 ArrayList。接下來,我們寫一個(gè)測試類來測試一下我們的代碼。JobCandidateSorterTest.java
在上面的測試類中,我們創(chuàng)建了四個(gè) JobCandidate 對象并把它們添加到 ArrayList,然后傳遞這個(gè) ArrayList 到構(gòu)造函數(shù)來實(shí)例化 JobCandidateSorter 類。最后,我們調(diào)用 JobCandidateSorter 類的 getSortedJobCandidateByAge()方法,并打印這個(gè)方法返回的排序后的 ArrayList。測試的輸出結(jié)果如下:
使用 Comparable 對 ArrayList 排序是一種常用的方法。但是你必須知道有某些限制。你想要排序的對象的類必須實(shí)現(xiàn) Comparable 并覆寫 compareTo()方法。這基本上意味著你將只能基于一個(gè)成員變量來比較對象(我們例子中的年齡字段)。如果要求你按照姓名和年齡來對 JobCandidate 對象進(jìn)行排序怎么辦? Comparable 就不是解決的方法了。另外,比較邏輯是需要進(jìn)行比較的對象的類的一部分,它消除了比較邏輯可復(fù)用性的可能。Java 通過使用在 java.util 包下提供的Comparator接口解決了上述的比較需求。
使用 Comparator 排序 ArrayList
Comparator 接口與Comparable 接口相似也提供了一個(gè)單一的比較方法叫作 compare()。然而,與 Comparable的 compareTo()方法不同的是,這個(gè) compare()接受兩個(gè)同類型的不同對象進(jìn)行比較。我們將用 Comparator 對我們之前使用過的相同?JobCandidate 類對象進(jìn)行排序。我們將通過實(shí)現(xiàn) Comparatoras 匿名內(nèi)部類,允許對 JobCandidate 對象按照年齡和姓名進(jìn)行排序。下面是使用了 Comparator 的 JobCandidate 類代碼JobCandidate.java
在上面的類中,從 29 行到 35 行,我們寫了一個(gè)匿名類并實(shí)現(xiàn)了 compare()方法,按照年齡的降序?qū)?JobCandidate 對象進(jìn)行排序。從37行到42行,我們又寫了一個(gè)匿名類并實(shí)現(xiàn)了 compare() 方法,按照姓名的升序?qū)?JobCandidate進(jìn)行排序?,F(xiàn)在我們寫一個(gè)類,為委托方對 ArrayList 的元素進(jìn)行排序。JobCandidateSorter.java
在上面的類中,我們寫了 getSortedJobCandidateByAge()方法,在這個(gè)方法內(nèi)部我們調(diào)用了 Collections.sort()的重載版本,這個(gè)版本傳遞要被排序的 ArrayList 對象和比較年齡的 Comparator 對象。在 getSortedJobCandidateByName()方法內(nèi)部,我們又調(diào)用了 Collections.sort()的另一個(gè)重載版本,這個(gè)版本傳遞要被排序的 ArrayList 對象和比較姓名的 Comparator 對象。Let’s write a test class to test our code.讓我們寫一個(gè)測試類來測試我們的代碼。JobCandidateSorterTest.java
在測試類中我們向 ArrayList 中添加若干 JobCandidate 對象,并使用 Before 注釋在測試單元的 setup()方法中創(chuàng)建了一個(gè) JobCandidateSorter 對象。如果你是一個(gè) Junit 新手,可以參考我以前的文章包括 Junit 注釋(Junit 單元測試系列)。在 testGetSortedJobCandidateByAge()測試方法中我們調(diào)用了 getSortedJobCandidateByAge()方法,并打印了該方法返回的排序后的 ArrayList。在 testGetSortedJobCandidateByName()測試方法中我們調(diào)用了getSortedJobCandidateByName()方法并同樣打印該方法返回的 ArrayList。測試的輸出如下:
總結(jié)
在本文中我們看到了 ArrayList 排序的不同方法。一種是使用 Comparable 另一種是使用 Comparator。方法的選擇一直是造成程序員們困惑的原因之一。你最應(yīng)該記住的就是一個(gè) Comparable 對象可以說“我可以自己與另外一個(gè)對象比較”而一個(gè) Comparator 對象可以說“我可以比較兩個(gè)不同的對象”。你不能說一個(gè)接口比另一個(gè)要好。選擇的接口取決于你需要實(shí)現(xiàn)的功能。
總結(jié)
以上是生活随笔為你收集整理的arraylist java 排序_Java ArrayList排序方法详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: gprinter佳博打印机android
- 下一篇: Java多线程下载