导航:首页 > 编程语言 > java比较器的工作原理

java比较器的工作原理

发布时间:2025-01-20 11:56:34

A. java中,comparator与comparable有什么不同

在Java的集合框架中,`Comparable`和`Comparator`这两个术语经常被提及,它们在比较对象时扮演着关键角色。本文旨在深入解析这两种机制,以解答“Java中,`Comparator`与`Comparable`有什么不同?”这一问题。

`Comparable`是一个接口,它要求类实现一个名为`compareTo`的方法,用于比较实例之间的相对顺序。实现`Comparable`接口的类必须重写`compareTo`方法,以便定义对象间的比较逻辑。例如,可以定义一个`Person`类,通过比较年龄来实现对象间的排序。下面是一个简单的示例,展示了如何实现`Comparable`接口来比较年龄大小。

java
class Person implements Comparable {
private int age;

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

@Override
public int compareTo(Person other) {
return Integer.compare(this.age, other.age);
}
}

public class Main {
public static void main(String[] args) {
Person p1 = new Person();
p1.setAge(20);
Person p2 = new Person();
p2.setAge(30);
List list = new ArrayList>();
list.add(p1);
list.add(p2);
Collections.sort(list);
System.out.println(list.get(0).getAge() < list.get(1).getAge()); // 输出:true
}
}

`Comparator`是一个接口,它提供了比`Comparable`更加灵活的比较方式,允许在不修改原有类的情况下定义比较逻辑。`Comparator`的核心方法是`compare`,用于比较两个对象之间的顺序。下面是一个示例,展示了如何为`Person`类定义一个自定义的比较器,用于比较年龄大小。

java
class PersonalComparator implements Comparator {
@Override
public int compare(Person p1, Person p2) {
return Integer.compare(p1.getAge(), p2.getAge());
}
}

public class Main {
public static void main(String[] args) {
List list = new ArrayList>();
list.add(new Person());
list.get(0).setAge(20);
list.add(new Person());
list.get(1).setAge(30);
list.sort(new PersonalComparator());
System.out.println(list.get(0).getAge() < list.get(1).getAge()); // 输出:true
}
}

在实现排序逻辑时,`Comparator`允许我们更加灵活地控制对象间的比较,而无需修改对象本身的类。例如,我们可以使用`Collections.sort()`方法,传入一个`Comparator`对象来对集合进行排序。

总结而言,`Comparable`接口提供了类内比较功能,适用于实现对象间的自然比较逻辑;而`Comparator`接口则提供了更加灵活的比较机制,允许在不修改对象类的情况下实现复杂比较规则。理解这两个机制的不同应用场景,有助于在Java编程中更有效地管理数据的排序与比较。

B. java中Comparable和Comparator两种比较器的区别

Comparable和Comparator接口都是为了对类进行比较,众所周知,诸如Integer,double等基本数据类型,java可以对他们进行比较,而对于类的比较,需要人工定义比较用到的字段比较逻辑。可以把Comparable理解为内部比较器,而Comparator是外部比较器,基本的写法如下:
class Apple implements Comparable<Apple>{
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 +
'}';
}
}
class AESComparator implements Comparator<Apple>{

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;
}
}
}
实现了Comparable接口的类需要实现compareTo()方法,传入一个外部参数进行比对,实现了Comparator接口的方法需要实现compare()方法,对外部传入的两个类进行比较,从而让外部方法在比较时调用。
两者的区别是实现Comparator接口代码更加灵活,可以定义某个类的多个比较器,从而在排序时根据实际场景自由调用,而Comparable接口实现后便不能改动。两种接口的调用方式如下:
class AESComparator implements Comparator<Apple>{

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<Apple>{

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;
}
}
}
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<Apple> list = new ArrayList<Apple>();
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);

}
}

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

public int compare(Apple o1, Apple o2) {
return Double.compare(o1.price,o2.price);
}
}
class DESComparator implements Comparator<Apple>{

public int compare(Apple o1, Apple o2) {
return Double.compare(o2.price,o1.price);
}
}
查看Double.compare的源码如下
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)
}

阅读全文

与java比较器的工作原理相关的资料

热点内容
炒股app有哪个 浏览:108
汽车钥匙编程器哪个好 浏览:688
误删除文件怎么恢复 浏览:885
360wifi扩展器版本升级 浏览:336
word批量删除某个同一图片logo 浏览:637
苹果5应用需要证书 浏览:531
触摸屏编程有哪些优势 浏览:550
ps文件存储环境 浏览:74
文件名怎么改不了大小写 浏览:613
眼睛验光数据什么样算假近视 浏览:269
1在编程里代表什么 浏览:193
密码文件柜哪里便宜 浏览:949
box文件怎么打开 浏览:114
线切割编程哪个好用 浏览:70
反诈app官方已下载怎么注册 浏览:496
安卓5flash游戏 浏览:895
什么卡有免费微信提示 浏览:511
iphone看不了文件管理 浏览:783
数据包如何上传宝贝 浏览:885
java获得url参数 浏览:753

友情链接