深入理解Arrays.sort()

2023-05-16

翻译人员: 铁锚
翻译日期: 2013年11月16日
原文链接:  Deep Understanding of Arrays.sort(T[], Comparator < ? super T > c)

Arrays.sort(T[], Comparator < ? super T > c) 方法用于对象数组按用户自定义规则排序.
官方Java文档只是简要描述此方法的作用,并未进行详细的介绍,本文将深入解析此方法。
1. 简单示例
sort方法的使用非常的简单明了,下面的例子中,先定义一个比较Dog大小的Comparator,然后将其实例对象作为参数传给sort方法,通过此示例,你应该能够快速掌握Arrays.sort()的使用方法。
import java.util.Arrays;
import java.util.Comparator;
 
class Dog{
	int size;	
	public Dog(int s){
		size = s;
	}
}
 
class DogSizeComparator implements Comparator<Dog>{
 
	@Override
	public int compare(Dog o1, Dog o2) {
		return o1.size - o2.size;
	}
}
 
public class ArraySort {
 
	public static void main(String[] args) {
		Dog d1 = new Dog(2);
		Dog d2 = new Dog(1);
		Dog d3 = new Dog(3);
 
		Dog[] dogArray = {d1, d2, d3};
		printDogs(dogArray);
 
		Arrays.sort(dogArray, new DogSizeComparator());	
		printDogs(dogArray);
	}
 
	public static void printDogs(Dog[] dogs){
		for(Dog d: dogs)
			System.out.print(d.size + " " );
 
		System.out.println();
	}
}
输出为:
2 1 3
1 2 3

2. 使用策略模式
这是策略模式( Strategy pattern)的一个完美又简洁的示例,值得一提的是为什么这种场景下适合使用策略模式.
总体来说,策略模式允许在程序执行时选择不同的算法.比如在排序时,传入不同的比较器(Comparator),就采用不同的算法.
根据上面的例子,假设你想要根据Dog的重量来进行排序,可以像下面这样,创建一个新的比较器来进行排序:
class Dog{
	int size;
	int weight;
 
	public Dog(int s, int w){
		size = s;
		weight = w; 
	}
}
 
class DogSizeComparator implements Comparator<Dog>{
 
	@Override
	public int compare(Dog o1, Dog o2) {
		return o1.size - o2.size;
	}
}
 
class DogWeightComparator implements Comparator<Dog>{
 
	@Override
	public int compare(Dog o1, Dog o2) {
		return o1.weight - o2.weight;
	}
}
 
public class ArraySort {
 
	public static void main(String[] args) {
		Dog d1 = new Dog(2, 50);
		Dog d2 = new Dog(1, 30);
		Dog d3 = new Dog(3, 40);
 
		Dog[] dogArray = {d1, d2, d3};
		printDogs(dogArray);
 
		Arrays.sort(dogArray, new DogSizeComparator());	
		printDogs(dogArray);
 
		Arrays.sort(dogArray, new DogWeightComparator());	
		printDogs(dogArray);
	}
 
	public static void printDogs(Dog[] dogs){
		for(Dog d: dogs)
			System.out.print("size="+d.size + " weight=" + d.weight + " ");
 
		System.out.println();
	}
}
执行结果:
size=2 weight=50 size=1 weight=30 size=3 weight=40
size=1 weight=30 size=2 weight=50 size=3 weight=40
size=1 weight=30 size=3 weight=40 size=2 weight=50
Comparator 是一个接口,所以sort方法中可以传入任意实现了此接口的类的实例,这就是策略模式的主要思想.

3. 为何使用"super"
如果使用 "Comparator < T > c" 那是很简单易懂的,但是sort的第2个参数里面的 < ? super T > 意味着比较器所接受的类型可以是T或者它的超类. 为什么是超类呢? 答案是: 这允许使用同一个比较器对不同的子类对象进行比较.在下面的示例中很明显地演示了这一点:
import java.util.Arrays;
import java.util.Comparator;
 
class Animal{
	int size;
}
 
