Comparable
- Comparable 是有泛型的,实现的时候要添加泛型——要比较什么类型就添加什么类型
Collections的sort方法是对集合元素进行自然排序,那么两个元素对象之间就一定要有大小之分。这个大小之分是如何界定的?实际上,在使用Collections的sort排序的集合元素都必须是Comparable接口的实现类,该接口表示其子类是可比较的,因为实现该接口必须重写抽象方法:
compareTo方法
— int compareTo(T t); 该方法用于使当前对象 与给定对象 进行比较。
— 若当前对象 大于 给定对象,那么返回值应为**>0**的整数。——当前对象会排在给定对象的后面——由小到大排序(升序排序)
— 若小于给定对象,那么返回值应为**<0**的整数。——当前对象会排在给定对象的前面
— 若两个对象相等,则应返回0。
- 每个人重写的都可以不一样,只要自己看得懂就好
//重写compareTo()
public int compareTo(Emp o){
if(this.age==o.age){
//年龄一样,根据姓名排序
return this.name.compareTo(o.name);
}
//根据年龄排序
return this.age-o.age;
}
public class Demo06Comparable {
public static void main(String[] args) {
int[]arr={2,3,4,6,9,21,12,31};
Arrays.sort(arr);//排序方法按数字顺序
System.out.println(Arrays.toString(arr));//[2, 3, 4, 6, 9, 12, 21, 31]
String[] strArr={"zhnagsan","lisi","zhaowu","wanrong"};
Arrays.sort(strArr);//排序方法按字母先后顺序
System.out.println(Arrays.toString(strArr));//[lisi, wanrong, zhaowu, zhnagsan]
People[] ps={new People("zhangsan",18,'m'),
new People("lisi",20,'m'),
new People("zhaowu",33,'m')};
//自己定义的数组的排序要实现Comparable,这属于类型转换异常
Arrays.sort(ps);
System.out.println(Arrays.toString(ps));//ClassCastException
//将People对象强制转换成Comparable类型
//[People{name='zhangsan', age=18, gendar=m}, People{name='lisi', age=20, gendar=m}, People{name='zhaowu', age=33, gendar=m}]
}
}
public class People implements Comparable<People>{
private String name;
private int age;
private char gendar;
public People(String name,int age,char gendar){
this.name=name;
this.age=age;
this.gendar=gendar;
}
public String getName(){
return name;
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", age=" + age +
", gendar=" + gendar +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
People people = (People) o;
return age == people.age && gendar == people.gendar && Objects.equals(name, people.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age, gendar);
}
@Override
/**
* this和o比较
* @return 大于0,this>o
* 等于0,this=o
* 小于0,this<o
*/
public int compareTo(People o) {
if(this.age==o.age){
//年龄一样,根据姓名排序
return this.name.compareTo(o.name);
}
return this.age-o.age;
}
}
Comparator
- 比较器,单独实现 compare
- 当指定Comparator的时候,优先使用Comparator
- 如果没有指定Comparator,那么必须实现Comparable
public static void main(String[] args) {
Set<String> set=new TreeSet<String>();
set.add("strong");
set.add("height");
set.add("width");
set.add("weak");
set.add("beautiful");
//按照字典顺序排序
System.out.println(set);//[beautiful, height, strong, weak, width]
//重写了equals和hashCode方法,所以People在hashSet中不允许重复的
//TreeSet不允许重复,看compareTo方法
//若不能修改People类,有要求People对象在TreeSet中按照姓名排序,如果名字一样的时候,再根据年龄排序
//用比较器 comparator
Comparator comparator=new MyComparator();
Set<People>ps=new TreeSet<People>();
ps.add(new People("zhangsan",18,'m'));
ps.add(new People("lisi",20,'m'));
ps.add(new People("lisi",20,'m'));
ps.add(new People("zhaowu",33,'m'));
System.out.println(ps);//[People{name='zhangsan', age=18, gendar=m}, People{name='lisi', age=20, gendar=m}, People{name='zhaowu', age=33, gendar=m}]
//修改compareTo方法的返回值为0,返回一个对象
}
}
class MyComparator implements Comparator<People>{
/**
* 比较o1,o2对象
* @param o1
* @param o2
* @return>0 说明o1>o2
* <0 说明o1<o2
* =0 说明o1=o2
*/
@Override
public int compare(People o1, People o2) {
return o1.getName().compareTo(o2.getName());
}
}