<!--此处接上周-->

3、相关接口

对象的排序,可以通过以下两种方法:

1、实现Comparable接口,重写compareTo方法;

2、Comparator<>比较器接口,重写compare方法;

区别:Comparator位于包java.util下,而Comparable位于包java.lang下,Comparable接口将比较代码嵌入自身类中,而后者在一个独立的类中实现比较。

(1)Comparator比较器接口

想要对一个类的对象进行排序,需要写一个实现类实现此接口,调用Arrays.sort()或Collection.sort()进行排序,先重写Comparator<>的实现类中的compare方法,然后将排序的规则写在方法中。

compare(T o1,T o2)方法排序规则

例如比较年龄:

o1.getAge()>o2.getAge()返回 1,

o1.getAge()<o2.getAge()返回 -1,

相等返回0,可继续通过其它属性来比较

最后会按照年龄从小到大来输出。

下面举例比较员工类Emps:

1、先写一个员工类

 1 package comparator;
 2  3  public class Emps {
 4      private String name;
 5      private int age;
 6      private int sal;
 7      public Emps(String name, int age, int sal) {
 8          this.name = name;
 9          this.age = age;
10          this.sal = sal;
11      }
12      public Emps() {}
13      public String getName() {
14          return name;
15      }
16      public void setName(String name) {
17          this.name = name;
18      }
19      public int getAge() {
20          return age;
21      }
22      public void setAge(int age) {
23          this.age = age;
24      }
25      public int getSal() {
26          return sal;
27      }
28      public void setSal(int sal) {
29          this.sal = sal;
30      }
31      @Override
32      public String toString() {
33          return "Emp [ename=" + name + ", age=" + age + ", sal=" + sal + "]";
34      }
35  }

2、然后是实现类EmpsComparator

 
 1 package comparator;
 2  import java.util.Comparator;
 3  4  public class EmpsComparator implements Comparator<Emps> {
 5      @Override
 6      public int compare(Emps o1, Emps o2) {
 7          //比较年龄
 8          if(o1.getAge()>o2.getAge()){
 9              return 1;
10          }else if(o1.getAge()<o2.getAge()){
11              return -1;
12          }else{
13              //年龄相同,比较工资
14              if(o1.getSal()>o2.getSal()){
15                  return 1;
16              }else if(o1.getSal()<o2.getSal()){
17                  return -1;
18              }
19          }
20          return 0;
21      }
22  }

 

3、测试

 1  package comparator;
 2  import java.util.Arrays;
 3  4  public class Test {
 5      public static void main(String[] args) {
 6          Emps[] emps={
 7                  new Emps("佐菲",35,30000),//姓名,年龄,工资
 8                  new Emps("赛文",33,28000),
 9                  new Emps("杰克",33,25000),
10                  new Emps("艾斯",32,24000),
11                  new Emps("泰罗",30,22000),
12          };
13          Arrays.sort(emps,new EmpsComparator());
14          for (Emps e:emps) {
15              System.out.println(e);
16          }
17      }
18  }

 

 

4、输出

上面代码是通过Arrays.sort(emps,new EmpsComparator())进行排序的,若没有new EmpsComparator()比较规则会显示ClassCastException异常,这默认是从小到大排序的,若想从大到小,只需将返回值1和-1调换。

(2)Comparable接口

此接口强行对实现它的每个类的对象进行整体排序。此排序被称为该类的自然排序 ,类的 compareTo方法被称为它的自然比较方法 。实现此接口的对象列表(和数组)可以通过 Collections.sort(和 Arrays.sort)进行自动排序。

 1  package comparator;
 2  3  public class Emp implements Comparable<Emp>{
 4      private String name;
 5      private int age;
 6      private int sal;
 7      
 8      @Override
 9      public int compareTo(Emp o) {
10          //比较年龄
11          if(this.getAge()>o.getAge()){
12              return 1;
13          }else if(this.getAge()<o.getAge()){
14              return -1;
15          }else{
16              //年龄相同,比较工资
17              if(this.getSal()>o.getSal()){
18                  return 1;
19              }else if(this.getSal()<o.getSal()){
20                  return -1;
21              }
22          }
23          return 0;
24      }
25      
26      public Emp(String name, int age, int sal) {
27          this.name = name;
28          this.age = age;
29          this.sal = sal;
30      }
31      public Emp() {
32      }
33      public String getName() {
34          return name;
35      }
36      public void setName(String name) {
37          this.name = name;
38      }
39      public int getAge() {
40          return age;
41      }
42      public void setAge(int age) {
43          this.age = age;
44      }
45      public int getSal() {
46          return sal;
47      }
48      public void setSal(int sal) {
49          this.sal = sal;
50      }
51      @Override
52      public String toString() {
53          return "Emp [ename=" + name + ", age=" + age + ", sal=" + sal + "]";
54      }
55 56      
57  }
58  package comparator;
59  import java.util.Arrays;
60  public class Test {
61      public static void main(String[] args) {
62          Emp[] emps={
63                  new Emp("佐菲",35,30000),
64                  new Emp("赛文",33,28000),
65                  new Emp("杰克",33,25000),
66                  new Emp("艾斯",32,24000),
67                  new Emp("泰罗",30,22000),
68          };
69          Arrays.sort(emps);
70          for (Emp e:emps) {
71              System.out.println(e);
72          }
73      }
74  }

 

此接口只需用要排序的类来实现它,然后重写compareTo方法即可,关于这个方法里面是用本类对象和其他类对象进行比较,然后测试类中只需写Arrays.sort(emps);即可比较的规则跟Comparator相同

int compareTo(T o) 比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。

4、接口总结

让规范和实现分离正是接口的好处,让系统的各组件之间通过接口耦合,是一种松耦合的设计。软件系统各模块之间也应该采用这种面向接口的耦合,为系统提供更好的可扩展性和维护性。

抽象类与接口的区别

1、组成上:抽象类=普通类的组成+【抽象方法】,接口中只能包含抽象方法,常量,静态方法、默认方法。

2、抽象类和接口均不能直接实例化。

3、接口看成是对抽象类的再次抽象。

4、抽象类受到继承单根性的限制,接口可以多继承。

5、接口可以更好的实现多态。接口一般用于系统间的解耦。一般情况使用面向接口编程。

6、接口不包含构造函数;抽象类可以包含构造函数,抽象类里的构造函数并不是用于创建对象,而是让其子类调用这些构造函数来完成属于抽象类的初始化操作。

7、能用接口地方尽量使用而不要使用抽象类。

8、抽象类一般用于模板设计、适配器设计。

 

今天就总结到这了,下周继续!!!!!奥里给!!!