class Dog extends Animal{
	public Dog(int s){
		size = s;
	}
}
 
class Cat extends Animal{
	public Cat(int s){
		size  = s;
	}
}
 
class AnimalSizeComparator implements Comparator<Animal>{
 
	@Override
	public int compare(Animal o1, Animal o2) {
		return o1.size - o2.size;
	}
	//in this way, all sub classes of Animal can use this comparator.
}
 
public class ArraySort {
 
	public static void main(String[] args) {
		Dog d1 = new Dog(2);
		Dog d2 = new Dog(1);
		Dog d3 = new Dog(3);
 
		Dog[] dogArray = {d1, d2, d3};
		printDogs(dogArray);
 
		Arrays.sort(dogArray, new AnimalSizeComparator());	
		printDogs(dogArray);
 
		System.out.println();
 
		//when you have an array of Cat, same Comparator can be used. 
		Cat c1 = new Cat(2);
		Cat c2 = new Cat(1);
		Cat c3 = new Cat(3);
 
		Cat[] catArray = {c1, c2, c3};
		printDogs(catArray);
 
		Arrays.sort(catArray, new AnimalSizeComparator());	
		printDogs(catArray);
	}
 
	public static void printDogs(Animal[] animals){
		for(Animal a: animals)
			System.out.print("size="+a.size + " ");
 
		System.out.println();
	}
}
输出结果:
size=2 size=1 size=3
size=1 size=2 size=3
size=2 size=1 size=3
size=1 size=2 size=3

4. 小结
与Arrays.sort()相关的信息总结如下:
  1. 通用: super 类
  2. 策略设计模式(strategy pattern);
  3. 归并排序(merge sort): 时间复杂度 n*log(n);
  4. Java.util.Collections#sort(List < T > list, Comparator < ? super T > c)与Arrays.sort 使用类似的思想.
参考文献:
1.  Arrays.sort(T[], java.util.Comparator)

相关阅读:

  1. Example of Sorting Arrays
  2. Java Design Pattern: Strategy
  3. Comparable vs Comparator in Java
  4. Top 10 Methods for Java Arrays

转载于:https://www.cnblogs.com/lanzhi/p/6467076.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深入理解Arrays.sort() 的相关文章

