一、Stream排序原理
Stream是Java 8引入的全新API,它對集合進行封裝,可以對集合進行類似於SQL語句的操作。其中,sort()是stream中最常用的排序方法,它是一個中間操作,返回的是此流的排序視圖。sort()方法有兩種形式:有參形式和無參形式。在無參形式中,sort()使用自然順序進行排序;在有參形式中,sort()使用自定義比較器進行排序。
當流中的元素數量較小,排序時間較短,但流中的元素數量逐漸增加時,排序操作將花費更多的時間。這是因為排序算法的時間複雜度為O(nlogn),因此它的性能與元素數量呈對數關係,也就是說,如果元素數量增加一倍,則排序時間將增加一個單位時間。
Stream排序算法通常使用的是歸併排序,該算法的思想是將一個大的有序序列劃分為兩個較小的有序序列,然後對這兩個有序序列進行合併,得到一個更大的有序序列。在每次合併過程中,都會使用比較器對兩個有序序列進行比較,以得到更小或更大的值,最終得到一個有序序列。
二、使用Comparator進行排序
在使用Stream進行排序時,通常需要實現Comparator接口,該接口用於定義兩個對象之間的比較規則。Comparator接口是一個函數式接口,可以使用lambda表達式來實現。下面是一個例子,使用Comparator對Person對象按年齡進行排序:
List people = new ArrayList(); people.add(new Person("John", 25)); people.add(new Person("Mary", 30)); people.add(new Person("Peter", 35)); List sortedPeople = people.stream() .sorted((p1, p2) -> p1.getAge() - p2.getAge()) .collect(Collectors.toList());
在上面的例子中,sorted()方法使用一個比較器對流中的元素進行排序。這個比較器是一個lambda表達式,該表達式對兩個Person對象進行比較,返回一個整數,用於表示它們之間的順序。在本例中,比較器使用第一個Person對象的年齡減去第二個Person對象的年齡,如果結果為負數,則表示第一個Person對象的年齡小於第二個Person對象的年齡,排在前面。
三、使用自然排序進行排序
在Java中,每個類都可以實現Comparable接口,該接口定義了一個compareTo()方法,用於指定該類對象之間的自然順序。如果一個類實現了Comparable接口,它的對象就可以被自然排序。下面是一個例子,使用自然排序對字符串進行排序:
List names = Arrays.asList("John", "Mary", "Peter"); List sortedNames = names.stream().sorted().collect(Collectors.toList());
在上面的例子中,sorted()方法沒有傳遞任何比較器,因此使用自然排序對字符串進行排序。String類實現了Comparable接口,因此它的對象可以進行自然排序。
四、排序的穩定性
排序的穩定性指的是,在排序後,具有相同關鍵字的元素,其原來的相對順序沒有變化。例如,對一個包含多個人名和年齡的列表,按照年齡排序後,如果有兩個人的年齡相同,則這兩個人的名字應該按照原來的順序排列。
在Stream排序中,排序的穩定性取決於所使用的排序算法。例如,如果使用Arrays.sort()對數組進行排序,該方法使用的是快速排序,該算法不保證排序的穩定性。如果要保證排序的穩定性,可以使用歸併排序或插入排序等算法。
五、並行排序
Stream提供了parallel()方法,該方法用於將流轉換為並行流。在使用並行流進行排序時,Stream將自動對流進行拆分,將每個子流交給線程池中的線程處理,再將處理結果合併。下面是一個例子,對一個包含大量隨機數的列表進行排序:
List numbers = new Random().ints(10000000).boxed().collect(Collectors.toList()); long start = System.currentTimeMillis(); List sortedNumbers = numbers.parallelStream().sorted().collect(Collectors.toList()); long end = System.currentTimeMillis(); System.out.println("Time: " + (end - start) + "ms");
在上面的例子中,使用ints()方法生成一個包含1000萬個隨機數的列表,然後使用parallelStream()方法將其轉換為並行流。在sorted()方法之後,Stream將會對每個子流進行排序,然後將排序結果合併。在本例中,使用並行流進行排序所花費的時間要比使用順序流要少得多。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/257593.html