最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文詳解Java Stream的sorted自定義排序

 更新時間:2025年06月22日 11:23:10   作者:潛意識Java  
Java stream中的sorted方法是用于對流中的元素進(jìn)行排序的方法,它可以接受一個comparator參數(shù),用于指定排序規(guī)則,sorted方法返回一個新的流,其中的元素按照指定的排序規(guī)則進(jìn)行排序,本文給大家詳細(xì)介紹了Java Stream的sorted自定義排序,需要的朋友可以參考下

一、sorted 操作的基礎(chǔ)原理

Java Stream 的sorted()方法用于對流中的元素進(jìn)行排序,分為兩種形式:

  • 自然排序:要求元素實現(xiàn)Comparable接口,調(diào)用Stream.sorted()
  • 自定義排序:通過Comparator指定排序規(guī)則,調(diào)用Stream.sorted(Comparator)

核心特性

  • 有狀態(tài)操作:需緩存所有元素才能進(jìn)行排序
  • 穩(wěn)定性:默認(rèn)使用 TimSort 算法(歸并排序變體),保證穩(wěn)定排序
  • 并行流優(yōu)化:并行流使用多線程分治策略提升性能
// 自然排序示例
List<Integer> numbers = Arrays.asList(5, 3, 4, 1, 2);
List<Integer> sorted = numbers.stream()
    .sorted()  // 依賴Integer實現(xiàn)的Comparable接口
    .collect(Collectors.toList());  // [1, 2, 3, 4, 5]
 
// 自定義排序示例
List<String> words = Arrays.asList("apple", "Banana", "cherry");
List<String> caseInsensitive = words.stream()
    .sorted(String.CASE_INSENSITIVE_ORDER)  // 忽略大小寫排序
    .collect(Collectors.toList());  // [apple, Banana, cherry]

二、自定義排序的實現(xiàn)方式

1. Comparator 接口的 Lambda 實現(xiàn)

通過Comparator.comparing工廠方法簡化實現(xiàn):

// 按字符串長度排序
List<String> words = Arrays.asList("apple", "grape", "banana");
words.stream()
    .sorted(Comparator.comparing(String::length))
    .forEach(System.out::println);  // apple → grape → banana
 
// 復(fù)雜對象多字段排序(先按年齡降序,再按姓名升序)
List<User> users = Arrays.asList(
    new User("Alice", 25),
    new User("Bob", 20),
    new User("Charlie", 25)
);
users.stream()
    .sorted(Comparator.comparingInt(User::getAge).reversed()
        .thenComparing(User::getName))
    .forEach(u -> System.out.printf("%s: %d%n", u.getName(), u.getAge()));
/* 輸出:
Alice: 25
Charlie: 25
Bob: 20
*/

2. 傳統(tǒng) Comparator 實現(xiàn)類

適用于復(fù)雜排序邏輯復(fù)用:

class UserAgeComparator implements Comparator<User> {
    @Override
    public int compare(User u1, User u2) {
        return Integer.compare(u1.getAge(), u2.getAge());
    }
}
 
// 使用自定義Comparator
users.stream()
    .sorted(new UserAgeComparator())
    .collect(Collectors.toList());

3. null 值處理

使用Comparator.nullsFirst()nullsLast()

List<String> wordsWithNulls = Arrays.asList("apple", null, "banana");
wordsWithNulls.stream()
    .sorted(Comparator.nullsLast(String::compareTo))
    .forEach(System.out::println);  // null → apple → banana

三、性能優(yōu)化策略

1. 預(yù)排序與懶排序

對已排序的數(shù)據(jù)源,避免重復(fù)排序:

// 反例:對有序集合重復(fù)排序
List<Integer> sortedNumbers = Arrays.asList(1, 2, 3, 4, 5);
sortedNumbers.stream()
    .sorted()  // 不必要的排序操作
    .collect(Collectors.toList());
 
// 優(yōu)化:確保數(shù)據(jù)源有序后直接處理

2. 基礎(chǔ)類型流避免裝箱

對大量數(shù)據(jù),使用IntStream/LongStream減少裝箱開銷:

// 低效:對象流裝箱
List<Integer> boxedResult = numbers.stream()
    .sorted()
    .collect(Collectors.toList());
 
// 高效:IntStream直接排序
int[] primitiveResult = numbers.stream()
    .mapToInt(Integer::intValue)
    .sorted()
    .toArray();

3. 并行流排序的分治策略

并行流排序采用平衡二叉樹分治算法:

