1、前言
在Java中经常遇到数组和对象的排序问题,那么就涉及到对象之间的比较问题。
Java中的对象,正常情况下,只能进行比较:== !=。不能用 > < 号比较对象,使用以下方式比较对象的大小。
在Java中实现对象排序的两种方式:
①自然排序:java.lang.Comparable
②定制排序:java.util.Comparator
2、方式一:自然排序,自定义类实现Comparable接口
一个类实现Comparable接口,Comparable会强行对实现它的每个类进行整体排序。这种类的排序称为类的自然排序。
实现Comparable的类必须实现的Comparable中的compareTo(Object obj)方法,两个对象通过compareTo(Object obj)方法的返回值来比较大小。
如果当this对象大于形参的obj,则返回正整数;
如果当前this对象小于形参obj,则返回负整数;
如果当前对象的this等于形参obj,则返回0;
返回的是如果前面添加 负号,
// 返回的是自然排序从小到大,要从大到小的话,在前面添加负号
return -s1.compareTo(s2);
有的类已经实现了Comparable接口,比如String,重写了接口中的compareTo()方法,给出比较两个对象的大小。对于自定义的类来说,如果需要排序,我们可以自定义类实现Comparable接口,重写compareTo()方法进行排序。
注意:A instanceOf(B):意思是判断A是否是B的对象
具体自定义类的比较,需要实现Comparable接口,然后实现compareTo()方法。
public class Goods implements Comparable{
private String name;
private Double price;
public Goods(String name, Double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
@Override
public String toString() {
return "Goods{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
public int compareTo(Object o) {
// 判断参数对象是否属于Goods
if (o instanceof Goods) {
// 将参数o强转Goods对象
Goods good = (Goods)o;
if (this.price > good.price) {
return 1;
} else if (this.price < good.price) {
return -1;
} else {
// return 0;
// 当商品价格相同的时候,就从商品的名称开始排序
return this.name.compareTo(good.name);
}
// return Double.compare(this.price, good.price);
}
// 如果不是一个商品就抛出异常
throw new RuntimeException("运行时候异常");
}
}
public void test3(){
String[] arr = new String[]{"ZZ","KK","QQ","WW"};
Arrays.sort(arr, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
// 两个对象都应该是String类似,满足才比较
if (o1 instanceof String && o2 instanceof String) {
// 进行强转
String s1 = (String) o1;
String s2 = (String) o2;
// 返回的是自然排序从小到大,要从大到小的话,在前面添加负号
return -s1.compareTo(s2);
}
throw new RuntimeException("运行时候异常");
}
});
System.out.println(Arrays.toString(arr));
}
2、方式一:定制排序,排序的时候new Compartor(){}
当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则而不适合的操作,那么可以使用Comparator的对象来排序。
在sort()方法中的第二个参数实现Comparator(){},判断对象的大小。
compare(Object obj,Object obj),比较o1和o2的大小:如果方法放回正整数,则o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2;
注意:int compare(T o1,T o2):意思是判断A是否是B的对象
代码如下:实现的是如果name相同,就比较price。否则就按照姓名排序。
@Test
public void test4(){
Goods[] goods = new Goods[5];
goods[0] = new Goods("qwq", 12.0);
goods[1] = new Goods("dwe", 13.0);
goods[2] = new Goods("awqeq", 54.0);
goods[3] = new Goods("yh", 1000.0);
goods[4] = new Goods("yh", 123.0);
Arrays.sort(goods, new Comparator<Goods>() {
@Override
public int compare(Goods o1, Goods o2) {
if (o1.getName().equals(o2.getName())) {
return o1.getPrice().compareTo(o2.getPrice());
} else {
return o1.getName().compareTo(o2.getName());
}
}
});
System.out.println(Arrays.toString(goods));
}
4、总结
本文是主要讲的是Java中的比较器,现在来做个总结。
①自然比较:java.lang.Comparable,接口中的方法public int compareTo(T o);
②定制比较:java.util.Comparator , 接口中的方法 int compare(T o1,T o2)
比较:
Comparable接口的方式一旦确定,保证Comparable接口实现实现类的对象在任何位置比较大小。
Comparator接口属于临时性比较,相当于一次性的,程序自己写。