Comparable与Comparator
Comparable与Comparator
中文,字母,数字的比较:
①字符串字母比较:
"ba">"ab"
(英文按照ASCII码比较),因为‘a’的是ASCII码是97,而‘b’的是98。
“ba”.compareTo("ab")
。 返回1。“ca”.compareTo("ab")
,就返回2。
②数字比较:
3.compateTo(5)
,返回 -1; 5.compateTo(3)
,返回1; 相等返回0
//Integer中实现的compartTo方法
public static int compare(int x, int y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
③中文比较:
中文是按照Unicode编码比较的。 eg: "空".compareTo("冰"),会返回10442。其中“空”的Uiicode的编码为\u7a7a,“冰”的Uiicode的编码为\u51b0,
它们是16进制的。也就是0x7a7a-0x51b0,在转换为十进制就是10442。
综合上述CompareTo方法:
public int compareTo(T o);
e1.compareTo(e2) > 0 即 e1 > e2
e1.compareTo(e2) = 0 即 e1 = e2
e1.compareTo(e2) < 0 即 e1 < e2
这里:调用对象总是减去传入的对象,转换为ASCll进行相减。
**String中compareTo实现:**即String默认是从小到大排序
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
**Integer中compareTo实现:**即Integer默认是从小到大排序
public static int compare(int x, int y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
1、Comparable
Compareable更像是**自然排序,**使用一个类继承自Compareable
接口,并实现其中compareTo
的方法
public class Student implements Comparable<Student>{
public String name;
public Integer age;
public Student() {
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
//getter
//setter
//toString
//按照姓名从小到大排序
//@Override
//public int compareTo(Student o) {
// return name.compareTo(o.name);
//}
//按照姓名从大到下排序
//@Override
//public int compareTo(Student o) {
// return o.name.compareTo(name);
//}
//按照姓名从小到大排序,姓名相同的按照年龄从大到小排序
@Override
public int compareTo(Student o) {
//姓名相同
if (name.equals(o.name)) {
//按照age从大到小排序
return o.age.compareTo(age);
}else{
//姓名不相同
//按照姓名从小到大排序
return name.compareTo(o.name);
}
}
}
public static void main(String[] args) {
List<Student> list = Arrays.asList(
new Student("lc", 10),
new Student("lc", 9),
new Student("lc", 11),
new Student("zs", 8),
new Student("ls", 25),
new Student("ww", 19),
new Student("zl", 20)
);
System.out.println("排序之前:"+list);
Collections.sort(list);
System.out.println("排序之后:"+list);
}
排序之前:[
{name='lc', age=10},
{name='lc', age=9},
{name='lc', age=11},
{name='zs', age=8},
{name='ls', age=25},
{name='ww', age=19},
{name='zl', age=20}]
排序之后:[
{name='lc', age=11},
{name='lc', age=10},
{name='lc', age=9},
{name='ls', age=25},
{name='ww', age=19},
{name='zl', age=20},
{name='zs', age=8}]
先按照姓名从小到大排序,如果姓名相同则按照年龄从大到小排序
使用Collection.sort()方法时:
public static <T extends Comparable<? super T>> void sort(List<T> list) {
list.sort(null);
}
必须传入一个实现Comparable
或实现comparator
接口的类。默认使用的是重写compareTo()
的类中的方法
2、Comparator
Comparator更像是定制排序. 当我们的接口没有实现Comparable
接口时,我们可以在调用Collections.sort
定制其接口
public class Teacher {
public String name;
public Integer age;
public Teacher() {
}
public Teacher(String name, Integer age) {
this.name = name;
this.age = age;
}
//getter
//setter
//toString
}
public static void main(String[] args) {
List<Teacher> list = Arrays.asList(
new Teacher("lc", 10),
new Teacher("lc", 9),
new Teacher("lc", 11),
new Teacher("zs", 8),
new Teacher("ls", 25),
new Teacher("ww", 19),
new Teacher("zl", 20)
);
System.out.println("排序之前:"+list);
Collections.sort(list, new Comparator<Teacher>() {
@Override
public int compare(Teacher o1, Teacher o2) {
//如果姓名相同
if (o1.name.equals(o2.name)) {
//按照年龄小到大排序
return o1.age.compareTo(o2.age);
}else{
//姓名不相同,按照姓名从大到小排序
return o2.name.compareTo(o1.name);
}
}
});
System.out.println("排序之后:"+list);
}
按照姓名从大到小排序,如果姓名相同,则按照年龄从小到大排序
当我们定制其接口时,使用collection.sort()
public static <T> void sort(List<T> list, Comparator<? super T> c) {
list.sort(c);
}
第一个参数为比较的集合,第二参数为传入的自定义比较器
3、使用场景比较
注意:Comparator定制的排序规则高于comparable自然排序的规则
实现Comparable接口的方式比实现Comparator接口的耦合性要强一些,如果要修改比较算法,要修改Comparable接口的实现类,而实现Comparator的类是在外部进行比较的,不需要对实现类有任何修改。