Arrays.sort的用法

Arrays.sort用法 package test; import java.util.Arrays; import java.util.Comparator; public class ArraySortDemo { /** * 整数型数组排序 */ public void sortIntArray() { int[] arrayToSort = new int[] { 48, 5, 89, 80, 81, 23, 45, 16, 2 }; System.out.println("整数型数组排序,排序前:"); for (int i = 0; i < arrayToSort.length; i++){ System.out.print(arrayToSort[i]+","); } // 调用数组的静态排序方法sort Arrays.sort(arrayToSort); System.out.println(); System.out.println("排序后:"); for (int i = 0; i < arrayToSort.length; i++){ System.out.print(arrayToSort[i]+","); } } /** * 字符型数组排序demo */ public void sortStringArray() { String[] arrayToSort = new String[] { "Oscar", "Charlie", "Ryan", "Adam", "David","aff","Aff" }; System.out.println(); System.out.println("字符型数组排序,排序前:"); for (int i = 0; i < arrayToSort.length; i++){ System.out.print(arrayToSort[i]+","); } System.out.println(); System.out.println("排序后:"); // 调用数组的静态排序方法sort Arrays.sort(arrayToSort); for (int i = 0; i < arrayToSort.length; i++){ System.out.print(arrayToSort[i]+","); } } /** * 对象数组排序demo */ public void sortObjectArray() { Dog o1 = new Dog("dog1", 1); Dog o2 = new Dog("dog2", 4); Dog o3 = new Dog("dog3", 5); Dog o4 = new Dog("dog4", 2); Dog o5 = new Dog("dog5", 3); Dog[] dogs = new Dog[] { o1, o2, o3, o4, o5 }; System.out.println(); System.out.println("对象数组排序排序前:"); for (int i = 0; i < dogs.length; i++) { Dog dog = dogs[i]; System.out.print(dog.getName()+"["+dog.getWeight()+"],"); } Arrays.sort(dogs, new ByWeightComparator()); System.out.println(); System.out.println("排序后:"); for (int i = 0; i < dogs.length; i++) { Dog dog = dogs[i]; System.out.print(dog.getName()+"["+dog.getWeight()+"],"); } } public static void main(String[] args) { ArraySortDemo t = new ArraySortDemo(); t.sortIntArray(); t.sortStringArray(); t.sortObjectArray(); } } /** * 定义了一个Dog类 */ class Dog { private String name; private int weight; public Dog(String name, int weight) { this.setName(name); this.weight = weight; } public int getWeight() { return weight; } public void setWeight(int weight) { this.weight = weight; } public void setName(String name) { this.name = name; } public String getName() { return name; } } /** * 因为要对对象进行排序,所以要实现java.util.Comparator接口的compare(T o1, T o2)方法,在该方法中自定义排序算法。 */ class ByWeightComparator implements Comparator { public final int compare(Object pFirst, Object pSecond) { int aFirstWeight = ((Dog) pFirst).getWeight(); int aSecondWeight = ((Dog) pSecond).getWeight(); int diff = aFirstWeight - aSecondWeight; if (diff > 0) return 1; if (diff < 0) return -1; else return 0; } } 运行结果: 整数型数组排序,排序前: 48,5,89,80,81,23,45,16,2, 排序后: 2,5,16,23,45,48,80,81,89, 字符型数组排序,排序前: Oscar,Charlie,Ryan,Adam,David,aff,Aff, 排序后: Adam,Aff,Charlie,David,Oscar,Ryan,aff, 对象数组排序排序前: dog1[1],dog2[4],dog3[5],dog4[2],dog5[3], 排序后: dog1[1],dog4[2],dog5[3],dog2[4],dog3[5], 地方 List list = new ArrayList() ; list.add("abcd") ; list.add("abdc") ; list.add("aadf") ; list.add("aabf") ; /*将list转为数组*/ String[] strs = new String[list.size()] ; list.toArray(strs) ; /*排序,只排2<=索引<4之间的数据*/ Arrays.sort(strs,2,4) ; for(String str : strs){ System.out.println(str) ; }

<think>我们正在讨论Java中的Arrays.sort方法。根据用户需求,需要介绍其使用方法和原理,并参考提供的引用内容。 引用内容摘要: [^1]: 介绍了Arrays.sort()方法的使用场景、定义等,但标题是"Java实战入门:深入解析Java中的 `Arrays.sort()` 方法",说明它可能是关于Arrays.sort的详细解析。 [^2]: 提到Arrays.sort()和Collections.sort()的底层原理,指出基本类型数组和对象数组的排序方式不同,基本类型用快速排序的变体,对象用归并排序(但注意,实际在Java中,对象数组排序在早期版本是归并,后来改为TimSort)。 [^3]: 明确说明不论是Collections.sort方法或者是Arrays.sort方法,底层实现都是TimSort实现的(这是jdk1.7新增的),以前是归并排序。并解释了TimSort算法的基本思想:找到已经排好序数据的子序列(run),然后对剩余部分排序,再合并。 [^4]: 提到Arrays.sort()对快速排序的优化,特别是处理相等元素的优化(使得相等的元素能够放在附近,从而减少不必要的交换)。 [^5]: 列举了Collections类中的其他方法(如混排、反转等),但并没有直接关于Arrays.sort原理的更多信息。 因此,我们可以组织答案如下: 1. 方法定义和使用场景: 根据[^1],Arrays.sort()用于对数组排序,支持基本数据类型数组和对象数组。 2. 使用方法: 基本数据类型数组:直接使用Arrays.sort(数组) 对象数组:需要对象实现Comparable接口,或者提供Comparator 3. 实现原理(重点): 根据[^2][^3][^4]: - 对于基本数据类型数组:使用双轴快速排序(Dual-Pivot Quicksort),这是对经典快速排序的优化,由Vladimir Yaroslavskiy在2009年提出。它使用两个基准元素将数组分成三部分,然后递归排序。这种算法在大多数情况下比传统单轴快速排序更快,特别是对于大量数据。同时,它也对连续相等元素做了优化(避免不必要的交换)[^4]。 - 对于对象数组:使用TimSort算法(从Java 7开始)。TimSort是一种归并排序和插入排序的混合排序算法,它利用了数据中已存在的有序片段(称为run),然后合并这些run。TimSort是稳定的排序算法(即相等元素的相对顺序不变)。 4. 示例代码: 分别展示基本类型数组和对象数组的排序。 5. 注意事项: - 对象数组排序时,如果没有实现Comparable接口,则必须在调用时提供Comparator,否则会抛出ClassCastException。 - 排序会直接修改原数组(原地排序)。 - 对于基本类型数组,排序算法是非稳定的,但对于对象数组,排序是稳定的(因为使用TimSort)。 6. Collections.sort()的关系: 根据[^2][^3],Collections.sort()底层也是调用Arrays.sort(),但是它是针对List接口的,内部会先将列表转换为数组,然后使用Arrays.sort()排序,最后将排序后的数组复制回列表。 7. 性能分析: - 时间复杂度:平均为$O(n \log n)$,最坏情况下,快速排序为$O(n^2)$,但双轴快速排序在实现中通过多种技巧(如小数组用插入排序、选择好的基准等)减少了最坏情况发生的概率。TimSort的最坏时间复杂度也是$O(n \log n)$,最好情况(已经有序)是$O(n)$。 - 空间复杂度:双轴快速排序是$O(\log n)$(递归栈),TimSort是$O(n)$(因为归并排序需要额外的空间)。 根据以上思路,我们组织答案。 </think>### Java中`Arrays.sort()`方法解析 `Arrays.sort()`是Java中用于数组排序的核心方法,支持基本类型数组和对象数组的高效排序。以下从使用方法和底层原理两方面深入解析。 --- #### 一、使用方法 ##### 1. **基本类型数组排序** 直接调用`Arrays.sort()`,默认升序排序: ```java int[] numbers = {5, 2, 9, 1}; Arrays.sort(numbers); // 原地排序,结果为[1, 2, 5, 9] ``` - **支持类型**:`int[]`、`double[]`、`char[]`等基本类型数组[^1]。 ##### 2. **对象数组排序** 对象数组需满足以下条件之一: - **实现`Comparable`接口**: ```java class Person implements Comparable<Person> { String name; int age; // 实现compareTo方法定义自然顺序 @Override public int compareTo(Person other) { return Integer.compare(this.age, other.age); } } Person[] people = new Person[]{...}; Arrays.sort(people); // 按年龄升序 ``` - **提供`Comparator`**: ```java Arrays.sort(people, Comparator.comparing(Person::getName)); // 按姓名排序 Arrays.sort(people, Comparator.comparingInt(Person::getAge).reversed() // 按年龄降序 ); ``` ⚠️ **未实现`Comparable`且未提供`Comparator`会抛出`ClassCastException`**[^1][^2]。 ##### 3. **部分排序** 对数组指定区间排序: ```java int[] arr = {7, 3, 8, 2, 5}; Arrays.sort(arr, 1, 4); // 对索引[1,4)排序 → [7, 2, 3, 8, 5] ``` --- #### 二、底层原理 根据数组类型选择不同算法: ##### 1. **基本类型数组:双轴快速排序(Dual-Pivot Quicksort)** - **核心思想**:使用两个基准值(pivot)将数组分为三部分: $$ \text{左侧} < \text{Pivot1} \leq \text{中间} < \text{Pivot2} \leq \text{右侧} $$ 递归处理子数组[^2][^4]。 - **优化点**: - 小数组(长度<47)转插入排序减少递归开销 - 处理连续相等元素时减少交换次数[^4] - **时间复杂度**: - 平均:$O(n \log n)$ - 最坏:$O(n^2)$(概率极低) ##### 2. **对象数组:TimSort算法** - **核心思想**:归并排序 + 插入排序优化[^3]: 1. **寻找有序子序列(Run)**:扫描数组识别升序/降序片段 2. **插入排序优化**:短序列(长度<32)用二分插入排序 3. **归并合并**:按规则合并相邻有序子序列 - **优势**: - 稳定排序(相等元素顺序不变) - 对部分有序数据效率接近$O(n)$[^3] - **时间复杂度**:最坏$O(n \log n)$ --- #### 三、关键注意事项 1. **原地排序**:直接修改原数组,无返回值[^1][^2]。 2. **稳定性差异**: - 对象数组排序**稳定**(TimSort特性) - 基本类型数组排序**非稳定** 3. **性能对比**: | 场景 | 推荐方法 | 原因 | |-------------------|-------------------|--------------------------| | 基本类型大数组 | `Arrays.sort()` | 双轴快排缓存命中率高 | | 对象数组/链式排序 | `Collections.sort()` | 底层调用`Arrays.sort()` | [^2][^5] --- #### 四、示例场景 ```java // 混合排序:先按姓名升序,再按年龄降序 Arrays.sort(people, Comparator.comparing(Person::getName) .thenComparing(Comparator.comparingInt(Person::getAge).reversed()) ); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值