对象数组如何排序-Comparable接口详解

1 普通数组使用Arrays.sort方法排序

在Arrays工具类中,sort函数可以对普通数组进行排序,如以下代码所示:

  int[] hello = {18888,8888,5888,13888};
  Arrays.sort(hello);
  System.out.println(Arrays.toString(hello));//[5888, 8888, 13888, 18888]
		
  String[] heroName = {"成吉思汗","狄仁杰","孙尚香","虞姬"};
  Arrays.sort(heroName);
  System.out.println(Arrays.toString(heroName));//[孙尚香, 成吉思汗, 狄仁杰, 虞姬]

上面的代码分别对int类型的数组String类型的数组进行了排序,对这个排序的算法感兴趣的同学可以看这里那么我们自定义的对象数组能不能也用此方法进行排序呢?

首先我们可以新建一个类Hero1,给它定义两个属性:name和price,分别对应王者荣耀中英雄的名字和价格。然后在main函数中定义一个Hero1类型的对象数组heros1,接着调用**Arrays.sort(Object[] o)**方法。

public class Hero1{
	private String name;	
	private int price;
    //省略set,get方法和构造函数	
}
	Hero1[] heros1 = {
			new Hero1("成吉思汗",18888),new Hero1("狄仁杰",8888),
			new Hero1("孙尚香",5888),new Hero1("虞姬",13888)
		};
	Arrays.sort(heros1);//程序运行到这里抛出java.lang.ClassCastException异常
	System.out.println(Arrays.toString(heros1));

通过运行程序,我们可以很快发现程序抛出了java.lang.ClassCastException异常

类型转换异常

**那么为什么我们自定义的对象数组不能用sort方法排序呢?**通过查看源码和所抛出的异常,可以发现所有使用sort(Object[] a)方法进行排序的对象都必须实现Comparable接口。我们通过查看String的源码也可以观察到String类也实现了Comparable接口。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {}

2 自定义对象排序通过实现Comparable接口进行排序

在Hero1类中实现Comparable接口,然后重写它唯一的compareTo方法。

public class Hero1 implements Comparable<Hero1>{

	private String name;
	
	private int price;
        
    //省略set,get方法和构造函数	

	@Override
	public int compareTo(Hero1 o) {
	    //这里如果不处理系统会抛出空指针异常
		if(o == null) {
			throw new RuntimeException("对象为空!");
		}
		
		if(this.price > o.price) {
			return 1;
		}else if(this.price < o.price) {
			return -1;
		}
		return 0;
	}
}

Hero1类实现Comparable接口后排序正常实现。

	Hero1[] heros1 = {
			new Hero1("成吉思汗",18888),new Hero1("狄仁杰",8888),
			new Hero1("孙尚香",5888),new Hero1("虞姬",13888)
		};
	Arrays.sort(heros1);
	System.out.println(Arrays.toString(heros1));//[Hero1 [name=孙尚香, price=5888], Hero1 [name=狄仁杰, price=8888], Hero1 [name=虞姬, price=13888], Hero1 [name=成吉思汗, price=18888]]

3 自定义类不实现Comparable接口也有办法进行排序

Comparable接口要求自定义类主动去实现,但按照面向对象原则,代码需要对修改关闭,对扩展开发,那么在不破坏自定义类结构的前提下,我们是否有方法对类进行排序呢?

答案是肯定的,我们可以新建一个自定义的排序类,这个类实现Comparator接口,然后通过调用Arrays.sort(T[] a, Comparator<? super T> c)方法进行排序。

新建一个Hero2类,属性和Hero1一模一样,但Hero2类没有实现Comparable接口。

public class Hero2{
	private String name;
	private int price;
	//省略构造函数及set,get方法
}

接着新建一个自定义的排序类,这个类需要实现Comparator接口,然后在里面重写compare方法,逻辑和之前一样,但这个函数的入参为两个对象,同样是第一个对象大则返回1,第二个对象大则返回-1,相等返回0。

public class CustomComparator implements Comparator<Hero2>{
	@Override
	public int compare(Hero2 o1, Hero2 o2) {
		if(o1 == null || o2 == null) {
			throw new RuntimeException("对象为空!");
		}
		
		if(o1.getPrice() > o2.getPrice()) {
			return 1;
		}else if(o1.getPrice() < o2.getPrice()) {
			return -1;
		}
		return 0;
	}
}

建好自定义的排序类后便可调用Arrays.sort(T[] a, Comparator<? super T> c)方法进行排序。

	Hero2[] heros2 = {
			new Hero2("成吉思汗",18888),new Hero2("狄仁杰",8888),
			new Hero2("孙尚香",5888),new Hero2("虞姬",13888)
		};
		
	Arrays.sort(heros2, new CustomComparator());
	System.out.println(Arrays.toString(heros2));//[Hero1 [name=孙尚香, price=5888], Hero1 [name=狄仁杰, price=8888], Hero1 [name=虞姬, price=13888], Hero1 [name=成吉思汗, price=18888]]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值