(四)Java常用类之比较器 | 【奔跑吧!JAVA】
【摘要】 在Java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题,Java实现对象排序的方式有两种:自然排序和定制排序。
在Java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题,Java实现对象排序的方式有两种:自然排序和定制排序。
1、自然排序:java.lang.Comparable
1.1、概述
(1)Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序。
(2)实现Comparable的类必须实现 compareTo(Object obj) 方法,两个对象即通过 compareTo(Object obj) 方法的返回值来比较大小。如果当前对象this大于形参对象obj,则返回正整数,如果当前对象this小于形参对象obj,则返回负整数,如果当前对象this等于形参对象obj,则返回零。
(3)实现Comparable接口的对象列表(和数组)可以通过 Collections.sort 或Arrays.sort进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。
(4)对于类A的每一个a1和a2来说,当且仅当a1.compareTo(a2) == 0 与a1.equals(a2) 具有相同的 boolean 值时,类A的自然排序才叫做与 equals 一致。建议(虽然不是必需的)最好使自然排序与 equals 一致。
1.2、Comparable 的典型实现
String:按照字符串中字符的Unicode值进行比较
Character:按照字符的Unicode值来进行比较
数值类型对应的包装类以及BigInteger、BigDecimal:按照它们对应的数值大小进行比较
Boolean:true 对应的包装类实例大于 false 对应的包装类实例
Date、Time等:后面的日期时间比前面的日期时间大
1.3、举例
public class Goods implements Comparable<Goods> {
private String name;
private double price;
public Goods(String name, double price) {
this.name = name;
this.price = price;
}
@Override
public String toString() {
return "Goods{" + "name='" + name + '\'' + ", price=" + price + '}';
}
@Override
public int compareTo(Goods other) {
if (this.price > other.price) {
return 1;
} else if (this.price < other.price) {
return -1;
}
return 0;
}
}
public class ComparableTest {
public static void main(String[] args) {
Goods[] all = new Goods[4];
all[0] = new Goods("《红楼梦》", 100);
all[1] = new Goods("《西游记》", 150);
all[2] = new Goods("《三国演义》", 140);
all[3] = new Goods("《水浒传》", 120);
Arrays.sort(all);
System.out.println(Arrays.toString(all));
}
}
2、定制排序:java.util.Comparator
2.1、概述
(1)当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用 Comparator 的对象来排序,强行对多个对象进行整体排序的比较。
(2)重写compare(Object o1,Object o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2。
(3)可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。
(4)还可以使用 Comparator 来控制某些数据结构(如有序 set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。
2.2、举例
public class Goods {
private String name;
private double price;
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 ComparatorTest {
public static void main(String[] args) {
Goods[] all = new Goods[4];
all[0] = new Goods("War and Peace", 100);
all[1] = new Goods("Childhood", 80);
all[2] = new Goods("Scarlet and Black", 140);
all[3] = new Goods("Notre Dame de Paris", 120);
Arrays.sort(all, new Comparator<Goods>() {
@Override
public int compare(Goods o1, Goods o2) {
return o1.getName().compareTo(o2.getName());
}
});
System.out.println(Arrays.toString(all));
}
}
3、两种排序方式对比
Comparable接口的方式一旦一定,保证Comparable接口实现类的对象在任何位置都可以比较大小。
Comparator接口属于临时性的比较。
【奔跑吧!JAVA】有奖征文火热进行中:https://bbs.huaweicloud.com/blogs/265241
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)