如果说起比较,像我这样的小白第一时间想到的是1“等于”(==)1或者是1“不等于”(!=)2这种。那是因为正常情况下,java中的对象只能比较==和!=。但是在日常的开发中,我们会面临大量的数据,而此时有大批的“对象”等着我们给他们“排队”,此时就用到了“Comparable” 和“Comparator”接口。
下面我来简单介绍一下这两个接口:
1.Comparable接口简介
我们在开发中有时候需要对数据进行自然排序(像是数据从大到小,从a到z等等)时,这时就用到了Comparable接口。而他为什么叫自然排序呢,是因为他本身就带着一个compareTo(),而且此方法已经在底层源码中写好的,而我们只需要在自定义类中,重写compareTo()方法即可,他会自动比较调用方法的对象和参数的大小,结果自然而然就出来啦。
代码举例:
/**
* 商品类
*/
public class Goods implements Comparable{
private String name;//商品名字
private double price;//价格
//指明商品比较大小的方式:按照价格从低到高排序,再按照产品名称从高到低排序
@Override
public int compareTo(Object o) {
//这里的o是object类型,转Goods是向下转型需要强转。强制转型可能会有错误,所以使用instanceof判断下
if(o instanceof Goods){
Goods goods = (Goods)o;
if(this.price > goods.price){
return 1;
}else if(this.price < goods.price){
return -1;
}else{
// return 0;
return -this.name.compareTo(goods.name);//不加-是从低到高,加-是从高到低
}
throw new RuntimeException("传入的数据类型不一致!");
}
public Goods() {
}
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 class CompareTest {
@Test
public void test(){
Goods[] arr = new Goods[5];
arr[0] = new Goods("lenovoMouse",34);
arr[1] = new Goods("dellMouse",43);
arr[2] = new Goods("xiaomiMouse",12);
arr[3] = new Goods("huaweiMouse",65);
arr[4] = new Goods("microsoftMouse",43);
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}
}
通过上方的代码,我们可以总结出重写comparaTo()的规则:
- 如果当前对象this大于形参对象obj,则返回正整数
- 如果当前对象this小于形参对象obj,则返回负整数
- 如果当前对象this等于形参对象obj,则返回零
2.Comparator接口简介
当元素的类型实现类java.lang.Comparable接口无法满足于当前的需求,或者是既没有实现该接口又不想费劲改代码,此时就用到了我们的的专属定制——comparator接口,因此comparator接口的使用有被称为定制排序。也就是说,我们可以通过实现Comparator接口来创建一个新的比较器,然后通过该比较器对类或类的对象进行排序。
代码举例:
@Test
public void test1(){
String[] arr = new String[]{"AA","CC","KK","MM","GG","JJ","DD"};
Arrays.sort(arr,new Comparator(){//创建一个接口实现类的对象,因此处只用1次,所以可以匿名
//按照字符串从大到小的顺序排列
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof String && o2 instanceof String){
String s1 = (String) o1;
String s2 = (String) o2;
return -s1.compareTo(s2);
}
// return 0;
throw new RuntimeException("输入的数据类型不一致");
}
});
System.out.println(Arrays.toString(arr));
}
@Test
public void test2(){//此处用上面的自定义Goods类(商品类)
Goods[] arr = new Goods[6];
arr[0] = new Goods("lenovoMouse",34);
arr[1] = new Goods("dellMouse",43);
arr[2] = new Goods("xiaomiMouse",12);
arr[3] = new Goods("huaweiMouse",65);
arr[4] = new Goods("huaweiMouse",224);
arr[5] = new Goods("microsoftMouse",43);
//把需要自定义排序的元素/属性赋值给创建继承comparator匿名内部类的匿名对象,重写其排序规则的方法
Arrays.sort(arr, new Comparator() {
//指明商品比较大小的方式:按照产品名称从低到高排序,再按照价格从高到低排序
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof Goods && o2 instanceof Goods){
Goods g1 = (Goods)o1;
Goods g2 = (Goods)o2;
if(g1.getName().equals(g2.getName())){
return -Double.compare(g1.getPrice(),g2.getPrice());
}else{
return g1.getName().compareTo(g2.getName());
}
}
throw new RuntimeException("输入的数据类型不一致");
}
});
System.out.println(Arrays.toString(arr));
}
通过上方的代码,我们可以总结出重写compare()的规则:
重写compare(Object o1,Object o2)方法,比较o1和o2的大小:
- 如果方法返回正整数,则表示o1大于o2
- 如果返回0,表示相等
- 返回负整数,表示o1小于o2
就此可以看出来Comparable接口与Comparator的使用上的区别:
Comparable接口的方式一旦指定,实现Comparable接口的对象都可以比较大小;而Comparator更像是一种临时工,用完(比较完)就走人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/81359.html