# 对象排序
List 可以如下排序
Collections.sort(l);
1
如果是一个 List<String>
那么将是按照自然顺序排序。如果是一个 List<Data>
,它将按时间顺序排序。
这是怎么回事?只要提供一个实现了 Comparable
接口的比较器,就能自动排序了。下表总结了 Java 平台中一些类的比较性
类 | 自然排序 |
---|---|
Byte | 带符号数字 |
Character | 无符号数值 |
Long | 带符号数字 |
Integer | 带符号数字 |
Short | 带符号数字 |
Double | 带符号数字 |
Float | 带符号数字 |
BigInteger | 带符号数字 |
BigDecimal | 带符号数字 |
Boolean | Boolean.FALSE < Boolean.TRUE |
File | 路径名上的系统相关的词典 |
String | 词典 |
Date | 按时间顺序 |
CollationKey | 语言特定词典 |
如果你视图排序一个列表,其中的元素不实现 Comparable
,Collections.sort(list)
将抛出一个 ClassCastException
。
但是你可以指定一个自己的比较器进进行排序,Collections.sort(list, comparator)
# 编写自己的可比较类型
Comparable
接口包括以下方法
public interface Comparable<T> {
public int compareTo(T o);
}
1
2
3
2
3
该方法接收对象与指定对象的进行比较,并根据返回值:等于还是大于指定对象,返回一个负整数,0 ,或则正整数。
如果指定的对象不能与接收对象进行比较,则抛出 ClassCastException
也就是在自定义对象中编写该对象以什么进行一个排序。
class Name implements Comparable<Name> {
private final String firstName, lastName;
public Name(String firstName, String lastName) {
// 根据业务校验
if (firstName == null || lastName == null)
throw new NullPointerException();
this.firstName = firstName;
this.lastName = lastName;
}
public String firstName() {
return firstName;
}
public String lastName() {
return lastName;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Name))
return false;
Name n = (Name) o;
return n.firstName.equals(firstName) && n.lastName.equals(lastName);
}
@Override
public int hashCode() {
return 31 * firstName.hashCode() + lastName.hashCode();
}
@Override
public String toString() {
return firstName + " " + lastName;
}
@Override
public int compareTo(Name n) {
int lastCmp = lastName.compareTo(n.lastName);
return (lastCmp != 0 ? lastCmp : firstName.compareTo(n.firstName));
}
}
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
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
上面的例子说明了以下几点:
Name
对象是不可变的,对于被用作Sets
中的元素或则作为Map
中的键来说,是有必要的- 构造函数检查 null,良好的约束习惯
- 重写
hashCode
方法。且需要重写equals
方法(两个 equals 相等的对象,hashCode 必须相等) - 重写
toString
方法,因此可以能打印良好的阅读格式。这是一个好习惯,特别是对于那些放入集合的对象。
Name 的 compareTo 使用了自然顺序的排序方法。
# 比较器
如果你想按照自定义的顺序来排序的话,可以使用比较器 Collections.sort(list, comparator)
public interface Comparator<T> {
int compare(T o1, T o2);
}
1
2
3
2
3
使用这种方式需要注意的就是:对于放入 TreeSet(Comparator<? super E> comparator)
集合中的时候,
需要注意全面的比较,如果指比对该对象中的 几个属性,那么在插入集合的时候,就有可能造成 bug。
一切都需要根据自己的业务规则来编写比较器。
← Map 接口 SortedSet 接口 →