// 并行流排序示例
List<Integer> largeData = IntStream.range(0, 1000000)
    .boxed()
    .collect(Collectors.toList());
 
List<Integer> sortedParallel = largeData.parallelStream()
    .sorted()
    .collect(Collectors.toList());

性能對比(數(shù)據(jù)來源:JMH 基準(zhǔn)測試):

數(shù)據(jù)規(guī)模順序流排序時間并行流排序時間加速比
1 萬元素1.2ms1.8ms0.67x
100 萬元素120ms75ms1.6x
1000 萬元素1.2s0.5s2.4x

四、特殊場景處理

1. 局部排序(Top-K 問題)

對大數(shù)據(jù)集取 Top-K,使用PriorityQueue替代全局排序:

// 傳統(tǒng)排序:O(n log n)
List<Integer> topKTraditional = numbers.stream()
    .sorted(Comparator.reverseOrder())
    .limit(10)
    .collect(Collectors.toList());
 
// 優(yōu)化:O(n log k)
PriorityQueue<Integer> heap = new PriorityQueue<>(10);
numbers.forEach(n -> {
    if (heap.size() < 10 || n > heap.peek()) {
        heap.offer(n);
        if (heap.size() > 10) heap.poll();
    }
});
List<Integer> topKOptimized = new ArrayList<>(heap);
Collections.sort(topKOptimized, Collections.reverseOrder());

2. 自定義復(fù)雜排序邏輯

通過Comparator.thenComparing()組合多個排序條件:

// 按用戶年齡、性別、姓名排序
users.stream()
    .sorted(Comparator.comparingInt(User::getAge)
        .thenComparing(User::getGender)
        .thenComparing(User::getName))
    .collect(Collectors.toList());

3. 對象屬性為 Optional 的排序

處理可能為空的屬性:

class User {
    private Optional<Integer> age;
    // getter省略
}
 
// 按年齡排序,空值放最后
users.stream()
    .sorted(Comparator.comparing(
        u -> u.getAge().orElse(Integer.MAX_VALUE)
    ))
    .collect(Collectors.toList());

五、常見誤區(qū)與避坑指南

錯誤使用非線程安全的 Comparator

// 錯誤:在并行流中使用非線程安全的Comparator
Comparator<String> unsafeComparator = new Comparator<String>() {
    private Collator collator = Collator.getInstance(Locale.CHINA);
    @Override
    public int compare(String s1, String s2) {
        return collator.compare(s1, s2);  // Collator非線程安全
    }
};
words.parallelStream().sorted(unsafeComparator);  // 可能拋出異常
 
// 正確:每次創(chuàng)建新的Comparator實例
words.parallelStream().sorted((s1, s2) -> 
    Collator.getInstance(Locale.CHINA).compare(s1, s2)
);

忽略排序的穩(wěn)定性

// 錯誤假設(shè):認(rèn)為所有排序都是穩(wěn)定的
List<User> users = Arrays.asList(
    new User("Alice", 25),
    new User("Bob", 25)
);
// 兩次排序可能導(dǎo)致順序不一致(非穩(wěn)定排序算法)
users.stream()
    .sorted(Comparator.comparingInt(User::getAge))
    .collect(Collectors.toList());

過度使用 sorted 導(dǎo)致性能下降

// 反例:多次排序操作
users.stream()
    .sorted(Comparator.comparingInt(User::getAge))
    .filter(u -> u.getAge() > 18)
    .sorted(Comparator.comparing(User::getName))
    .collect(Collectors.toList());
 
// 優(yōu)化:合并排序條件,減少排序次數(shù)
users.stream()
    .filter(u -> u.getAge() > 18)
    .sorted(Comparator.comparingInt(User::getAge)
        .thenComparing(User::getName))
    .collect(Collectors.toList());

六、性能調(diào)優(yōu)實戰(zhàn)

對 100 萬隨機(jī)整數(shù)排序的性能對比(單位:ms):

排序方式耗時內(nèi)存占用備注
傳統(tǒng) Collections.sort ()15080MB需完整集合加載
Stream.sorted()18095MB中間操作,延遲執(zhí)行
IntStream.sorted()10060MB避免裝箱
并行 IntStream.sorted ()65120MB多核 CPU 加速

總結(jié)

Java Stream 的sorted操作提供了靈活的自定義排序能力,但使用時需注意:

  • 基礎(chǔ)實現(xiàn):通過Comparator接口定義排序規(guī)則,支持鏈?zhǔn)浇M合;
  • 性能優(yōu)化:優(yōu)先使用基礎(chǔ)類型流,合理選擇并行流,避免重復(fù)排序;
  • 特殊場景:處理 null 值、局部排序、Optional 屬性時需定制邏輯;
  • 避坑指南:注意排序穩(wěn)定性、線程安全及內(nèi)存占用。

