一、说明

Java中基本数据类型可以使用 ==!=><来比较,但是对象之间的比较只能用== 或者 !=。不能使用<>比较。

那么如何比较对象的大小的,如何对多个对象进行排序呢?

这就引出了我们今天的主角,两个接口:

  • 自然排序:java.lang.Comparable

  • 定制排序:java.lang.Comparator

二、自然排序:Comparable接口

基本介绍:
  • Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序。
  • 实现 Comparable 的类必须重写该接口的 compareTo(Object obj) 方法,两个对象通过 compareTo(Object obj) 方法的返回值来比较大小。
    • 如果当前对象this大于形参对象obj,则返回正整数。
    • 如果当前对象this小于形参对象obj,则返回负整数。
    • 如果当前对象this等于形参对象obj,则返回零。
  • 实现Comparable接口的对象列表(和数组)可以通过 Collections.sort 或者Arrays.sort进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。
典型实现:(默认都是从小到大排列)
  • String:按照字符串中字符的Unicode值进行比较

  • Character:按照字符的Unicode值来进行比较

  • 数值类型对应的包装类以及BigInteger、BigDecimal:按照它们对应的数值大小进行比较

  • Boolean:true 对应的包装类实例大于 false 对应的包装类实例

  • Date、Time等:后面的日期时间比前面的日期时间大

    代码演示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    //商品类,实现Comparable接口
    public class Goods implements Comparable {
    private String name;
    private double price;

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public double getPrice() {
    return price;
    }

    @Override
    public String toString() {
    return "Goods{" +
    "name='" + name + '\'' +
    ", price=" + price +
    '}';
    }

    public void setPrice(double price) {
    this.price = price;
    }

    public Goods(String name, double price) {
    this.name = name;
    this.price = price;
    }

    //商品比较大小的方式:按照价格从低到高排序,再按照商品名称从高到低排序
    @Override
    public int compareTo(Object o) {
    if (o instanceof Goods) {
    Goods goods = (Goods) o;
    if (this.price > goods.price) {
    return 1;
    } else if (this.price < goods.price) {
    return -1;
    } else {
    return -this.name.compareTo(goods.name);
    }
    }
    throw new RuntimeException("传入的数据类型不一致!");
    }
    }

    //测试类
    @Test
    public void test2() {
    Goods[] arr = new Goods[5];
    arr[0] = new Goods("罗技",299);
    arr[1] = new Goods("雷蛇",399);
    arr[2] = new Goods("小米",99);
    arr[3] = new Goods("戴尔",169);
    arr[4] = new Goods("联想",99);

    Arrays.sort(arr);
    System.out.println(Arrays.toString(arr));
    }

3.定制排序:java.util.Comparator

  • 当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用Comparator的对象来排序,强行对多个对象进行整体排序的比较。
  • 重写compare(Object o1,Object o2)方法,比较o1和o2的大小:
    • 如果方法返回正整数,则表示o1大于o2
    • 如果方法返回0,则表示o1等于o2
    • 如果方法返回负整数,则表示o1小于o2
  • 可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。

代码演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Test
public void test4() {
Goods[] arr = new Goods[6];
arr[0] = new Goods("l罗技",299);
arr[1] = new Goods("l雷蛇",399);
arr[2] = new Goods("x小米",99);
arr[3] = new Goods("d戴尔",169);
arr[4] = new Goods("l联想",99);
arr[5] = new Goods("l雷蛇",199);

Arrays.sort(arr, new Comparator<Goods>() {
//商品比较大小的方式:按照商品名称从低到高,再按照商品价格从高到低排序
@Override
public int compare(Goods o1, Goods 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));
}

不得不说,康师傅yyds!