文章目录
一、自然排序 java.lang.Comparable
- 在Java中,如果想要对数组进行自然排序,可以调用
Arrays.sort()
方法进行排序,不过数组元素必须是实现了Comparable接口的类对象(不传入比较器时)
int[] nums = {5,3,4,1,6};
Arrays.sort(nums);
- 因此,如果需要对自定义的类的对象实现自然排序,则需要让该类继承Comparable接口,重写CompareTo方法即可
- String、包装类等实现了Comparable接口,重写了CompareTo()
1. 重写规则
- 当前对象大于形参对象,返回1
- 当前对象等于形参对象,返回0
- 当前对象小于形参对象,返回-1
2. 自定义类实现自然排序
自定义Person类,按照年龄大小进行自然排序:
// 继承Comparable接口,重写CompareTo方法
class Person implements Comparable {
private String name ;
private int age ;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {this.name = name;}
public void setAge(int age) {this.age = age;}
public String getName() {return name;}
public int getAge() {return age;}
// 这里可以使用泛型进行替换
@Override
public int compareTo(Object o){
if(o instanceof Person){
Person person = (Person)o;
return Integer.compare(this.age,person.getAge()); // 可以直接调用包装器的comparaTo方法
}
throw new RuntimeException("传入的数据类型不一致");
}
public String toString(){
return "name: "+this.name+
" age: " + this.age;
}
}
测试运行:
public void test(){
Person[] persons = new Person[5];
Random random = new Random();
for(int i = 0 ; i < persons.length; i ++)
persons[i] = new Person(i+"",random.nextInt(25));
// 排序前:
System.out.println("排序前");
for (Person person : persons) {
System.out.println(person);
}
Arrays.sort(persons);
// 排序后:
System.out.println("排序后");
for (Person person : persons) {
System.out.println(person);
}
}
- 运行结果:
排序前
name: 0 age: 16
name: 1 age: 17
name: 2 age: 2
name: 3 age: 18
name: 4 age: 0
排序后
name: 4 age: 0
name: 2 age: 2
name: 0 age: 16
name: 1 age: 17
name: 3 age: 18
二、自定义排序 比较器:java.util.Comparator
- 当将一个比较器对象作为参数传递给使用Arrays.sort()数组进行排序,此时不需要考虑数组元素是否实现了Comparable接口
- 比较器:实现了Comparator接口的类,该类只需要重写Compare()方法即可
1. 使用背景:
- 某些类没有实现Comparable接口而不方便修改代码
- 实现了Comparable接口的排序规则不适合当前操作
2. 重写规则
- 当o1 大于 o2,返回 1
- 当o1 等于 o2,返回 0
- 当o1 小于 o2,返回 -1
3. 对于上述Person类使用比较器的方式进行比较排序
- 对每个人进行比较,按年龄升序排列;若年龄相同,对姓名按自然排序排列
class PersonComparator implements Comparator{
// 对每个人进行比较,按年龄升序排列;若年龄相同,则比较姓名
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof Person && o2 instanceof Person){
Person p1 = (Person) o1 ;
Person p2 = (Person) o2 ;
if(p1.getAge() == p2.getAge()){
return p1.getName().compareTo(p1.getName());
}
else{
return Integer.compare(p1.getAge(), p2.getAge());
}
}
throw new RuntimeException("传入的数据类型错误");
}
}
测试代码:
@Test
public void Test2(){
Person[] persons = new Person[5];
Random random = new Random();
for(int i = 0 ; i < persons.length; i ++)
// 对年龄进行取余操作,便于观察到年龄相同时,按姓名进行排列
persons[i] = new Person(i+"",random.nextInt(25)%3);
for (Person person : persons) {
System.out.println(person);
}
System.out.println();
Arrays.sort(persons);
for (Person person : persons) {
System.out.println(person);
}
}
- 运行结果:
name: 0 age: 0
name: 1 age: 0
name: 2 age: 1
name: 3 age: 0
name: 4 age: 2
name: 0 age: 0
name: 1 age: 0
name: 3 age: 0
name: 2 age: 1
name: 4 age: 2