目的
学会使用Comparable接口与Comparator接口。
掌握Comparable、Comparator与Arrays.sort之间的关系
实验准备
package persons;
public class Person {
private String name;
private int age;
private int gender;
private int id;
private static int count;//类属性
public static void main(String[] args) {
Person x1 = new Person();
System.out.println(x1.getId());
Person x2 = new Person();
System.out.println(x2.getId());
System.out.println("count="+Person.getCount());
for(int i =1; i<10;i++){
System.out.println(new Person());
}
System.out.println("count="+Person.getCount());
}
public Person() {
}
public static int getCount() {
return count;
}
{
id = count;
count++;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", gender=" + gender
+ ", id=" + id + "]";
}
public Person(String name, int age){
this.name = name;
this.age = age;
}
public Person(String name, int age, int gender) {
this(name,age);
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
public int getId() {
return id;
}
}
实验步骤与常见问题及解决过程
让Person可比较
让Person类(name, age)实现Comparable接口
在Person类的类声明行添加"implements Comparable<Person>",表示该类实现了Comparable接口,并指定接口泛型为Person。
在Person类中实现compareTo方法,该方法用于定义Person对象之间的比较规则。
1.@Override
2. public int compareTo(Person o) {
3. return this.age - o.getAge();
4. }
按age比较,然后使用Arrays.sort升、降序排序
创建一个Person数组
1.Person[] persons = new Person[5];
2. persons[0] = new Person("a",5);
3. persons[1] = new Person("d",3);
4. persons[2] = new Person("b",4);
5. persons[3] = new Person("c",18);
6. persons[4] = new Person("aa",2);
升序
1.Arrays.sort(persons);
2. System.out.println(Arrays.toString(persons));
降序
如果需要进行降序排序,则需要使用Comparator接口来定义自定义比较规则。
1.Arrays.sort(persons, Comparator.reverseOrder());
2. System.out.println(Arrays.toString(persons));
按name比较,然后排序。需考虑name为null的情况
让Person类实现Comparable接口,并在compareTo方法中按姓名比较两个Person对象。在比较过程中,需要特别处理name为null的情况。
1.@Override
2.public int compareTo(Person other) {
3. if (this.name == null && other.getName() == null) {
4. return 0;
5. } else if (this.name == null) {
6. return -1;
7. } else if (other.getName() == null) {
8. return 1;
9. } else {
10. return this.name.compareTo(other.getName());
11. }
12.}
首先判断两个Person对象的name是否都为null,如果是,则认为它们相等,返回0。如果只有一个Person对象的name为null,则将其排在前面(返回-1),反之排在后面(返回1)。如果两个Person对象的name都不为null,则按照name的比较结果进行排序。
通过调用Arrays.sort方法进行排序后,people数组中的Person对象将按照姓名进行排序。对于name为null的Person对象,将排在其他对象之前。
在public int compareTo(Person o) {中编写if (this == null) return -1是否合理?this可能为null吗?
不合理,在Java中,this关键字永远不会为null。
如果perosons数组中某个元素为null,排序的时候会碰到什么问题?
如果persons数组中的某个元素为null,在排序过程中可能会出现NullPointerException异常。Arrays.sort方法在排序对象数组时,会调用数组元素的compareTo方法来进行比较和排序。如果数组中存在null元素,null无法调用实例方法,因此会导致NullPointerException异常。为了避免这种异常,可以在排序之前先进行对null元素的检查,可以通过使用Comparator接口的自定义比较器来处理null元素。
1.Arrays.sort(persons, Comparator.nullsLast(Comparator.naturalOrder()));
使用Comparator.nullsLast方法,它允许将null元素放在排序结果的末尾。然后使用Comparator.naturalOrder来按照自然顺序对非null元素进行比较。这样,persons数组中的null元素将会被放在排序结果的最后。通过这种方式,可以避免NullPointerException异常的出现。
总结
在本次实验中,我们讨论了如何处理数组中某个元素为null的情况。我们使用了Comparator来对Person对象进行排序,并处理了null值的情况。具体而言,我们介绍了三种处理null值的方法:使用Comparator.nullsLast方法将null元素放在排序结果的末尾;使用Comparator.nullsFirst方法将null元素放在排序结果的开头;自定义比较器来处理null元素。我们还展示了如何使用匿名类和Lambda表达式来实现Comparator接口,以简化代码并提高可读性。