理解排序操作的底層實現(xiàn)(TimSort 算法)和性能特性,能幫助開發(fā)者在實際應(yīng)用中做出更優(yōu)選擇。在處理大規(guī)模數(shù)據(jù)時,建議結(jié)合數(shù)據(jù)特性(如有序度)和硬件環(huán)境(如 CPU 核心數(shù))進(jìn)行針對性優(yōu)化,以達(dá)到最佳性能。

以上就是一文詳解Java Stream的sorted自定義排序的詳細(xì)內(nèi)容,更多關(guān)于Java Stream sorted自定義排序的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java中的HashMap弱引用之WeakHashMap詳解

    Java中的HashMap弱引用之WeakHashMap詳解

    這篇文章主要介紹了Java中的HashMap弱引用之WeakHashMap詳解,當(dāng)內(nèi)存空間不足,Java虛擬機(jī)寧愿拋出OutOfMemoryError錯誤,使程序異常終止,也不會靠隨意回收具有強(qiáng)引用的對象來解決內(nèi)存不足的問題,需要的朋友可以參考下
    2023-09-09
  • 使用監(jiān)聽器對Spring bean id進(jìn)行唯一校驗過程解析

    使用監(jiān)聽器對Spring bean id進(jìn)行唯一校驗過程解析

    這篇文章主要介紹了使用監(jiān)聽器對Spring bean id進(jìn)行唯一校驗過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-08-08
  • Mybatis-plus配置多數(shù)據(jù)源,連接多數(shù)據(jù)庫方式

    Mybatis-plus配置多數(shù)據(jù)源,連接多數(shù)據(jù)庫方式

    這篇文章主要介紹了Mybatis-plus配置多數(shù)據(jù)源,連接多數(shù)據(jù)庫方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • SimpleDateFormat格式化日期問題

    SimpleDateFormat格式化日期問題

    這篇文章主要介紹了SimpleDateFormat格式化日期問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • java方法重寫和super關(guān)鍵字實例詳解

    java方法重寫和super關(guān)鍵字實例詳解

    這篇文章主要介紹了java方法重寫和super關(guān)鍵字實例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • 詳解Java分布式IP限流和防止惡意IP攻擊方案

    詳解Java分布式IP限流和防止惡意IP攻擊方案

    這篇文章主要介紹了詳解Java分布式IP限流和防止惡意IP攻擊方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • java中request常用方法小結(jié)

    java中request常用方法小結(jié)

    這篇文章主要介紹了java中request常用方法小結(jié),需要的朋友可以參考下
    2014-10-10
  • java 使用異常的好處總結(jié)

    java 使用異常的好處總結(jié)

    這篇文章主要介紹了java 使用異常的好處總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • intellij idea使用git stash暫存一次提交的操作

    intellij idea使用git stash暫存一次提交的操作

    這篇文章主要介紹了intellij idea使用git stash暫存一次提交的操作,具有很好的參考價值希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Java開發(fā)深入分析講解二叉樹的遞歸和非遞歸遍歷方法

    Java開發(fā)深入分析講解二叉樹的遞歸和非遞歸遍歷方法

    樹是一種重要的非線性數(shù)據(jù)結(jié)構(gòu),直觀地看,它是數(shù)據(jù)元素(在樹中稱為結(jié)點)按分支關(guān)系組織起來的結(jié)構(gòu),很象自然界中的樹那樣。樹結(jié)構(gòu)在客觀世界中廣泛存在,如人類社會的族譜和各種社會組織機(jī)構(gòu)都可用樹形象表示,本篇介紹二叉樹的遞歸與非遞歸遍歷的方法
    2022-05-05

最新評論

盱眙县| 洛宁县| 元谋县| 建始县| 车致| 华亭县| 辽源市| 淅川县| 邢台市| 昭觉县| 嘉善县| 遵义市| 庆城县| 太原市| 平昌县| 常熟市| 永平县| 区。| 淄博市| 祥云县| 平定县| 虎林市| 澄江县| 米泉市| 前郭尔| 昌邑市| 建德市| 馆陶县| 改则县| 十堰市| 光泽县| 襄城县| 神池县| 申扎县| 大新县| 东山县| 七台河市| 越西县| 淮北市| 长春市| 陆河县|