Java数组排序

排序的基本概念与重要性

排序是将一组无序数据按照特定顺序(通常是升序或降序)重新排列的过程。

经典排序算法:冒泡排序

冒泡排序是一种简单直观的排序算法,其核心思想是通过重复比较相邻元素并交换位置,使较大的元素逐渐"浮"到数组末尾。

冒泡排序的实现原理

  1. 从数组头部开始,依次比较相邻的两个元素
  2. 如果前一个元素大于后一个元素,交换它们的位置
  3. 完成一轮比较后,最大的元素会移动到数组末尾
  4. 忽略已排好序的末尾元素,对剩余元素重复上述过程
  5. 直到所有元素都排好序

代码实现:升序排列

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](同样被修改)

这是因为数组是引用类型,originalcopy指向内存中的同一个数组对象。

对字符串数组排序

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.数组排序的更多相关文章

  1. Java数组操作的10大方法

    转载自码农网 译文链接:http://www.codeceo.com/article/10-java-array-method.html 英文原文:Top 10 Methods for Java Ar ...

  2. 菜鸡的Java笔记 实践 - java 数组操作

    讲解一个继承的实现思路                要求定义一个数组操作类(Array类),在这个类里面可以进行整型数组的操作,由外部传入数组的大小        ,并且要求实现数据的保存以及数据的 ...

  3. Java数组操作十大方法 (转)

    定义一个Java数组 String[] aArray = new String[5]; String[] bArray = {"a","b","c&q ...

  4. Java数组操作利器:Arrays工具类

    java.util.Arrays提供大量的工具方法来操作数组,这些方法全是静态方法. 1 便捷创建List public static <T> List<T> asList(T ...

  5. Java 数组操作

    参考了网上别人的代码,在Java中对数组的比较便利的操作是 将数组转换成集合再利用集合所提供的add remove等方法进行增删,然后再转换成原数组类型 如 String[] --> 填充至 A ...

  6. java数组操作

    @Bizlet("数据对象扩展运算逻辑")public class DataObjectExt { private DataObjectExt(){ //工具类不能实例化 } /* ...

  7. java——数组操作

    排序.二分查找.复制数组.填充 package follow_pack; import java.util.Arrays; import java.text.DecimalFormat; public ...

  8. 廖雪峰Java1-4数组操作-2数组排序

    冒泡排序法 将第一个值和后面的值,挨个比较,如果手里的值比序列的值小,就交换数据,拿新的数字继续比较,直到最后. 再将第二个值和后面的值,挨个比较. 循环往复,排序完成. int[] ns = {28 ...

  9. Java数组操作类

    最近又重新在看慕课网的数据结构,然后把示例代码整理一下. public class Array<E> { private E[] data; private int count = 0; ...

  10. Java数组操作方法收集(快速判断某个值在这个数组中)

    Java数组操作最高效的方式是循环取值,如果转换成集合那么就会分配内存,效率不如前者,但是方法多,需要在性能调优上去权衡.切记:数组是数组,集合是集合. 下面是收集最常用的数组转成集合的操作方法: i ...

随机推荐

  1. 【Java】汉字转拼音

    将汉字转成拼音及汉字首字母,可以使用jar包 pingyin4j,但是遇到多音节汉字就会有问题.如果使用大名鼎鼎的jpinyin,可以自动识别常见多音字,而且还支持简体转换为繁体,检查是简体还是繁体, ...

  2. 聊聊常见的几款Agent平台:字节Coze、腾讯元器、文心智能体

    你好,小钗在医疗AI.教育AI.管理AI有丰富的经验 关注公众号,回复1,与我交个朋友吧 之前我们探讨过公司AI能力的评判方式: 这里主要涉及两个方面:工程能力以及行业KnowHow. 对于一般公司, ...

  3. Kubernetes数据存储-本地存储

    简单存储 EmptyDir EmptyDir是最基础的Volume类型,一个EmptyDir就是Host上的一个空目录. EmptyDir是在Pod被分配到Node时创建的,它的初始内容为空,并且无须 ...

  4. 现在的AI工具还能写剧本杀了?

    本文由 ChatMoney团队出品 近年来,剧本杀作为一种新兴社交游戏,收到了越来越多人的喜爱,它不仅需要玩家们发挥自身演技,还需运用逻辑思维推理,分析所获得的线索,找出案件真凶.然而你是否想过,你在 ...

  5. Maven 打包时,提示 java: 程序包com.sun.xml.internal.ws.fault 不存在 和 javax.crypto 不存在

    报错原因: Maven 打包时,不会导入 JDK 内部的依赖( JDK 属于部署的环境,不属于外部的三方依赖: 解决办法: 在pom.xml 文件中,添加如下 plugin 插件: <plugi ...

  6. 数栈UI5.0设计实战|B端表单这样设计,不仅美观还提效

    表单是B端产品中最常见的组件之一,主要⽤于数据收集.校验和提交.比如登陆流程的账号密码填写,注册流程的邮箱.用户名等信息填写,都是表单应用的常见案例,在数栈产品中也是出现频率⾮常⾼的组件. 尽管表单应 ...

  7. 巧用指标平台DataIndex,五步法轻松实现指标管理

    开发部门在做指标加工的全流程中,是否经常出现如下问题: · 业务部门看指标数据的时候,看到两个名称相似的指标,不清楚两个指标的差异性,来咨询开发部门指标计算口径,开发部门配合业务部门翻找代码,找出指标 ...

  8. veRL代码阅读-2.Ray

    看VeRL代码之前发现代码里主要使用了ray框架来进行调度和通信. 所以先对ray进行初步学习, 后续有空闲时间再细看下Ray的代码. 框架原理 构成 架构图如下, ray里主要分为系统层面的laye ...

  9. 我们开源的AI产品pandawiki 火了……

    大家好,经过一个月的内测,我们刚刚开源了一款 AI 驱动的 Wiki 项目,叫做 PandaWiki. GitHub 链接:https://github.com/chaitin/PandaWiki 项 ...

  10. ceph mgr balancer模块执行流程与配置方案

    随着OSD的更替和集群的扩缩容,PG在OSD的分布会逐渐变的不均衡,导致各OSD的实际容量使用率出现差异,集群整体使用率降低.ceph balancer模块就是通过调整权重或者upmap指定pg映射来 ...