java中的arrays.sort()代码详解

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.使用策略模式

这是策略模式(Strategypattern)的一个完美又简洁的示例,值得一提的是为什么这种场景下适合使用策略模式.

总体来说,策略模式允许在程序执行时选择不同的算法.比如在排序时,传入不同的比较器(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个参数里面的<?superT>意味着比较器所接受的类型可以是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()相关的信息总结如下:

通用: super 类
策略设计模式(strategy pattern);
归并排序(merge sort): 时间复杂度 n*log(n);
Java.util.Collections#sort(List < T > list, Comparator < ? super T > c)与Arrays.sort 使用类似的思想.

总结

以上就是本文关于Java中的Arrays.sort()代码详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他Java相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

(0)

相关推荐

  • Java文件读写IO/NIO及性能比较详细代码及总结

    干Java这么久,一直在做WEB相关的项目,一些基础类差不多都已经忘记.经常想得捡起,但总是因为一些原因,不能如愿. 其实不是没有时间,只是有些时候疲于总结,今得空,下定决心将丢掉的都给捡起来. 文件读写是一个在项目中经常遇到的工作,有些时候是因为维护,有些时候是新功能开发.我们的任务总是很重,工作节奏很快,快到我们不能停下脚步去总结. 文件读写有以下几种常用的方法 1.字节读写(InputStream/OutputStream) 2.字符读取(FileReader/FileWriter) 3.

  • java编程进行动态编译加载代码分享

    简述 该类使用javax.tools.ToolProvider自带的JavaCompiler进行编译,使用IO的File及NIO的Files进行对应的路径创建.读取及拷贝,使用正则表达式进行包名与目录的转换,我只是将这些东西做了个容错整合,没什么技术含量,就为个方便吧. 模块API class DynamicReactor://空参构造 public Class<?> dynamicCompile(String srcPath);//输入一个指定的源文件路径,若编译.拷贝成功则返回该类对应的C

  • java IO流读取图片供前台显示代码分享

    最近项目中需要用到IO流来读取图片以提供前台页面展示,由于以前一直是用url路径的方式进行图片展示,一听说要项目要用IO流读取图片感觉好复杂一样,但任务下达下来了,做为程序员只有选择去执行喽,于是找了点资料看了会api, 嘿感觉挺简单的,由于是第一次采用IO流的方式进行读取图片供页面显示,所以把以下代码记录一下 后台代码: /** * IO流读取图片 by:long * @return */ @RequestMapping(value = "/IoReadImage/{imgName}"

  • java语言描述Redis分布式锁的正确实现方式

    分布式锁一般有三种实现方式:1.数据库乐观锁:2.基于Redis的分布式锁:3.基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介绍Redis分布式锁实现的博客,然而他们的实现却有着各种各样的问题,为了避免误人子弟,本篇博客将详细介绍如何正确地实现Redis分布式锁. 可靠性 首先,为了确保分布式锁可用,我们至少要确保锁的实现同时满足以下四个条件: 互斥性.在任意时刻,只有一个客户端能持有锁. 不会发生死锁.即使有一个客户端在持有锁的期间

  • java的IO流详细解读

    流,就是一系列的数据. 当不同介质之间有数据交互的时候,JAVA就使用流来实现.数据源可以是文件,还可以是数据库.网络甚至其他的程序. 比如读取文件的数据到程序中,站在程序的角度来看,就叫做输入流. 字节流(以字节的形式读取和写入数据) InputStream字节输入流同时也是抽象类,只提供方法声明,不提供方法的具体实现. FileInputStream是InputStream的子类,下面以FileInputStream为例进行文件读取 package testIO; import java.i

  • java通过JFrame做一个登录系统的界面完整代码示例

    在java的JFrame内通过创建匿名对象的方式做登录界面 package com.sxt; import java.awt.Container; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.J

  • Javacv使用ffmpeg实现音视频同步播放

    最近用javaCV的ffmpeg包的FFmpegFrameGrabber帧捕捉器对捕捉到的音频帧和视频帧做了同步的播放.采用的同步方法是视频向音频同步. 程序和源码 具体的思路如下: (1)首先介绍ffmpeg是如何捕捉视频文件的图像和声音的 FFmpegFrameGrabber fg = new FFmpegFrameGrabber("a video file path or a url); 得到帧捕捉器对象后,调用它的grab()方法就会返回捕捉到的Frame对象.这个Frame可以是视频帧

  • Java基础知识杂文

    1.基本概念 IO是主存和外部设备(硬盘.终端和网络等)拷贝数据的过程.IO是操作系统的底层功能实现,底层通过I/O指令进行完成. 所有语言运行时系统提供执行I/O较高级别的工具.(c的printfscanf,java的面向对象封装) 2.Java标准io回顾 Java标准IO类库是io面向对象的一种抽象.基于本地方法的底层实现,我们无须关注底层实现.InputStream\OutputStream(字节流):一次传送一个字节.Reader\Writer(字符流):一次一个字符. 3.nio简介

  • java中的arrays.sort()代码详解

    Arrays.sort(T[], Comparator < ? super T > c) 方法用于对象数组按用户自定义规则排序. 官方Java文档只是简要描述此方法的作用,并未进行详细的介绍,本文将深入解析此方法. 1. 简单示例 sort方法的使用非常的简单明了,下面的例子中,先定义一个比较Dog大小的Comparator,然后将其实例对象作为参数传给sort方法,通过此示例,你应该能够快速掌握Arrays.sort()的使用方法. import java.util.Arrays; impo

  • Java中Math类常用方法代码详解

    近期用到四舍五入想到以前整理了一点,就顺便重新整理好经常见到的一些四舍五入,后续遇到常用也会直接在这篇文章更新... public class Demo{ public static void main(String args[]){ /** *Math.sqrt()//计算平方根 *Math.cbrt()//计算立方根 *Math.pow(a, b)//计算a的b次方 *Math.max( , );//计算最大值 *Math.min( , );//计算最小值 */ System.out.pri

  • java中switch选择语句代码详解

    switch结构(开关语句)的语法 switch(表达式 ){ --->类型为int.char case 常量1 :--->case 结构可以有多个 //语句块1 break; --->程序跳出switch结构 case 常量n :--->常量的值不能相同 //语句块n break; default:--->和if结构中的 else作用相同 //语句块 break; } 下面看一段代码示例,有详细的注释,大家可以参考: public class SwitchStu{ /* s

  • Java中EnumSet代替位域代码详解

    本文研究的主要是Java中EnumSet代替位域的相关内容,具体介绍如下. 读书笔记<Effective Java 中文版 第2版> 位域表示法允许利用位操作,有效地执行先 union(联合)和 intersection(交集)这样的集合操作.但是位域有着int枚举常亮的所有缺点,甚至更多.当位域一数字形式打印时,翻译位域比翻译简单的int枚举常量要困难得多.甚至,要遍历位域表示的所有元素都没有很容易的方法. //Bit field enumeration constant - OBSOLET

  • Java Arrays.sort()用法详解

    Java的Arrays类中有一个sort()方法,该方法是Arrays类的静态方法,在需要对数组进行排序时,非常的好用. 但是sort()的参数有好几种,下面我就为大家一一介绍,这几种形式的用法. 1.Arrays.sort(int[] a) 这种形式是对一个数组的所有元素进行排序,并且是按从小到大的顺序. 举例如下: import java.util.Arrays; public class Main { public static void main(String[] args) { int

  • Java语言中的内存泄露代码详解

    Java的一个重要特性就是通过垃圾收集器(GC)自动管理内存的回收,而不需要程序员自己来释放内存.理论上Java中所有不会再被利用的对象所占用的内存,都可以被GC回收,但是Java也存在内存泄露,但它的表现与C++不同. JAVA中的内存管理 要了解Java中的内存泄露,首先就得知道Java中的内存是如何管理的. 在Java程序中,我们通常使用new为对象分配内存,而这些内存空间都在堆(Heap)上. 下面看一个示例: public class Simple { public static vo

  • Java中CountDownLatch进行多线程同步详解及实例代码

    Java中CountDownLatch进行多线程同步详解 CountDownLatch介绍 在前面的Java学习笔记中,总结了Java中进行多线程同步的几个方法: 1.synchronized关键字进行同步. 2.Lock锁接口及其实现类ReentrantLock.ReadWriteLock锁实现同步. 3.信号量Semaphore实现同步. 其中,synchronized关键字和Lock锁解决的是多个线程对同一资源的并发访问问题.信号量Semaphore解决的是多副本资源的共享访问问题. 今天

  • 多用多学之Java中的Set,List,Map详解

    很长时间以来一直代码中用的比较多的数据列表主要是List,而且都是ArrayList,感觉有这个玩意就够了.ArrayList是用于实现动态数组的包装工具类,这样写代码的时候就可以拉进拉出,迭代遍历,蛮方便的. 也不知道从什么时候开始慢慢的代码中就经常会出现HashMap和HashSet之类的工具类.应该说HashMap比较多一些,而且还是面试经典题,平时也会多看看.开始用的时候简单理解就是个键值对应表,使用键来找数据比较方便.随后深入了解后发现 这玩意还有点小奥秘,特别是新版本的JDK对Has

  • 基于Java中的数值和集合详解

    数组array和集合的区别: (1) 数值是大小固定的,同一数组只能存放一样的数据. (2) java集合可以存放不固定的一组数据 (3) 若程序事不知道究竟需要多少对象,需要在空间不足时自动扩增容量,则需要使用容器类库,array不适用 数组转换为集合: Arrays.asList(数组) 示例: int[] arr = {1,3,4,6,6}; Arrays.asList(arr); for(int i=0;i<arr.length;i++){ System.out.println(arr[

  • java 中复合机制的实例详解

    java 中复合机制的实例详解 继承的缺陷 继承的缺陷是由它过于强大的功能所导致的.继承使得子类依赖于超类的实现,从这一点来说,就不符合封装的原则. 一旦超类随着版本的发布而有所变化,子类就有可能遭到破坏,即使它的代码完全没有改变. 为了说明的更加具体,假设我们现在程序中使用到了HashSet,我们需要增加一个功能,去统计这个HashSet自创建以来一共曾经添加过多少元素. 在还不知道继承的缺陷的情况下,我们设计了一个类,继承了HashSet,添加了一个属性addCount来进行统计,并且复写了

随机推荐