参考链接: Java比较器接口与示例

写在前面: 我是「扬帆向海」,这个昵称来源于我的名字以及女朋友的名字。我热爱技术、热爱开源、热爱编程。技术是开源的、知识是共享的。 这博客是对自己学习的一点点总结及记录,如果您对 Java、算法 感兴趣,可以关注我的动态,我们一起学习。  用知识改变命运,让我们的家人过上更好的生活。

比如Integer,double等基本类型数据,Java可以对他们进行比较排序,但是在 Java 中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题 。

目录

一、java中的sort()方法二、自然排序:Comparable1.自然排序的定义2.实现过程3.示例代码

三、定制排序 :Comparator1.实现过程2.示例代码

一、java中的sort()方法

在java.util.Collections类中有个sort()方法,主要是用来给数组排序

public class CompareTest1 {

@Test

public void test() {

String[] arr = new String[]{"AA", "SS", "FF", "OO", "EE", "HH"};

System.out.println("排序之前: " + Arrays.toString(arr));

Arrays.sort(arr);

System.out.println("排序之后: " + Arrays.toString(arr));

}

}

代码执行结果:

排序之前: [AA, SS, FF, OO, EE, HH]

排序之后: [AA, EE, FF, HH, OO, SS]

需求:商场有一批水果,对水果的价格进行排序

水果类:

public class Fruit {

private String name;

private double price;

public Fruit() {

}

public Fruit(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 "Fruit{" +

"name='" + name + '\'' +

", price=" + price +

'}';

}

}

测试类:

public class CompareTest2 {

@Test

public void test() {

Fruit[] arr = new Fruit[5];

arr[0] = new Fruit("apple", 18);

arr[1] = new Fruit("pear", 6);

arr[2] = new Fruit("banana", 14);

arr[3] = new Fruit("watermelon", 26);

arr[4] = new Fruit("tomato", 6);

System.out.println("排序之前: " + Arrays.toString(arr));

// 排序

Arrays.sort(arr);

System.out.println("排序之后: " + Arrays.toString(arr));

}

}

程序将会报错:

java.lang.ClassCastException: xxx.Fruit cannot be cast to java.lang.Comparable

报错原因:类型转换错误。

为了解决这个错误,对象之间的排序将用到比较器。

Java 实现对象排序的方式有两种:

自然排序: java.lang.Comparable

定制排序: java.util.Comparator

二、自然排序:Comparable

1.自然排序的定义

Comparable 接口强行对实现它的每个类的对象进行整体排序

2.实现过程

实现 Comparable接口的类必须实现 compareTo(Object obj) 方法,两个对象通过 compareTo方法的返回值来比较大小 。 ① 如果当前对象 this 大于形参对象 obj 则返回正整数; ② 如果当前对象 this 小于 形参对象 obj则返回 负整数; ③ 如果当前对象 this 等于 形参对象 obj 则返回零 。 实现 Comparable接口的对象列表(和数组)可以通过 Collections.sort 或 Arrays.sort 进行自动排序。 实现此接口的对象可以用作有序映射中的键或有序集合中的集合,无需指定比较器

为了解决类型转换错误,在水果类里面实现Comparable接口。

3.示例代码

水果类:

public class Fruit implements Comparable<Fruit> {

private String name;

private double price;

public Fruit() {

}

public Fruit(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 "Fruit{" +

"name='" + name + '\'' +

", price=" + price +

'}';

}

// 水果价格从低到高进行排序,若价格相同则按水果名称从高到低排序

@Override

public int compareTo(Fruit fruit) {

if (this.price > fruit.price) {

return 1;

} else if (this.price < fruit.price) {

return -1;

} else {

// this.name.compareTo(fruit.name) 按名称从低到高,前面加负号,表示相反

return -this.name.compareTo(fruit.name);

}

}

}

注:测试类代码同Test2 代码执行结果:

排序之前: [Fruit{name='apple', price=18.0}, Fruit{name='pear', price=6.0}, Fruit{name='banana', price=14.0}, Fruit{name='watermelon', price=26.0}, Fruit{name='tomato', price=6.0}]

排序之后: [Fruit{name='tomato', price=6.0}, Fruit{name='pear', price=6.0}, Fruit{name='banana', price=14.0}, Fruit{name='apple', price=18.0}, Fruit{name='watermelon', price=26.0}]

三、定制排序 :Comparator

在实际开发中,遇到当元素的类型实现了Comparable 接口,但是它的排序方式不适合当前的操作;或者根本没有实现Comparable 接口,而又不方便修改代码。那么可以考虑使用 Comparator 的对象进行排序。

1.实现过程

定义一个比较器对象; 重写 compare(Object o1,Object o2) 方法,比较 o1 和 o2 的大小: ① 如果方法返回正整数,则表示 o1 大于 o2 ; ② 如果方法返回 0 ,表示相等; ③ 如果方法返回负整数,表示o1 小于 o2 。

可以 将 Comparator 传递给 sort 方法,从而允许在排序顺序上实现精确控制 。

2.示例代码

public class CompareTest3 {

/**

* 按字符从大到小进行排序

*/

@Test

public void test() {

String[] arr = new String[]{"AA", "CC", "KK", "MM", "GG", "FF", "DD"};

System.out.println("原来的字符串: " + Arrays.toString(arr));

Arrays.sort(arr, new Comparator<String>() {

@Override

public int compare(String o1, String o2) {

return -o1.compareTo(o2);

}

});

System.out.println("按字符从大到小排序后的字符串: " + Arrays.toString(arr));

}

}

代码执行结果:

原来的字符串: [AA, CC, KK, MM, GG, FF, DD]

按字符从大到小排序后的字符串: [MM, KK, GG, FF, DD, CC, AA]

对水果的价格进行排序

注:水果类同前,节省篇幅,在此不再重复。

public class CompareTest4 {

@Test

public void test() {

Fruit[] arr = new Fruit[5];

arr[0] = new Fruit("apple", 18);

arr[1] = new Fruit("pear", 6);

arr[2] = new Fruit("banana", 14);

arr[3] = new Fruit("watermelon", 26);

arr[4] = new Fruit("watermelon", 6);

System.out.println("排序之前: " + Arrays.toString(arr));

Arrays.sort(arr, new Comparator<Fruit>() {

// 按照水果名称从低到高排序,若名称相同则按照价格从高到低排序

@Override

public int compare(Fruit o1, Fruit o2) {

if (o1.getName().equals(o2.getName())) {

return -Double.compare(o1.getPrice(), o2.getPrice());

} else {

return o1.getName().compareTo(o2.getName());

}

}

});

System.out.println("排序之后: " + Arrays.toString(arr));

}

}

代码执行结果:

排序之前: [Fruit{name='apple', price=18.0}, Fruit{name='pear', price=6.0}, Fruit{name='banana', price=14.0}, Fruit{name='watermelon', price=26.0}, Fruit{name='watermelon', price=6.0}]

排序之后: [Fruit{name='apple', price=18.0}, Fruit{name='banana', price=14.0}, Fruit{name='pear', price=6.0}, Fruit{name='watermelon', price=26.0}, Fruit{name='watermelon', price=6.0}]

当定制排序和自然排序同时存在时,最终的排序结果是按照定制排序进行排序的。

上一篇 聊聊 StringBuffer 与 StringBuilder

