這篇文章主要講解了“Java中Sorting知識點有哪些”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Java中Sorting知識點有哪些”吧!
依安ssl適用于網(wǎng)站、小程序/APP、API接口等需要進行數(shù)據(jù)傳輸應用場景,ssl證書未來市場廣闊!成為成都創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:028-86922220(備注:SSL證書合作)期待與您的合作!
先上代碼:
package java.lang; public interface Comparable<T> { public int compareTo(T o); }
可以看出這個接口只有一個方法,這個方法只有一個參數(shù),實現(xiàn)了這個接口的類就可以和同類進行比較了。這個方法所實現(xiàn)的,就是比較法則,也是說,它表示如何對兩個對象進行比較。 它返回的是一個整數(shù)int:
返回正數(shù),代表當前對象大于被比較的對象;
返回0,代表當前對象等于于被比較的對象;
返回負數(shù),代表當前對象小于被比較的對象。
實現(xiàn)了該接口后,我們就可以使用Arrays.sort()和Collections.sort()來進行排序了。 不然對象沒有比較法則,程序肯定是不知道如何進行比較排序的。 像我們常用的類String、Integer、Double、Date等,JDK都幫我們實現(xiàn)了Comparable接口,我們可以直接對這類對象進行比較排序。 舉個例子,Date Comparable的實現(xiàn):
public int compareTo(Date anotherDate) { long thisTime = getMillisOf(this); long anotherTime = getMillisOf(anotherDate); return (thisTime<anotherTime ? -1 : (thisTime==anotherTime ? 0 : 1)); }
需要注意的是,當我們自己去實現(xiàn)Comparable接口時,一定要注意與**equals()**方法保持一致。當兩個對象是equals的,compare的結(jié)果應該是相等的。
還是先看代碼,看看接口定義吧:
package java.util; @FunctionalInterface public interface Comparator<T> { int compare(T o1, T o2); }
它是一個函數(shù)式接口,它的compare方法有兩個參數(shù),代表進行比較的兩個對象。這個接口代表了可以作為某種對象比較的一種法則,或叫一種策略。 它的返回值正負代表意義與Comparable接口的方法一樣。 它的使用通常會有三種方式:
實現(xiàn)類
匿名類
Lambda表達式
在Java8之后,我們一般用Lambda比較多,也比較靈活優(yōu)雅。
兩個接口功能都是用于比較排序,但其實有很大的區(qū)別。
兩者方法參數(shù)不同,Comparable只有一個參數(shù),表示被比較的對象,因為它的方法是位于需要比較的類里的,所以只要一個參數(shù)就可以了;而Comparator的比較方法則有兩個參數(shù),分別表示比較對象和被比較對象。
Comparable與對象綁定,位于對象內(nèi),我們可以稱之為內(nèi)比較器;而Comparator是獨立于需要比較的類的,我們可以稱為外比較器。
當類實現(xiàn)了Comparable方法后,比較法則就確定了,我們稱之為自然比較方法,我們無法給它實現(xiàn)多種比較方法;而因為Comparator獨立于外,我們可以為同一個類提供多種Comparator的實現(xiàn),這樣來提供多種比較方法/策略,如升序倒序,因此我們也可以將Comparator看成是一種策略模式。
相對于Comparable,Comparator有一定的靈活性,假如一個類并沒有實現(xiàn)Comparable接口,并且這個類是無法修改的,我們就要通過提供Comparator來進行比較排序。 Comparator這種模式實現(xiàn)了數(shù)據(jù)與算法的解耦合,對于維護也是很方便的。
十分友好的是,JDK為我們提供了工具類,它們的靜態(tài)方法可以幫助我們直接對數(shù)組和List進行排序。
Arrays的sort方法可以對已經(jīng)實現(xiàn)了Comparable接口的進行排序,同時還可指定排序的范圍。
//Arrays.sort對String進行排序 String[] strings = {"de", "dc", "aA", "As", "k", "b"}; Arrays.sort(strings); assertTrue(Arrays.equals(strings, new String[]{"As", "aA", "b", "dc", "de", "k"}));
指定范圍排序,需要注意的是,index是從0開始算的,包含fromIndex,不包含toIndex:
//Arrays.sort指定范圍排序 strings = new String[]{"z", "a", "d", "b"}; Arrays.sort(strings, 0, 3); assertTrue(Arrays.equals(strings, new String[]{"a", "d", "z", "b"}));
對于基本類型,一樣可以進行排序,并不需要使用封裝類:
//Arrays.sort對基本類型排序 int[] nums = {3, 1, 20, 2, 38, 2, 94}; Arrays.sort(nums); assertTrue(Arrays.equals(nums, new int[]{1, 2, 2, 3, 20, 38, 94}));
還能多線程進行排序,其實是拆分成多個子數(shù)組再進行排序,最終再合并結(jié)果。
//Arrays.parallelSort多線程排序 nums = new int[]{3, 1, 20, 2, 38, 2, 94}; Arrays.parallelSort(nums); assertTrue(Arrays.equals(nums, new int[]{1, 2, 2, 3, 20, 38, 94}));
對于沒有實現(xiàn)Comparable的類也可以使用,但需要提供Comparator來指定比較策略。 本文的沒有實現(xiàn)Comparable接口的類Person如下:
import lombok.AllArgsConstructor; import lombok.Data; @Data @AllArgsConstructor public class Person { private String name; private int age; }
排序:
//Arrays.sort提供Comparator進行排序 Person[] persons = new Person[]{ new Person("Larry", 18), new Person("David", 30), new Person("James", 20), new Person("Harry", 18)}; Arrays.sort(persons, Comparator.comparingInt(Person::getAge)); assertTrue(Arrays.equals(persons, new Person[]{ new Person("Larry", 18), new Person("Harry", 18), new Person("James", 20), new Person("David", 30)}));
JDK的Collections工具類提供了排序方法,可以方便使用。 對于實現(xiàn)Comparable的類進行排序:
//Collections.sort對于實現(xiàn)Comparable的類進行排序 List<String> names = asList("Larry", "Harry", "James", "David"); Collections.sort(names); assertEquals(names, asList("David", "Harry", "James", "Larry"));
提供Comparator進行排序:
//Collections.sort提供Comparator進行排序 List<Person> persons2 = asList( new Person("Larry", 18), new Person("David", 30), new Person("James", 20), new Person("Harry", 18)); Collections.sort(persons2, Comparator.comparingInt(Person::getAge)); assertEquals(persons2, asList( new Person("Larry", 18), new Person("Harry", 18), new Person("James", 20), new Person("David", 30)));
反序:只是把List反過來,并不代表一定是按照大小順序的:
//Collections.reverse反序 names = asList("Larry", "Harry", "James", "David"); Collections.reverse(names); assertEquals(names, asList("David", "James", "Harry", "Larry"));
List接口有sort(Comparator<? super E> c)方法,可以實現(xiàn)對自身的排序,會影響自身的順序。
//List.sort排序 names = asList("Larry", "Harry", "James", "David"); names.sort(Comparator.naturalOrder()); assertEquals(names, asList("David", "Harry", "James", "Larry"));
Stream提供了sorted()和sorted(Comparator<? super T> comparator)進行排序,會返回一個新的Stream。
//Stream.sorted排序 names = asList("Larry", "Harry", "James", "David"); List<String> result = names.stream() .sorted() .collect(Collectors.toList()); assertEquals(result, asList("David", "Harry", "James", "Larry")); //Stream.sorted提供Comparator排序 names = asList("Larry", "Harry", "James", "David"); result = names.stream() .sorted(Comparator.naturalOrder()) .collect(Collectors.toList()); assertEquals(result, asList("David", "Harry", "James", "Larry"));
對類的單字段進行排序很簡單,只要提供形如:
Comparator.comparing(類名::屬性getter)
的Comparator就行了。如果需要倒序,就需要:
Comparator.comparing(類名::屬性getter).reversed()
或Comparator.comparing(類名::屬性getter, Comparator.reverseOrder())。
具體代碼使用(為了不破壞List的原有順序,我們都使用Stream來操作):
//單字段排序-升序 List<Person> personList = asList( new Person("Larry", 18), new Person("David", 30), new Person("David", 3), new Person("James", 20), new Person("Harry", 18)); List<Person> personResult = personList.stream() .sorted(Comparator.comparing(Person::getName)) .collect(Collectors.toList()); assertEquals(personResult, asList( new Person("David", 30), new Person("David", 3), new Person("Harry", 18), new Person("James", 20), new Person("Larry", 18))); //單字段排序-倒序1 personResult = personList.stream() .sorted(Comparator.comparing(Person::getName).reversed()) .collect(Collectors.toList()); assertEquals(personResult, asList( new Person("Larry", 18), new Person("James", 20), new Person("Harry", 18), new Person("David", 30), new Person("David", 3))); //單字段排序-倒序2 personResult = personList.stream() .sorted(Comparator.comparing(Person::getName, Comparator.reverseOrder())) .collect(Collectors.toList()); assertEquals(personResult, asList( new Person("Larry", 18), new Person("James", 20), new Person("Harry", 18), new Person("David", 30), new Person("David", 3)));
多字段其實也很方便,只需要用thenComparing進行連接就可以: Comparator.comparing(類名::屬性一getter).thenComparing(類名::屬性二getter) 具體代碼使用例子如下:
//多字段排序-1升2升 personResult = personList.stream() .sorted(Comparator.comparing(Person::getName) .thenComparing(Person::getAge)) .collect(Collectors.toList()); assertEquals(personResult, asList( new Person("David", 3), new Person("David", 30), new Person("Harry", 18), new Person("James", 20), new Person("Larry", 18))); //多字段排序-1升2倒 personResult = personList.stream() .sorted(Comparator.comparing(Person::getName) .thenComparing(Person::getAge, Comparator.reverseOrder())) .collect(Collectors.toList()); assertEquals(personResult, asList( new Person("David", 30), new Person("David", 3), new Person("Harry", 18), new Person("James", 20), new Person("Larry", 18))); //多字段排序-1倒2升 personResult = personList.stream() .sorted(Comparator.comparing(Person::getName, Comparator.reverseOrder()) .thenComparing(Person::getAge)) .collect(Collectors.toList()); assertEquals(personResult, asList( new Person("Larry", 18), new Person("James", 20), new Person("Harry", 18), new Person("David", 3), new Person("David", 30))); //多字段排序-1倒2倒 personResult = personList.stream() .sorted(Comparator.comparing(Person::getName, Comparator.reverseOrder()) .thenComparing(Person::getAge, Comparator.reverseOrder())) .collect(Collectors.toList()); assertEquals(personResult, asList( new Person("Larry", 18), new Person("James", 20), new Person("Harry", 18), new Person("David", 30), new Person("David", 3)));
感謝各位的閱讀,以上就是“Java中Sorting知識點有哪些”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對Java中Sorting知識點有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
網(wǎng)頁題目:Java中Sorting知識點有哪些
轉(zhuǎn)載來于:http://bm7419.com/article46/jciehg.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、虛擬主機、、網(wǎng)站內(nèi)鏈、網(wǎng)站制作、網(wǎng)頁設計公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)