Java数组操作——2.数组排序
Java数组排序
排序的基本概念与重要性
排序是将一组无序数据按照特定顺序(通常是升序或降序)重新排列的过程。
经典排序算法:冒泡排序
冒泡排序是一种简单直观的排序算法,其核心思想是通过重复比较相邻元素并交换位置,使较大的元素逐渐"浮"到数组末尾。
冒泡排序的实现原理
- 从数组头部开始,依次比较相邻的两个元素
- 如果前一个元素大于后一个元素,交换它们的位置
- 完成一轮比较后,最大的元素会移动到数组末尾
- 忽略已排好序的末尾元素,对剩余元素重复上述过程
- 直到所有元素都排好序
代码实现:升序排列
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args) {
int[] numbers = {28, 12, 89, 73, 65, 18, 96, 50, 8, 36};
System.out.println("排序前:" + Arrays.toString(numbers));
// 冒泡排序实现
for (int i = 0; i < numbers.length - 1; i++) {
// 每轮循环后,最大的元素已"浮"到末尾,因此减少一次比较
for (int j = 0; j < numbers.length - i - 1; j++) {
// 如果前一个元素大于后一个,交换它们
if (numbers[j] > numbers[j + 1]) {
int temp = numbers[j];
numbers[j] = numbers[j + 1];
numbers[j + 1] = temp;
}
}
}
System.out.println("排序后:" + Arrays.toString(numbers));
}
}
输出结果:
排序前:[28, 12, 89, 73, 65, 18, 96, 50, 8, 36]
排序后:[8, 12, 18, 28, 36, 50, 65, 73, 89, 96]
在排序过程中,交换两个变量的值需要借助临时变量,否则会导致数据丢失。
Java标准库的排序方法:Arrays.sort()
手动实现排序算法虽然有助于理解原理,但在实际开发中,我们更倾向于使用Java标准库提供的排序功能,因为它们通常经过优化,性能更好。
基本用法
Java的java.util.Arrays类提供了sort()方法,可以直接对数组进行排序:
import java.util.Arrays;
public class ArraysSortExample {
public static void main(String[] args) {
int[] numbers = {28, 12, 89, 73, 65, 18, 96, 50, 8, 36};
// 使用标准库排序
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers));
// 输出:[8, 12, 18, 28, 36, 50, 65, 73, 89, 96]
}
}
Arrays.sort()方法默认对数组进行升序排列,其内部使用的排序算法因数据类型而异:
- 对于基本类型数组,使用双轴快速排序(Dual-Pivot QuickSort)
- 对于对象数组,使用TimSort(归并排序的变种)
排序对数组的影响
需要注意的是,Arrays.sort()会直接修改原数组,而不是返回一个新的排序后的数组:
int[] original = {3, 1, 2};
int[] copy = original; // 引用同一个数组
Arrays.sort(original);
System.out.println(Arrays.toString(original)); // [1, 2, 3]
System.out.println(Arrays.toString(copy)); // [1, 2, 3](同样被修改)
这是因为数组是引用类型,original和copy指向内存中的同一个数组对象。
对字符串数组排序
Arrays.sort()同样适用于对象数组,如字符串数组:
import java.util.Arrays;
public class StringSortExample {
public static void main(String[] args) {
String[] fruits = {"banana", "apple", "pear", "orange"};
System.out.println("排序前:" + Arrays.toString(fruits));
Arrays.sort(fruits);
System.out.println("排序后:" + Arrays.toString(fruits));
}
}
输出结果:
排序前:[banana, apple, pear, orange]
排序后:[apple, banana, orange, pear]
字符串排序基于Unicode字符编码的字典顺序,与我们日常使用的字典排序一致。
实现降序排序
Arrays.sort()默认提供升序排序,要实现降序排序,需要额外处理:
方法1:对基本类型数组先升序再反转
import java.util.Arrays;
public class DescendingSort {
public static void main(String[] args) {
int[] numbers = {28, 12, 89, 73, 65, 18, 96, 50, 8, 36};
// 先升序排序
Arrays.sort(numbers);
// 再反转数组
for (int i = 0; i < numbers.length / 2; i++) {
int temp = numbers[i];
numbers[i] = numbers[numbers.length - 1 - i];
numbers[numbers.length - 1 - i] = temp;
}
System.out.println(Arrays.toString(numbers));
// 输出:[96, 89, 73, 65, 50, 36, 28, 18, 12, 8]
}
}
方法2:使用包装类和比较器(对象数组)
对于对象数组(包括基本类型的包装类数组),可以使用带比较器的sort()方法:
import java.util.Arrays;
import java.util.Collections;
public class DescendingSortWithComparator {
public static void main(String[] args) {
// 使用Integer包装类数组
Integer[] numbers = {28, 12, 89, 73, 65, 18, 96, 50, 8, 36};
// 使用Collections.reverseOrder()获取降序比较器
Arrays.sort(numbers, Collections.reverseOrder());
System.out.println(Arrays.toString(numbers));
// 输出:[96, 89, 73, 65, 50, 36, 28, 18, 12, 8]
}
}
这种方法更灵活,适用于需要自定义排序规则的场景。
排序算法的选择与性能
不同的排序算法在性能上有显著差异,了解它们的特点有助于选择合适的算法:
| 排序算法 | 平均时间复杂度 | 最坏时间复杂度 | 空间复杂度 | 稳定性 |
|---|---|---|---|---|
| 冒泡排序 | O(n²) | O(n²) | O(1) | 稳定 |
| 插入排序 | O(n²) | O(n²) | O(1) | 稳定 |
| 快速排序 | O(n log n) | O(n²) | O(log n) | 不稳定 |
| 归并排序 | O(n log n) | O(n log n) | O(n) | 稳定 |
| Arrays.sort()(基本类型) | O(n log n) | O(n log n) | O(log n) | 不稳定 |
在实际开发中,除非有特殊需求,否则应优先使用Java标准库的Arrays.sort()方法。
参考案例
案例1:对自定义对象数组排序
要对自定义对象数组排序,需要让对象类实现Comparable接口或提供Comparator:
import java.util.Arrays;
// 实现Comparable接口
class Student implements Comparable<Student> {
String name;
int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
// 按分数升序排序
@Override
public int compareTo(Student other) {
return this.score - other.score;
}
@Override
public String toString() {
return name + "(" + score + ")";
}
}
public class ObjectSortExample {
public static void main(String[] args) {
Student[] students = {
new Student("Alice", 85),
new Student("Bob", 75),
new Student("Charlie", 90)
};
Arrays.sort(students);
System.out.println(Arrays.toString(students));
// 输出:[Bob(75), Alice(85), Charlie(90)]
}
}
案例2:排序并去重
排序后的数据更容易进行去重操作:
import java.util.Arrays;
public class SortAndDeduplicate {
public static void main(String[] args) {
int[] numbers = {5, 3, 8, 3, 5, 1, 8};
// 先排序
Arrays.sort(numbers);
System.out.println("排序后:" + Arrays.toString(numbers));
// 去重
int index = 0;
for (int i = 1; i < numbers.length; i++) {
if (numbers[i] != numbers[index]) {
numbers[++index] = numbers[i];
}
}
// 复制去重后的结果
int[] uniqueNumbers = Arrays.copyOf(numbers, index + 1);
System.out.println("去重后:" + Arrays.toString(uniqueNumbers));
}
}
输出结果:
排序后:[1, 3, 3, 5, 5, 8, 8]
去重后:[1, 3, 5, 8]
总结
- 掌握冒泡排序
- 掌握Java标准库的
Arrays.sort()方法 - 排序会直接修改原数组(引用类型特性)
- 升序是默认排序方式,降序排序需要额外处理
Java数组操作——2.数组排序的更多相关文章
- Java数组操作的10大方法
转载自码农网 译文链接:http://www.codeceo.com/article/10-java-array-method.html 英文原文:Top 10 Methods for Java Ar ...
- 菜鸡的Java笔记 实践 - java 数组操作
讲解一个继承的实现思路 要求定义一个数组操作类(Array类),在这个类里面可以进行整型数组的操作,由外部传入数组的大小 ,并且要求实现数据的保存以及数据的 ...
- Java数组操作十大方法 (转)
定义一个Java数组 String[] aArray = new String[5]; String[] bArray = {"a","b","c&q ...
- Java数组操作利器:Arrays工具类
java.util.Arrays提供大量的工具方法来操作数组,这些方法全是静态方法. 1 便捷创建List public static <T> List<T> asList(T ...
- Java 数组操作
参考了网上别人的代码,在Java中对数组的比较便利的操作是 将数组转换成集合再利用集合所提供的add remove等方法进行增删,然后再转换成原数组类型 如 String[] --> 填充至 A ...
- java数组操作
@Bizlet("数据对象扩展运算逻辑")public class DataObjectExt { private DataObjectExt(){ //工具类不能实例化 } /* ...
- java——数组操作
排序.二分查找.复制数组.填充 package follow_pack; import java.util.Arrays; import java.text.DecimalFormat; public ...
- 廖雪峰Java1-4数组操作-2数组排序
冒泡排序法 将第一个值和后面的值,挨个比较,如果手里的值比序列的值小,就交换数据,拿新的数字继续比较,直到最后. 再将第二个值和后面的值,挨个比较. 循环往复,排序完成. int[] ns = {28 ...
- Java数组操作类
最近又重新在看慕课网的数据结构,然后把示例代码整理一下. public class Array<E> { private E[] data; private int count = 0; ...
- Java数组操作方法收集(快速判断某个值在这个数组中)
Java数组操作最高效的方式是循环取值,如果转换成集合那么就会分配内存,效率不如前者,但是方法多,需要在性能调优上去权衡.切记:数组是数组,集合是集合. 下面是收集最常用的数组转成集合的操作方法: i ...
随机推荐
- 【Java】汉字转拼音
将汉字转成拼音及汉字首字母,可以使用jar包 pingyin4j,但是遇到多音节汉字就会有问题.如果使用大名鼎鼎的jpinyin,可以自动识别常见多音字,而且还支持简体转换为繁体,检查是简体还是繁体, ...
- 聊聊常见的几款Agent平台:字节Coze、腾讯元器、文心智能体
你好,小钗在医疗AI.教育AI.管理AI有丰富的经验 关注公众号,回复1,与我交个朋友吧 之前我们探讨过公司AI能力的评判方式: 这里主要涉及两个方面:工程能力以及行业KnowHow. 对于一般公司, ...
- Kubernetes数据存储-本地存储
简单存储 EmptyDir EmptyDir是最基础的Volume类型,一个EmptyDir就是Host上的一个空目录. EmptyDir是在Pod被分配到Node时创建的,它的初始内容为空,并且无须 ...
- 现在的AI工具还能写剧本杀了?
本文由 ChatMoney团队出品 近年来,剧本杀作为一种新兴社交游戏,收到了越来越多人的喜爱,它不仅需要玩家们发挥自身演技,还需运用逻辑思维推理,分析所获得的线索,找出案件真凶.然而你是否想过,你在 ...
- Maven 打包时,提示 java: 程序包com.sun.xml.internal.ws.fault 不存在 和 javax.crypto 不存在
报错原因: Maven 打包时,不会导入 JDK 内部的依赖( JDK 属于部署的环境,不属于外部的三方依赖: 解决办法: 在pom.xml 文件中,添加如下 plugin 插件: <plugi ...
- 数栈UI5.0设计实战|B端表单这样设计,不仅美观还提效
表单是B端产品中最常见的组件之一,主要⽤于数据收集.校验和提交.比如登陆流程的账号密码填写,注册流程的邮箱.用户名等信息填写,都是表单应用的常见案例,在数栈产品中也是出现频率⾮常⾼的组件. 尽管表单应 ...
- 巧用指标平台DataIndex,五步法轻松实现指标管理
开发部门在做指标加工的全流程中,是否经常出现如下问题: · 业务部门看指标数据的时候,看到两个名称相似的指标,不清楚两个指标的差异性,来咨询开发部门指标计算口径,开发部门配合业务部门翻找代码,找出指标 ...
- veRL代码阅读-2.Ray
看VeRL代码之前发现代码里主要使用了ray框架来进行调度和通信. 所以先对ray进行初步学习, 后续有空闲时间再细看下Ray的代码. 框架原理 构成 架构图如下, ray里主要分为系统层面的laye ...
- 我们开源的AI产品pandawiki 火了……
大家好,经过一个月的内测,我们刚刚开源了一款 AI 驱动的 Wiki 项目,叫做 PandaWiki. GitHub 链接:https://github.com/chaitin/PandaWiki 项 ...
- ceph mgr balancer模块执行流程与配置方案
随着OSD的更替和集群的扩缩容,PG在OSD的分布会逐渐变的不均衡,导致各OSD的实际容量使用率出现差异,集群整体使用率降低.ceph balancer模块就是通过调整权重或者upmap指定pg映射来 ...