[转载] 比较器(Comparable和Comparator)、自然排序、定制排序相关推荐

  1. Java常用类(3)--Java比较器Comparable、Comparator类

    文章目录 自然排序:java.lang.Comparable 定制排序:java.util.Comparator 自然排序:java.lang.Comparable Comparable接口强行对实现 ...

  2. 比较器——Comparable与Comparator的使用

    目录 1.Comparable 2.Comparator比较器 1.Comparable 当我们要比较对象大小,或者是对对象进行排序时,我们就可以使用接口COmparable,重写该接口中的compa ...

  3. JAVASE的内、外部比较器Comparable和Comparator

    1.内部比较器,自定义实体类实现Comparable接口 /*** @author Nyotengu* @date 18/7/26 15:39*/ public class SortTest {/** ...

  4. 比较器Comparable跟Comparator

    在开发过程中如果需要对集合或数组中的一些属性左比较,并且按照一定的顺序排序的话,java的一个比价好的解决办法是用比较器,这里介绍两种 1.Comparable接口 比如在Person中需要对首先对a ...

  5. Day48(List接口,ArrayList,LinkedList,Vector,Set接口,HashSet,LinkedHashSet,TreeSet,自然排序,定制排序)

    Collection子接口之一:List接口 List接口概述 鉴于Java中数组用来存储数据的局限性,我们通常使用List替代数组 List集合类中元素有序.且可重复,集合中的每个元素都有其对应的顺 ...

  6. 浅析 Comparable和 Comparator的区别

    简介 Comparable和 Comparator都是java.util包下的两个接口,从字面上看这两个接口都是用来做比较用的,但是jdk里面不可能定义两个功能相同的接口,所以他们肯定有不同的用处. ...

  7. Java核心API -- 7(Iterator迭代器、Comparable、Comparator比较器)

    1. Iterator迭代器 所有Collection的实现类都实现了iterator方法,该方法返回一个Iterator接口类型的对象,用于实现对集合元素迭代的便利.在java.util包下. 1) ...

  8. Comparable 和 Comparator 比较器

    Comparable :自然排序(自己单独实现) 自然排序的定义 Comparable 接口强行对实现它的每个类的对象进行整体排序 实现过程 实现 Comparable 接口的类必须实现 compar ...

  9. TreeSet的自然排序和定制排序

    只要放在TreeSet中的元素对象,在该对象的类中必须实现Comparable接口,必须覆盖该接口中的compareTo()方法,并在该方法中编写比较规则.(该方法不能自动生成) 自然排序(Compa ...

最新文章

  1. 清除administrator密码 方法
  2. linux启动后分区数据变化,求助!我删除了Linux启动分区
  3. 【开源项目】基于FFmpeg的封装格式转换
  4. java2019 数据结构算法面试题_2019年JVM最新面试题,必须收藏它
  5. linux运行tcl脚本语言,Tool Command Language (Tcl)初体验
  6. 再谈Js定义变量,你不得不踩的那些坑
  7. Google是如何识别原创文章的,以及外链建设意见
  8. ATTCK实战系列三(msf域渗透)
  9. 企业供应链管理架构图
  10. Windows清理助手ARSWP
  11. python search group_python笔记52-re正则匹配search(group groups groupdict)
  12. 郑州等保测评公司有哪些?在哪里?
  13. 不用编程语言自带函数,你会如何实现计算平方根
  14. K8S---Downward API
  15. apicloud mysql_APICloud 微信授权登录
  16. UI设计中异常状态设计总结
  17. LPC1768学习笔记
  18. IE6 PNG 图片问题分析
  19. uniapp 中 通过经纬度获取地址详情(vue)
  20. python处理实验数据,Python在热敏电阻测量实验数据处理中的应用

热门文章

  1. 【NOIP2002】【Luogu1037】产生数(高精乘低精,DFS暴力搜索)
  2. 嵌入式linux clion,跨平台IDE集成开发环境Clion教程:嵌入式开发
  3. mysql5.6.19安装图解_mysql5.6.19安装说明
  4. 2018CCPC网络赛
  5. dfs-Bit Compression
  6. c++排序算法之 快速排序
  7. 2013蓝桥杯C++A:颠倒的价牌(stringstream用法)
  8. 递归法:走楼梯; 旋转数组的最小数字(递归法和改进二分法)
  9. UnityShader25:在Unity中实现泛光
  10. C++结构体,联合体与枚举类