java 比较器不同维度间的比较_java中Comparable和Comparator两种比较器的区别

Comparable和Comparator接口都是为了对类进行比较,众所周知,诸如Integer,double等基本数据类型,java可以对他们进行比较,而对于类的比较,需要人工定义比较用到的字段比较逻辑。可以把Comparable理解为内部比较器,而Comparator是外部比较器,基本的写法如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

class Apple implements Comparable{

int id;

double price;

public Apple(int id, double price) {

this.id = id;

this.price = price;

}

public int compareTo(Apple o) {

//return Double.compare(this.getPrice(),o.getPrice());

if (Math.abs(this.price-o.price)<0.001)

return 0;

else

return (o.price-this.price)>0?1:-1;

}

@Override

public String toString() {

return "Apple{" +

"id=" + id +

", price=" + price +

'}';

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

class AESComparator implements Comparator{

public int compare(Apple o1, Apple o2) {

if (Math.abs(o1.price-o2.price)<0.001)

return 0;

else{

return (o1.price-o2.price)>0?1:-1;

}

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

实现了Comparable接口的类需要实现compareTo()方法,传入一个外部参数进行比对,实现了Comparator接口的方法需要实现compare()方法,对外部传入的两个类进行比较,从而让外部方法在比较时调用。

两者的区别是实现Comparator接口代码更加灵活,可以定义某个类的多个比较器,从而在排序时根据实际场景自由调用,而Comparable接口实现后便不能改动。两种接口的调用方式如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

class AESComparator implements Comparator{

public int compare(Apple o1, Apple o2) {

if (Math.abs(o1.price-o2.price)<0.001)

return 0;

else{

return (o1.price-o2.price)>0?1:-1;

}

}

}

class DESComparator implements Comparator{

public int compare(Apple o1, Apple o2) {

if (Math.abs(o1.price-o2.price)<0.001)

return 0;

else {

return (o1.price-o2.price)>0?-1:1;

}

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

48304ba5e6f9fe08f3fa1abda7d326ab.png

public static void main(String[] args) {

Apple apple1 = new Apple(1,4.8);

Apple apple2 = new Apple(2,5.9);

Apple apple3 = new Apple(3,8.5);

List list = new ArrayList();

list.add(apple1);

list.add(apple3);

list.add(apple2);

System.out.println("Comparable==========");

System.out.printf("this list of apples: %s\n",list);

Collections.sort(list);

System.out.printf("this list of apples: %s\n",list);

System.out.println("Comparator==========");

System.out.printf("this list of apples: %s\n",list);

Collections.sort(list,new DESComparator());

System.out.printf("this list of apples: %s\n",list);

Collections.sort(list,new AESComparator());

System.out.printf("this list of apples: %s\n",list);

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

上述代码存在的问题,不能在比较器中进行double类型的减法操作,因为对于值比较大的double,减法操作容易导致值的溢出,java7对每一种包装类型的比较新增了compare()方法,改造后的代码如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

class Apple implements Comparable{

int id;

double price;

public Apple(int id, double price) {

this.id = id;

this.price = price;

}

public int compareTo(Apple o) {

return Double.compare(this.price,o.price);

}

@Override

public String toString() {

return "Apple{" +

"id=" + id +

", price=" + price +

'}';

}

}

class AESComparator implements Comparator{

public int compare(Apple o1, Apple o2) {

return Double.compare(o1.price,o2.price);

}

}

class DESComparator implements Comparator{

public int compare(Apple o1, Apple o2) {

return Double.compare(o2.price,o1.price);

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

查看Double.compare的源码如下

48304ba5e6f9fe08f3fa1abda7d326ab.png

public static int compare(double d1, double d2) {

if (d1 < d2)

return -1; // Neither val is NaN, thisVal is smaller

if (d1 > d2)

return 1; // Neither val is NaN, thisVal is larger

// Cannot use doubleToRawLongBits because of possibility of NaNs.

long thisBits = Double.doubleToLongBits(d1);

long anotherBits = Double.doubleToLongBits(d2);

return (thisBits == anotherBits ? 0 : // Values are equal

(thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)

1)); // (0.0, -0.0) or (NaN, !NaN)

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值