Java比较器

在Java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题。

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

    • 自然排序:java.lang.Comparable
    • 定制排序:java.util.Comparator

方式一:自然排序:java.lang.Comparable

  • Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序。

  • 实现 Comparable 的类必须实现 compareTo(Object obj)方法,两个对象即通过compareTo(Object obj) 方法的返回值来比较大小。

    • 如果当前对象this大于形参对象obj,则返回正整数,
    • 如果当前对象this小于形参对象obj,则返回负整数,
    • 如果当前对象this等于形参对象obj,则返回零。
  • 像String、包装类等实现了Comparable接口,重写了compareTo(obj)方法,给出了比较两个对象大小的方式

  • 像String、包装类重写了compareTo(obj)方法以后,进行了从小到大的排列

  1. @Test
  2. public void test1(){
  3. String[] arr=new String[]{"AA","CC","KK","MM","GG","JJ","DD"};
  4. Arrays.sort(arr);
  5. System.out.println(Arrays.toString(arr));
  6. }

Comparable 的典型实现:(默认都是从小到大排列的)

  • String:按照字符串中字符的Unicode值进行比较
  • Character:按照字符的Unicode值来进行比较
  • 数值类型对应的包装类以及BigInteger、BigDecimal:按照它们对应的数值大小进行比较
  • Boolean:true 对应的包装类实例大于 false 对应的包装类实例
  • Date、Time等:后面的日期时间比前面的日期时间大

比较商品大小

  1. /**
  2. * 商品类
  3. * @author tongfangping
  4. */
  5. public class Goods implements Comparable {
  6. private String name;
  7. private double price;
  8. public Goods() {
  9. }
  10. public Goods(String name, double price) {
  11. this.name = name;
  12. this.price = price;
  13. }
  14. public String getName() {
  15. return name;
  16. }
  17. public void setName(String name) {
  18. this.name = name;
  19. }
  20. public double getPrice() {
  21. return price;
  22. }
  23. public void setPrice(double price) {
  24. this.price = price;
  25. }
  26. @Override
  27. public String toString() {
  28. return "Goods{" +
  29. "name='" + name + '\'' +
  30. ", price=" + price +
  31. '}';
  32. }
  33. //指明商品比较大小的方式:按照价格从低到高排序
  34. @Override
  35. public int compareTo(Object o) {
  36. if(o instanceof Goods){
  37. Goods goods=(Goods)o;
  38. if(this.price > goods.price){
  39. return 1;
  40. }
  41. else if(this.price < goods.price){
  42. return -1;
  43. }
  44. else{
  45. return 0;
  46. }
  47. }
  48. throw new RuntimeException("传入的数据类型不一致!");
  49. }
  50. }
  51. @Test
  52. public void test2(){
  53. Goods[]arr=new Goods[4];
  54. arr[0]=new Goods("联想鼠标",34);
  55. arr[1]=new Goods("戴尔鼠标",43);
  56. arr[2]=new Goods("小米鼠标",12);
  57. arr[3]=new Goods("华为鼠标",65);
  58. Arrays.sort(arr);
  59. System.out.println(Arrays.toString(arr));
  60. //结果:[Goods{name='小米鼠标', price=12.0}, Goods{name='联想鼠标', price=34.0}, Goods{name='戴尔鼠标', price=43.0}, Goods{name='华为鼠标', price=65.0}]
  61. }

方式二:定制排序:java.util.Comparator

背景

元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,
或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用Comparator的对象来排序,强行对多个对象进行整体排序的比较。

使用

  • 重写compare(Object o1,Object o2)方法,比较o1和o2的大小:

    • 如果方法返回正整数,则表示o1大于o2;
    • 如果返回0,表示相等;
    • 返回负整数,表示o1小于o2。
  1. @Test
  2. public void test3(){
  3. String[] arr=new String[]{"AA","CC","KK","MM","GG","JJ","DD"};
  4. Arrays.sort(arr, new Comparator(){
  5. //按照字符串从大到小排序
  6. @Override
  7. public int compare(Object o1, Object o2) {
  8. if(o1 instanceof String && o2 instanceof String){
  9. String s1=(String)o1;
  10. String s2=(String)o2;
  11. return -s1.compareTo(s2);
  12. }
  13. throw new RuntimeException("传入的数据类型不一致!");
  14. }
  15. });
  16. System.out.println(Arrays.toString(arr));
  17. }