深入浅出Java排序:从基础算法到实战优化(下)

深入浅出Java排序:从基础算法到实战优化(下)
在这里插入图片描述

文章目录


  • 书接上回,在从基础算法到实战优化上咱们较为详细的讨论了数据结构中常见的八大排序.今天咱们来介绍一下java自带的.sort方法.

一、核心概念与底层实现

Java的排序方法遵循最佳实践,底层根据数据类型做了优化:

  • intlong基本类型数组:使用双轴快速排序(Dual-Pivot QuickSort),效率更高(时间复杂度O(n log n))。
  • String、自定义对象等引用类型:使用TimSort(归并排序+插入排序的混合算法),稳定且高效。

二、常用.sort方法用法

1. Arrays.sort()(数组排序)

适用于所有数组类型(基本类型、引用类型),默认升序排列。

示例1:基本类型数组排序(int数组)

importjava.util.Arrays;publicclassSortDemo{publicstaticvoidmain(String[] args){// 定义无序int数组int[] nums ={5,2,9,1,5,6};// 核心:数组排序(原地排序,直接修改原数组)Arrays.sort(nums);// 输出结果:[1, 2, 5, 5, 6, 9]System.out.println(Arrays.toString(nums));}}

示例2:自定义对象数组排序(实现Comparable)
如果要排序自定义对象,需让对象类实现Comparable接口,重写compareTo方法定义“自然排序规则”。

importjava.util.Arrays;// 自定义User类,实现Comparable接口classUserimplementsComparable<User>{privateString name;privateint age;publicUser(String name,int age){this.name = name;this.age = age;}// 定义排序规则:按年龄升序(this.age - o.age),降序则反过来@OverridepublicintcompareTo(User o){returnthis.age - o.age;}// 重写toString,方便打印@OverridepublicStringtoString(){return"User{name='"+ name +"', age="+ age +"}";}}publicclassObjectSortDemo{publicstaticvoidmain(String[] args){User[] users ={newUser("张三",25),newUser("李四",20),newUser("王五",30)};// 排序自定义对象数组Arrays.sort(users);// 输出结果:按年龄升序排列// [User{name='李四', age=20}, User{name='张三', age=25}, User{name='王五', age=30}]System.out.println(Arrays.toString(users));}}

示例3:自定义排序规则(Comparator)
如果不想修改对象类(比如第三方类),或需要临时自定义排序规则,可使用带Comparator的重载方法:

importjava.util.Arrays;importjava.util.Comparator;publicclassComparatorSortDemo{publicstaticvoidmain(String[] args){String[] strs ={"apple","Banana","cherry","date"};// 按字符串长度降序排序(忽略大小写)Arrays.sort(strs,newComparator<String>(){@Overridepublicintcompare(String s1,String s2){// 降序:s2长度 - s1长度int lenCompare = s2.length()- s1.length();// 长度相同则按字母序(忽略大小写)return lenCompare !=0? lenCompare : s1.compareToIgnoreCase(s2);}});// 输出:[cherry, Banana, apple, date]System.out.println(Arrays.toString(strs));}}
2. Collections.sort()(List集合排序)

专门用于List接口的实现类(如ArrayListLinkedList),用法和Arrays.sort()类似,默认升序。

示例:List集合排序(Lambda简化Comparator)
Java 8+支持Lambda表达式,可简化Comparator的写法:

importjava.util.ArrayList;importjava.util.Collections;importjava.util.List;publicclassListSortDemo{publicstaticvoidmain(String[] args){List<Integer> list =newArrayList<>(); list.add(8); list.add(2); list.add(7); list.add(1);// 方式1:默认升序Collections.sort(list);System.out.println("升序:"+ list);// [1, 2, 7, 8]// 方式2:Lambda自定义降序Collections.sort(list,(a, b)-> b - a);System.out.println("降序:"+ list);// [8, 7, 2, 1]}}

三、关键注意事项

  1. Arrays.sort()原地排序:直接修改原数组,不会返回新数组;
  2. 基本类型数组的排序是不稳定的,引用类型排序是稳定的;

Java 8+还提供了List.sort()方法(替代Collections.sort()),写法更简洁:

list.sort((a, b)-> b - a);// 等价于Collections.sort(list, ...)

总结

  1. Java的.sort核心分为Arrays.sort()(数组)和Collections.sort()(List),底层优化保证高性能;
  2. 排序规则分两种:实现Comparable定义“自然排序”,或传入Comparator实现“定制排序”;
  3. Java 8+推荐用Lambda简化Comparator,List.sort()替代Collections.sort()更简洁。

上面就是.sort的一些基本的用法,我是Dylan ,下期见~

Read more

TRE: 鼓励在Trust Rigon 进行探索

TRE: 鼓励在Trust Rigon 进行探索

机构:  百度 代码: https://github.com/WhyChaos/TRE-Encouraging-Exploration-in-the-Trust-Region Abstract 熵正则化是强化学习(RL)中提升探索能力的标准技术。然而,在大语言模型(LLMs)中,它往往效果甚微,甚至会导致性能下降。我们认为,这种失败源于大语言模型所固有的累积尾部风险(cumulative tail risk),这种风险来自其庞大的词表规模以及较长的生成序列长度。 在这样的环境下,标准的全局熵最大化会将概率质量不加区分地分散到大量处于尾部的无效 token 上,而不是集中于合理候选项,从而破坏连贯的推理过程。 为了解决这一问题,我们提出了 Trust Region Entropy(TRE) 方法。该方法鼓励模型仅在其“信任区域(trust region)”内进行探索。我们在数学推理任务(MATH)、组合搜索任务(Countdown)以及偏好对齐任务(HH)上进行了大量实验,结果表明,

By Ne0inhk
Spring MVC请求处理流程源码分析与DispatcherServlet核心逻辑

Spring MVC请求处理流程源码分析与DispatcherServlet核心逻辑

目录 🎯 先说说我遇到过的真实问题 ✨ 摘要 1. 从Tomcat到DispatcherServlet:请求的"奇幻漂流" 1.1 请求是怎么到你Controller的? 1.2 DispatcherServlet的初始化:不是你想的那样简单 2. 请求处理九大步:DispatcherServlet的"工作流程" 2.1 doDispatch方法:Spring MVC的心脏 2.2 九步流程详解:每个步骤都有坑 🚨 步骤1:Multipart检查 🚨 步骤2:获取Handler 3. HandlerMapping:请求的"导航系统" 3.1 四种HandlerMapping的区别 3.2 RequestMappingHandlerMapping的匹配算法 3.3 路径匹配的性能优化

By Ne0inhk
数字身份的通行证:深入解析单点登录(SSO)的架构与艺术

数字身份的通行证:深入解析单点登录(SSO)的架构与艺术

文章目录 * 概述 * 一、什么是单点登录(SSO)? * 二、SSO 的核心价值:为何它如此重要? * 三、SSO 的基本工作原理:一次认证,处处通行 * 场景一:首次登录应用 A * 场景二:访问应用 B(无感登录) * 四、SSO 的通用语言:常见协议与标准 * 五、SSO 架构的两种主流形态 * 1. **中心化 SSO** * 2. **联邦身份** * 六、安全:SSO 的生命线 * 七、典型应用场景:SSO 在哪里发光? * 八、快速上手:从理论到实践 * 九、常见误区澄清 * 总结 概述 在数字世界日益碎片化的今天,我们每个人都在无数应用和服务之间穿梭,

By Ne0inhk
Rust异步编程实战:构建高性能网络应用

Rust异步编程实战:构建高性能网络应用

Rust异步编程实战:构建高性能网络应用 一、异步编程概述 1.1 同步vs异步的区别 💡在传统的同步编程中,代码按照顺序执行,每个操作必须等待前一个完成才能继续。例如,发送网络请求时,主线程会阻塞直到响应返回,这种方式简单直观,但在高并发场景下效率低下,因为大量线程会因阻塞而闲置。 异步编程则允许代码在等待操作完成时继续执行其他任务。当一个异步操作开始后,程序会立即返回并继续处理下一个任务,直到该操作完成后通过回调或事件通知继续执行后续代码。这种方式显著提高了CPU利用率和系统的并发处理能力。 1.2 Rust异步编程的演进 Rust的异步编程经历了几个重要阶段: * 早期阶段:依赖futures库提供基础的Future和Executor支持,但语法冗长且难以使用。 * 2018 Edition:引入了async/await语法糖的实验版本,简化了异步代码的编写。 * 2021 Edition:async/await正式稳定,成为Rust异步编程的标准范式。 * 生态成熟:Tokio、async-std等异步运行时库的发展,以及大量异步IO库的出现,使Rus

By Ne0inhk