一.Comparable接口
请实现Comparable接口,实现一个List集合中的People 按姓名排序:
public class People implements Comparable{
public People(String name,int age){
this.age = age;
this.name = name;
}
public int age;
public String name;
public int compareTo(Object obj) {
People people = (People) obj;
return name.compareTo(people.name);
}
}
哈哈,我来看下 str.comPareto(str)里面到底是怎么实现的:
/*
* @param anotherString the {@code String} to
* be compared.is equal to
* this string; a value less than {@code 0} if this string
* is lexicographically less than the string argument; and
* a value greater than {@code 0} if this string is
* lexicographically greater than the string argument.
*/
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) { //从0开始,不能超过小长度lim
char c1 = v1[k];//从新装载,代码六六的
char c2 = v2[k];//六六的
if (c1 != c2) {
return c1 - c2;//返回字符之间的差值
}
k++;
}
return len1 - len2;//返回字符之间的长度
//告诉我们一个道理,同样长的字符,谁的字符顺序在后就在后,
// 例如:"abc"和"abf",那么"abf"肯定在后了。
// 还比如:"abcd"和"abcda",那"abcda"肯定在后面
}
好了,不扯了,解题要紧。
package com.test.comparator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
List list = new ArrayList();
People peoplea = new People("a", 15);
People peoplec = new People("abc", 14);
People peoplef = new People("abf", 16);
People peopleg = new People("g", 19);
People peopleh = new People("h", 10);
People peoplet = new People("t", 8);
People peopleb = new People("b", 17);
list.add(peoplea);
list.add(peoplec);
list.add(peoplef);
list.add(peopleg);
list.add(peopleh);
list.add(peoplet);
list.add(peopleb);
Collections.sort(list);
for (int i = 0; i<list.size();i++){
System.out.println(
" name = "+((People)list.get(i)).name+
" age = " ((People)list.get(i)).age);
}
}
}
输出结果:
name = a age = 15
name = abc age = 14
name = abf age = 16
name = b age = 17
name = g age = 19
name = h age = 10
name = t age = 8
那按年龄排序呢?
根据 compareTo 中的原理,return c1-c2,哈哈,看下面实现。
package com.test.comparator;
public class People implements Comparable{
public People(String name,int age){
this.age = age;
this.name = name;
}
public int age;
public String name;
public int compareTo(Object obj) {
People people = (People) obj;
return age-people.age;//改动这里
}
}
输出结果:
name = t age = 8
name = h age = 10
name = abc age = 14
name = a age = 15
name = abf age = 16
name = b age = 17
name = g age = 19
二.使用Comparator比较器
接题:使用comparator对List中的按姓名排序,姓名相等的按年龄排序。
有木有挑战。看实现:
package com.test.comparator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
List list = new ArrayList();
People peoplea = new People("a", 15);
People peoplec = new People("abc", 14);
People peoplef = new People("abf", 16);
People peopleg = new People("a", 19);//改动
People peopleh = new People("h", 10);
People peoplet = new People("a", 8);//改动
People peopleb = new People("a", 17);//改动
list.add(peoplea);
list.add(peoplec);
list.add(peoplef);
list.add(peopleg);
list.add(peopleh);
list.add(peoplet);
list.add(peopleb);
Collections.sort(list,new MyComparator());//改动
for (int i = 0; i<list.size();i++){
System.out.println(
"name = "+((People)list.get(i)).name+
"age = "+((People)list.get(i)).age);
}
}
}
package com.test.comparator;
import java.util.Comparator;
public class MyComparator implements Comparator{
public int compare(Object obj1, Object obj2) {
People p1 = (People) obj1;
People p2 = (People) obj2;
int result = p1.name.compareTo(p2.name);
if (result > 0){ //字母顺序
return 1;
} else if (result == 0){ //姓名相同
if (p1.age == p2.age){
return 0;
} else if (p1.age > p2.age){ // 从小到大
return 1;
} else {
return -1;
}
//return 0;
} else {
return -1;
}
}
}
输出结果:
name = a age = 8
name = a age = 15
name = a age = 17
name = a age = 19
name = abc age = 14
name = abf age = 16
name = h age = 10
我还要想同名的 年龄按倒序排,怎么弄?
看下Comparator源码
public interface Comparator<T> {
/*
* @param o1 the first object to be compared.
* @param o2 the second object to be compared.
* @return a negative integer, zero, or a positive
* integer as the first argument is less than, equal to,
* or greater than the second.
* @throws NullPointerException if an argument is null and
* this comparator does not permit null arguments
* @throws ClassCastException if the arguments' types
* prevent them from being compared by this comparator.
*/
int compare(T o1, T o2);
a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
负整数 0 正整数 对应小于 等于 大于
也就是说,当 o1 < o2 return -1,;o1 == o2 retrun 0 ;
o1 >o3 return 1;
隐藏一句话:按照此返回的话,集合正序排序,从小到大,如果要从大到小,o1 < o2 return 1 (改动);o1 == o2 retrun 0 ;
o1 >o3 return -1(改动); 即可
package com.test.comparator;
import java.util.Comparator;
public class MyComparator implements Comparator{
public int compare(Object obj1, Object obj2) {
People p1 = (People) obj1;
People p2 = (People) obj2;
int result = p1.name.compareTo(p2.name);
if (result > 0){
return 1;
} else if (result == 0){
if (p1.age == p2.age){
return 0;
} else if (p1.age > p2.age){
return -1; //改动
} else {
return 1;//改动
}
} else {
return -1;
}
}
}
输出结果:
name = a age = 19
name = a age = 17
name = a age = 15
name = a age = 8
name = abc age = 14
name = abf age = 16
name = h age = 10
总结一下:实现排序有两种方式,一种是实现Comparable接口,还有就是实现 Comparator比较器。第一种没有第二种灵活,主要体现在 比较多个参数,比如比完姓名还要比年龄,还体现在顺序和倒序上面,Comparator比较器可以灵活切换倒序和顺序! (> return 1; < return -1; = return 0)
完毕,谢谢!