八(三)、常用类之比较器Comparable Comparator
一、说明:
java 中的对象,正常情况下,只能进行:== or !=,不能使用> 或<的,(基本数据类型是都可以比较的)
但是实际开发场景中我们需要对多个对象进行排序,就需要比较对象的大小需要使用两个接口中的任何一个:
comparable 或者 comparator
二、comparable的使用
1.compare接口使用说明
1.1.像String、包装类实现了Comparable接口,重写了ComparableTo(obj)方法,给出了比较两个对象大小的方式
1.2..像String、包装类重写compareto() 方法以后,进行了从小到大的排列;
1.3.对于自定义类来说,如果需要排序,我们可以让自定义类实现compare接口,重写CompareTo()方法,在compareto()中指明如何排序;
1.4.重写compareto()的规则:
如果当前对象this 大于形参对象obj,则返回正整数,
如果当前对象this小于形参对象obj,则返回负数;
如果当前对象this小于形参对象obj,则返回0;
2.String 的排序举例:
1 @Test 2 public void test() { 3 String[] arr = new String[]{"AA","DD","BB","KK","JJ"}; 4 Arrays.sort(arr); 5 System.out.println(Arrays.toString(arr)); 6 }
这里Arrays.sort(arr)之后,自动从小到大排序;原因就是 String重写了ComparableTo(obj)方法,指定了排序规则,即从小到大排序;
3.自定义排序举例:
排序类:
1 package commonmethod.testClass; 2 3 //商品类 4 public class Goods implements Comparable<Goods>{ 5 private Double price; 6 private String name; 7 public Double getPrice() { 8 return price; 9 } 10 public void setPrice(Double price) { 11 this.price = price; 12 } 13 public String getName() { 14 return name; 15 } 16 public void setName(String name) { 17 this.name = name; 18 } 19 public Goods(Double price, String name) { 20 super(); 21 this.price = price; 22 this.name = name; 23 } 24 //指明 商品比较大小的方式,价格从低到高进行排序; 25 @Override 26 public int compareTo(Goods o) { 27 if(this.price>o.price) { 28 return 1; 29 }else if(this.price<o.price) { 30 return -1; 31 } 32 // TODO Auto-generated method stub 33 return 0; 34 } 35 @Override 36 public String toString() { 37 return "Goods [price=" + price + ", name=" + name + "]"; 38 } 39 40 41 }
排序方法体:
1 @Test 2 public void test1() { 3 Goods[] arr = new Goods[4]; 4 arr[0] = new Goods(34.0,"lenovoMouse"); 5 arr[1] = new Goods(43.0,"dellMouse"); 6 arr[2] = new Goods(12.0,"xiaomiMouse"); 7 arr[3] = new Goods(65.0,"huaweiMouse"); 8 Arrays.sort(arr);//Goods实现了Comparale接口,重写了comparable接口,否则报错; 9 System.out.println(Arrays.toString(arr)); 10 11 12 }
以下重写了Comparable接口的compareTo方法;可以自定义排序规则;
@Override
public int compareTo(Goods o) {
if(this.price>o.price) {
return 1;
}else if(this.price<o.price) {
return -1;
}
// TODO Auto-generated method stub
return 0;
}
三、comparator的使用
1.comparator 接口的使用:定制排序
1.1.背景:
当元素的类型没有实现comparable接口,而且又不方便修改代码
或者实现了commpare接口的排序规则不适合当前操作,那么就需要使用comparator
1.2.重写compare(object o1,object2 o2)方法,比o1,o2的大小;
如果方法返回正数,则o1>o2,
如果方法返回负数,则o1<o2,
如果方法返回0,则o1=o2,
1 @Test
2 public void test1() {
3 Goods[] arr = new Goods[4];
4 arr[0] = new Goods(34.0,"lenovoMouse");
5 arr[1] = new Goods(43.0,"dellMouse");
6 arr[2] = new Goods(12.0,"xiaomiMouse");
7 arr[3] = new Goods(65.0,"huaweiMouse");
8 Arrays.sort(arr);//Goods实现了Comparale接口,重写了comparable接口,否则报错;
9 System.out.println(Arrays.toString(arr));
10
11
12 }
这个例子使用comparator 实现:
1 @Test 2 public void test2() { 3 String[] arr = new String[]{"AA","DD","BB","KK","JJ"}; 4 Comparator c = new Comparator() {//匿名子类的非匿名对象; 5 6 @Override 7 public int compare(Object o1, Object o2) { 8 9 return -1; 10 }}; 11 Arrays.sort(arr, c); 12 13 System.out.println(Arrays.toString(arr)); 14 Goods[] goodsArr = new Goods[5]; 15 goodsArr[0] = new Goods(34.0,"lenovoMouse"); 16 goodsArr[1] = new Goods(43.0,"dellMouse"); 17 goodsArr[2] = new Goods(12.0,"xiaomiMouse"); 18 goodsArr[3] = new Goods(65.0,"huaweiMouse"); 19 goodsArr[4] = new Goods(66.0,"huaweiMouse"); 20 //按价格排序 21 Arrays.sort(goodsArr,new Comparator<Goods>() {//匿名对象的匿名子类 22 23 @Override 24 public int compare(Goods o1, Goods o2) { 25 // TODO Auto-generated method stub 26 if(o1.getPrice()>o2.getPrice()) { 27 return -1; 28 }else if(o1.getPrice()<o2.getPrice()) { 29 return 1; 30 }else { 31 return 0; 32 } 33 34 } 35 });//Goods实现了Comparale接口,重写了comparable接口,否则报错; 36 System.out.println(Arrays.toString(goodsArr)); 37 38 }
扩展:按名称排序,如果名称相同,按价格排序 都是倒叙
1 @Test 2 public void test2() { 3 Goods[] goodsArr = new Goods[5]; 4 goodsArr[0] = new Goods(34.0,"lenovoMouse"); 5 goodsArr[1] = new Goods(43.0,"dellMouse"); 6 goodsArr[2] = new Goods(12.0,"xiaomiMouse"); 7 goodsArr[3] = new Goods(65.0,"huaweiMouse"); 8 goodsArr[4] = new Goods(66.0,"huaweiMouse"); 9 10 Arrays.sort(goodsArr,new Comparator<Goods>() {//抽象类中的 匿名对象的匿名子类 11 12 @Override 13 public int compare(Goods o1, Goods o2) { 14 // TODO Auto-generated method stub 15 if(o1.equals(o2.getName())) { 16 if(o1.getPrice()>o2.getPrice()) { 17 return -1; 18 }else if(o1.getPrice()<o2.getPrice()) { 19 return 1; 20 }else { 21 return 0; 22 } 23 }else { 24 return -o1.getName().compareTo(o2.getName()); 25 } 26 27 } 28 });//Goods实现了Comparale接口,重写了comparable接口,否则报错; 29 System.out.println(Arrays.toString(goodsArr)); 30 31 }
2.Comparator 1.8 新特性:
四、comparable接口与Comparator接口比较
- comparable接口一旦指定,保证Comparable接口实现类在任何位置都能使用;
- Comparator接口属于临时性的比较