Java比较器
- 在 Java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题。
- Java实现对象排序的方式有两种
- 自然排序:java.lang.Comparable
- 定制排序:java.util.Comparator
自然排序 java.lang.Comparable
- Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序。
- 实现 compareTo(Object obj) 方法的返回值来比较大小。如果
当前对象 this大于形参 obj,则返回正整数,如果当前对象 this小于形参 obj,则返回负整数,
如果当前对象 thsi等于形参对象 obj,则返回零。
- 实现 Comparable接口的对象列表【和数组】可以通过 Collections.sort或 Arrays.sort
进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。
- 对于类 C的每一个 e1和 e2来说,当且仅当 e1.compareTo(e2) == 0 与 e1.equals(e2)
具有相同的 boolean值时,类 C的自然排序才叫做 equals一致。建议【虽然不是必需的】
最好使用自然排序与 equals一致。
Comparable 的典型实现:【默认都是从小到大排列的】
- String 按照字符串中字符的 Unicode值进行比较。
- Character 按照字符的 Unicode值来进行比较
数组类型对应的包装类以及 BigLnteger,BigDecimal 按照他们对应的数值
大小进行比较
- Boolean:true 对应的包装类实例大于 false对应的包装类实例
- Date,Time等:后面的日期时间比前面的日期时间大
class Goods implements Comparable{
private String name;
private double price;
//按照价格 比较商品的大小
@Overide
public int compareTo(Object o){
//不能写成 this instanceof o
//和 o instanceof this
if(o instanceof Goods){
Goods other = (Goods)o;
if(this.price > other.price){
return 1;
}else if(this.price < other.price){
return -1;
}
return 0;
}
throw new RuntimeException("输入的数据类型不一样");
}
//略 构造器 get set toString 方法
}
public class Test {
@org.junit.Test
public void test1() {
Goods[] all = new Goods[4];
all[0] = new Goods("<aa>", 100);
all[1] = new Goods("<bb>", 50);
all[2] = new Goods("<cc>", 399);
all[3] = new Goods("<dd>", 200);
Arrays.sort(all);
//从小到大
Arrays.stream(all).forEach(System.out::print);
}
}
定制排序:java.util.Comparator
- 当元素的类型没有实现 java.lang.Comparable 接口而又不方便修改代码,
或者实现了 java.lang.Comparable 接口的排序规则不适合当前的操作,那么可以考虑
使用 Comparator的对象排序,强行对多个对象进行整体排序的比较。
- 重写 compare(Object o1,Object 02)方法,比较 o1 和 o2的大小:如果方法返回正
整数,则表示 o1 大于 o2;如果返回 0,表示相等;返回负整数,表示 o1 小于 o2。
- 可以键 Comparator传递给 sort方法【如 Collections或 Arrays.sort】从而允许在排序
顺序上实现精确控制。
- 还可以使用 Comparator来控制某些数据结构【如有序 set或者有序映射】的顺序,或者
为那些没有自然顺序的对象 collection提供排序
@org.junit.Test
public void test2() {
Goods[] all = new Goods[4];
all[0] = new Goods("cc>", 100);
all[1] = new Goods("dd>", 50);
all[2] = new Goods("aa>", 399);
all[3] = new Goods("bb>", 200);
/* Arrays.sort(all, new Comparator<Goods>() {
@Override
public int compare(Goods o1, Goods o2) {
return o1.getName().compareTo(o2.getName());
}
});*/
//相等于上面 lambda使用
Arrays.sort(all, (x, y) -> {
return x.getName().compareTo(y.getName());
});
//从a-z输入
System.out.println(Arrays.toString(all));
}
总结
- 两个对象比较有三种情况:大于,等于,小于
- 如果按照升序排序:则 obj01 大于 obj02 返回正数,相等返回0,obj01 小于 obj02 返回的是负数
- 如果是降序排序:则obj01 大于obj02 返回的是负数,相等返回0,obj01 小于 obj02 返回是正数
- 简写
obj01 - obj02
---->升序排序
obj02 - obj01
---->降序排序
简述Comparable和Comparator的区别
- Comparable:强行对实现每个类对象进行整体排序。这种排序一般称之为自然排序,类的CompareTo方法被称位它的自然比较方法。只能在类中实现CompareTo方法一次,不能经常类的代码实现自己想要的排序。实现此接口的对象列表和数组可以通过Collections.sort() 和Arrays.sort()进行自动排序,对象可以用作有序映射中的键或者有序集合中的元素,无序指定比较器。
- Comarator:强行对某个对象进行整体排序,可以将Comparator传递给sort()方法如Collections.sort()后者Arrays.sort() 从而允许在排序上实现精确控制。还可以使用Comparator来控制某些数据结构(有序的set或者有序的映射)的顺序,或者为那些没有自然顺序的对象Collection提供排序。