随机推荐

  • Docker Hub + Github 自动化构建docker镜像

    自动创建 xff08 Automated Builds xff09 功能对于需要经常升级镜像内程序来说 xff0c 十分方便 有时候 xff0c 用户创建了镜像 xff0c 安装了某个软件 xff0c 如果软件发布新版本则需要手动更新镜像
  • ubuntu下旋转屏幕

    2019独角兽企业重金招聘Python工程师标准 gt gt gt ubuntu下把屏幕竖起来的方法很简单 xff1a xrandr o left 向左旋转90度 xrandr o right 向右旋转90度 xrandr o invert
  • Java 如何实现线程间通信

    正常情况下 xff0c 每个子线程完成各自的任务就可以结束了 不过有的时候 xff0c 我们希望多个线程协同工作来完成某个任务 xff0c 这时就涉及到了线程间通信了 本文涉及到的知识点 xff1a thread join object w
  • rtmp拉流测试工具

    http www cutv com demo live test swf 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
  • 微信PC客户端无法发送图片,怎么解决?

    今天登陆电脑的微信客户端 xff0c 无法发送截图图片 xff0c 该怎么办 xff1f 解决方法 1 在任务栏找到程序 xff0c 右键找到设置 2 找到通用设置下的清除聊天记录 3 重启Pc微信客户端就可以 PS 本人测试过 xff0c
  • sql server 索引总结一

    一 存储结构 在SQL Server中 xff0c 有许多不同的可用排列规则选项 二进制 xff1a 按字符的数字表示形式排序 ASCII码中 xff0c 用数字32表示空格 xff0c 用68表示字母 34 D 34 因为所有内容都表示为
  • CSS 为什么这么难学?

    最近半年 xff0c 我一直都没在知乎上遇到好的前端问题 xff0c 而这个问题 xff0c 问到我心坎上了 在过去一年的教学过程中 xff0c 不断有学生尝试理性地理解 CSS xff0c 都以失败告终 我告诉他们 CSS 是没有逻辑可言
  • 时间复杂度分析经典问题——最大子序列和

    时间复杂度经典问题 最大子列和问题 最大子序列和问题 最大子列和问题是非常经典的问题 xff0c 基本上讲算法的书都会将这个例子 xff0c 用此例题来讲解算法时间复杂度的重要性 xff0c 对比不同算法的时间复杂度 最大子列和问题如下 x
  • 无法运行宏,可能是因为该宏在此工作簿中不可用,或者所有的宏都被禁用的解决方法...

    此行为发生以下条件之一都为真时 xff1a 宏存储在未打开的文件中 宏已被禁用 若要确定是否已禁用了宏 xff0c 请按照下列步骤操作 xff1a 单击 Microsoft Office 按钮 xff0c 然后单击 Excel 选项 单击
  • h3c vlan配置

    1 基于端口的VLAN配置命令 SWA vlan 10 创建VLAN SWA vlan10 port Ethernet1 0 1 向当前VLAN添加端口 SWA vlan 20 创建VLAN SWA vlan20 port Ethernet
  • LMDB概述

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 发现一篇讲解LMDB不错的文章 xff0c 记录一下 xff0c 原文在这里 Overview homepage http symas com mdb https gith
  • GPU加速的FAST特征提取 Faster than FAST: GPU-Accelerated Frontend for High-Speed VIO (IROS 2020)

    在许多的VIO Pipeline中 xff0c 视觉特征通常依靠图像数据的detection和tracking 这两个部分通常会比较耗时 xff0c 比如一些经典的算子 xff0c 运算量都比较大 xff0c 如果将这些视觉前端用GPU进行
  • 什么是死锁及死锁的必要条件和解决方法【转】

    来自 xff1a http blog 163 com yanenshun 64 126 blog static 128388169200982444858590 fromdm amp fromSearch amp isFromSearchE
  • 获取C# RadioButton选中值

    C RadioButton的一些属性介绍 1 C RadioButton只允许用户从几个选项中选择一个 xff0c 同一个容器中一次只能选择一个按钮 xff1b 2 C RadioButton的Appearance属性 xff1a 根据的以
  • vc-api-枚举所有子窗口实例

    我经常想枚举一个父窗口的所有子窗口 xff0c 网上搜索了很多都没有搞的太懂 xff0c 经过多次实践 xff0c 总算搞明白了 xff0c 发一个最简单的实例 xff0c 希望能给大家带来帮助 实例 xff1a 枚举QQ登陆这个窗口所有的
  • VC 获取鼠标下面的窗口

    POINT pt GetCursorPos amp pt 得到鼠标下面的窗口句柄 HWND hWnd 61 WindowFromPoint pt 得到鼠标所在的子窗口句柄 HWND hChild 61 ChildWindowFromPoin
  • [SE]软件项目需求分析为什么困难

    有几种原因使需求分析变得困难 xff1a xff08 1 xff09 客户说不清楚需求 xff1b xff08 2 xff09 需求自身经常变动 xff1b xff08 3 xff09 分析人员或客户理解有误 1 客户说不清楚需求 有些客户
  • C++到底还能做什么?

    嗯 xff0c 这是一位朋友发到我邮箱里面的 xff0c 很奇怪 xff0c 发到了gmail邮箱 xff0c 而不是我常用的hotmail邮箱哈 我呢 xff0c 试着回答一下 xff0c 如果回答得不好 xff0c 叫做肖某人学艺不精
  • Docker 创建 MySQL 容器

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 1 拉取镜像 docker pull mysql 5 7 2 查看当前所有的镜像 docker image ls 3 创建并启动一个容器 docker run name t
  • 深入理解Arrays.sort()

    翻译人员 铁锚 翻译日期 2013年11月16日 原文链接 Deep Understanding of Arrays sort T Comparator lt super T gt c Arrays sort T Comparator lt