金沙澳门官网7817网址java学习笔记13–相比器(Comparable、Comparator)

①   TreeMap类通过使用红黑树实现Map接口,树映射保证它的元素按关键字升序排序,TreeMap类通过使用红黑树实现Map接口,TreeMap实现SortedMap并且扩展AbstractMap,实现类基于 compareTo() 方法的排序被称为自然排序,如果一个数组中的对象实现了 Compareable 接口,此方法可以直接对对象数组进行排序,可以直接使用java.util.Arrays类进行数组的排序操作

Map容器——TreeMap及常用API,Comparator和Comparable接口,treemapcomparator

TreeMap及常用API

①   TreeMap类通过应用红黑树达成Map接口;

②   TreeMap提供按排序依次存款和储蓄键/值对的实用手腕,同时同意急迅搜索;

③   不像散列(HashMap),树映射保障它的因素按首要性字升序排序;

④   TreeMap构造方法:

a)   TreeMap()

b)   TreeMap(Comparator comp)

c)   TreeMap(Map m)

d)   TreeMap(SortedMap sm)

⑤   TreeMap达成SortedMap况且扩充AbstractMap,它自个儿并未概念别的方法;

1         TreeMap<String,String> tmap=new TreeMap<String, String>();
2         tmap.put("zhang", "张三");
3         tmap.put("jack", "小明");
4         tmap.put("mary", "小红");
5         tmap.put("free", "小叶");
6         tmap.put("mary", "小草");
7         //tmap.put(null,"小草");//键不能传入null,会抛异常
8         System.out.println(tmap);
9     

私下认可依据键的当然顺序升序输出

输出结果:

{free=小叶, jack=小明, mary=小草, zhang=张三}

 

出口全部键值对

1     Set<Entry<String,String>> entrys=tmap.entrySet();
2         for(Entry<String,String> entry:entrys){
3             System.out.println(entry.getKey()+"--"+entry.getValue());
4         }

出口结果:

free–小叶

jack–小明

mary–小草

zhang–张三

 

编排五个Person类

 1 class Person{
 2     private String name;
 3     private int age;
 4     public Person(String name, int age) {
 5         super();
 6         this.name = name;
 7         this.age = age;
 8     }
 9     public String getName() {
10         return name;
11     }
12     public void setName(String name) {
13         this.name = name;
14     }
15     public int getAge() {
16         return age;
17     }
18     public void setAge(int age) {
19         this.age = age;
20     }
21 }

在主方法中创制并添澳成分,输出

1         TreeMap<Person,String> pdata=new TreeMap<Person, String>();
2         pdata.put(new Person("zhangsan",20), "张三");
3         pdata.put(new Person("lisi",25), "李四");
4         pdata.put(new Person("wangwu",30), "王五");
5         pdata.put(new Person("zhangsan",33), "张三");
6         System.out.println(pdata);

运作结果:

出错,原因是Person类中未有兑现compareTo``(T o)``比较方法

方法一:实现Comparable接口

 1 class Person implements
Comparable<Person>{ 2 3 } 

重写方法如下:按年龄实行排序

1     @Override
2     public int compareTo(Person o) {
3         if (this.age - o.getAge() > 0) {
4             return 1;
5         } else if (this.age - o.getAge() < 0) {
6             return -1;
7         }
8         return 0;
9     }

下一场再进行,输出结果:

{[email protected]=张三,
[email protected]=李四,
[email protected]=王五,
[email protected]=张三}

 

完整的Person类如下:

金沙澳门官网7817网址 1 1 class
Person implements Comparable<Person> { 2 private String name; 3
private int age; 4 5 public Person(String name, int age) { 6 super(); 7
this.name = name; 8 this.age = age; 9 } 10 11 public String getName() {
12 return name; 13 } 14 15 public void setName(String name) { 16
this.name = name; 17 } 18 19 public int getAge() { 20 return age; 21 }
22 23 public void setAge(int age) { 24 this.age = age; 25 } 26 27
@Override 28 public int compareTo(Person o) { 29 if (this.age –
o.getAge() > 0) { 30 return 1; 31 } else if (this.age – o.getAge()
< 0) { 32 return -1; 33 } 34 return 0; 35 } 36 } View Code

 

主意二:Person中不选取Comparable接口,在主方法中选拔佚名内部类:

 1 TreeMap<Person, String> pdata = new TreeMap<Person, String>(new Comparator<Person>() {
 2 
 3             @Override
 4             public int compare(Person o1, Person o2) {
 5                 if(o1.getAge()>o2.getAge()){
 6                     return 1;
 7                 }
 8                 else if(o1.getAge()<o2.getAge()){
 9                     return -1;
10                 }
11                 return 0;
12             }
13         });

输出结果与地点同样

 

上边都以使用int年龄举办排序,使用String名字排序方法如下:

1         @Override
2             public int compare(Person o1, Person o2) {
3                 return o1.getName().compareTo(o2.getName());
4             }

出口结果:

{[email protected]=李四,
[email protected]=王五,
[email protected]=张三}

因为zhangsan同样则被沟通了,修改如下:

 1         @Override
 2             public int compare(Person o1, Person o2) {
 3                 if(o1.getName().compareTo(o2.getName())>0){
 4                     return 1;
 5                 }
 6                 else if(o1.getName().compareTo(o2.getName())<0){
 7                     return -1;
 8                 }
 9                 else{
10                     //年龄相同时还是会替换
11                     return o1.getAge()-o2.getAge();
12                 }
13             }

Comparator和Comparable接口

①   TreeMap的key存款和储蓄引用类型数据,须要满意一定原则

a)   要么引用类型完成Comparable接口

b)   要么为该TreeMap容器提供实现Comparator接口的相比器对象

TreeMap及常用API ① TreeMap类通过动用红黑树实现Map接口; ②
TreeMap提供按排序…

TreeMap及常用API

转自:

java学习笔记13–比较器(Comparable、Comparator)

分类:
JAVA 2013-05-20 23:20 3296人阅读 评论(0)
收藏 举报

Comparable接口的效应

事先Arrays类中留存sort()方法,此格局能够平昔对目的数组开始展览排序。

 

Comparable接口

能够一向运用java.util.Arrays类举办数组的排序操作,但指标所在的类必须兑现Comparable接口,用于钦命排序接口。

Comparable接口的概念如下:

public  interface  Comparable<T>{

        public  int compareTo(T  o);

}

此办法重返三个int类型的数码,不过此int的值只可以是霎时三种:

1:表示大于

-1:表示小于

0:表示至极

 

渴求:定义三个学员类,里面有姓名,年龄,战绩三特性格,须求按战表由高到低排序,假诺战表杰出,则遵照年龄由低到高排序。

[java] view
plaincopy

  1. package com.itmyhome;  
  2.   
  3. import java.util.Arrays;  
  4.   
  5. class Student implements Comparable<Student>{  
  6.     private String name;  
  7.     private int age;  
  8.     private float score;  
  9.       
  10.     public Student(String name,int age,float score){  
  11.         this.name = name;  
  12.         this.age = age;  
  13.         this.score = score;  
  14.     }  
  15.       
  16.     @Override  
  17.     public int compareTo(Student stu) {  //覆写compareTo方法实现排序准绳的选取  
  18.         if(this.score>stu.score){  
  19.             return -1;  
  20.         }else if(this.score<stu.score){  
  21.             return 1;  
  22.         }else{  
  23.             if(this.age>stu.age){  
  24.                 return 1;  
  25.             }else if(this.age<stu.age){  
  26.                 return -1;  
  27.             }else{  
  28.                 return 0;  
  29.             }  
  30.         }  
  31.     }  
  32.       
  33.     public String toString(){  
  34.         return “姓名:”+this.name+”, 年龄:”+this.age+”, 成绩:”+this.score;  
  35.     }  
  36.       
  37.     public String getName() {  
  38.         return name;  
  39.     }  
  40.     public void setName(String name) {  
  41.         this.name = name;  
  42.     }  
  43.     public int getAge() {  
  44.         return age;  
  45.     }  
  46.     public void setAge(int age) {  
  47.         this.age = age;  
  48.     }  
  49.     public float getScore() {  
  50.         return score;  
  51.     }  
  52.     public void setScore(float score) {  
  53.         this.score = score;  
  54.     }  
  55.       
  56.       
  57. }  
  58.   
  59. public class T {  
  60.     public static void main(String[] args) throws Exception{  
  61.         Student stu[] = {new Student(“张三”,22,80f)  
  62.                         ,new Student(“李四”,23,83f)  
  63.                         ,new Student(“王五”,21,80f)};  
  64.           
  65.         Arrays.sort(stu);   //举办排序操作  
  66.         for (int i = 0; i < stu.length; i++) {  
  67.             Student s = stu[i];  
  68.             System.out.println(s);  
  69.         }  
  70.     }  
  71. }  

深入分析比较器的排序原理

实在相比器的操作,就是常事听到的二叉树的排序算法。

排序的基本原理:使用第八个因素作为根节点,之后如果前边的剧情比根节点小,则放在左子树,借使剧情比根节点的从头到尾的经过要大,则位居右子树。

[java] view
plaincopy

  1. package com.itmyhome;  
  2.   
  3. class BinaryTree {  
  4.     class Node { // 声美素佳儿(Friso)个节点类  
  5.         private Comparable data; // 保存具体的始末  
  6.         private Node left; // 保存左子树  
  7.         private Node right; // 保存右子树  
  8.   
  9.         public Node(Comparable data) {  
  10.             this.data = data;  
  11.         }  
  12.   
  13.         public void addNode(Node newNode) {  
  14.             // 显著是坐落左子树仍然右子树  
  15.             if (newNode.data.compareTo(this.data) < 0) { // 内容小,放在左子树  
  16.                 if (this.left == null) {  
  17.                     this.left = newNode; // 间接将新的节点设置成左子树  
  18.                 } else {  
  19.                     this.left.addNode(newNode); // 继续向下推断  
  20.                 }  
  21.             }  
  22.             if (newNode.data.compareTo(this.data) >= 0) { // 放在右子树  
  23.                 if (this.right == null) {  
  24.                     this.right = newNode; // 未有右子树则将此节点设置成右子树  
  25.                 } else {  
  26.                     this.right.addNode(newNode); // 继续向下判定  
  27.                 }  
  28.             }  
  29.         }  
  30.   
  31.         public void printNode() { // 输出的时候利用中序遍历  
  32.             if (this.left != null) {  
  33.                 this.left.printNode(); // 输出左子树  
  34.             }  
  35.             System.out.print(this.data + “\t”);  
  36.             if (this.right != null) {  
  37.                 this.right.printNode();  
  38.             }  
  39.         }  
  40.     };  
  41.   
  42.     private Node root; // 根元素  
  43.   
  44.     public void add(Comparable data) { // 插手成分  
  45.         Node newNode = new Node(data); // 定义新的节点  
  46.         if (root == null) { // 未有根节点  
  47.             root = newNode; // 第五个因素作为根节点  
  48.         } else {  
  49.             root.addNode(newNode); // 明显是放在左子树还是放在右子树  
  50.         }  
  51.     }  
  52.   
  53.     public void print() {  
  54.         this.root.printNode(); // 通过根节点输出  
  55.     }  
  56. };  
  57.   
  58. public class T2 {  
  59.     public static void main(String args[]) {  
  60.         BinaryTree bt = new BinaryTree();  
  61.         bt.add(8);  
  62.         bt.add(3);  
  63.         bt.add(3);  
  64.         bt.add(10);  
  65.         bt.add(9);  
  66.         bt.add(1);  
  67.         bt.add(5);  
  68.         bt.add(5);  
  69.         System.out.println(“排序之后的结果:”);  
  70.         bt.print();  
  71.     }  
  72. };  

 

另一种相比器:Compartor

设若二个类已经开放到位,可是在此类创立的开始时期并从未落到实处Comparable接口,此时早晚是力所不比张开对象排序操作的,所感觉了化解这一的标题,java又定义了另二个相比器的操作接口
Comparator 此接口定义在java.util包中,接口定义如下:

public  interface  Comparator<T>{

                 public  int  compare(T o1,T o2);

                 boolean  equals(Object  obj);

}

MyComparator.java

[java] view
plaincopy

  1. package com.itmyhome;  
  2.   
  3. import java.util.Comparator;  
  4.   
  5. public class MyComparator implements Comparator<Student> {  //达成比较器  
  6.   
  7.     @Override  
  8.     public int compare(Student stu1, Student stu2) {  
  9.         // TODO Auto-generated method stub  
  10.         if(stu1.getAge()>stu2.getAge()){  
  11.             return 1;  
  12.         }else if(stu1.getAge()<stu2.getAge()){  
  13.             return -1;  
  14.         }else{  
  15.             return 0;  
  16.         }  
  17.     }  
  18.   
  19. }  

 

[java] view
plaincopy

  1. package com.itmyhome;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Arrays;  
  5. import java.util.Collections;  
  6. import java.util.List;  
  7.   
  8. class Student {  
  9.     private String name;  
  10.     private int age;  
  11.       
  12.     public Student(String name,int age ){  
  13.         this.name = name;  
  14.         this.age = age;  
  15.     }  
  16.       
  17.     public String toString(){  
  18.         return “姓名:”+this.name+”, 年龄:”+this.age;  
  19.     }  
  20.       
  21.     public String getName() {  
  22.         return name;  
  23.     }  
  24.     public void setName(String name) {  
  25.         this.name = name;  
  26.     }  
  27.     public int getAge() {  
  28.         return age;  
  29.     }  
  30.     public void setAge(int age) {  
  31.         this.age = age;  
  32.     }  
  33. }  
  34.   
  35. public class T {  
  36.     public static void main(String[] args) throws Exception{  
  37.         Student stu[] = {new Student(“张三”,23)  
  38.                         ,new Student(“李四”,26)  
  39.                         ,new Student(“王五”,22)};  
  40.         Arrays.sort(stu,new MyComparator());             //对象数组举行排序操作  
  41.           
  42.         List<Student> list = new ArrayList<Student>();  
  43.         list.add(new Student(“zhangsan”,31));  
  44.         list.add(new Student(“lisi”,30));  
  45.         list.add(new Student(“wangwu”,35));  
  46.         Collections.sort(list,new MyComparator());      //List集结举行排序操作  
  47.           
  48.         for (int i = 0; i < stu.length; i++) {  
  49.             Student s = stu[i];  
  50.             System.out.println(s);  
  51.         }  
  52.           
  53.         System.out.println(“*********”);  
  54.           
  55.         for (int i=0;i<list.size();i++){  
  56.             Student s = list.get(i);  
  57.             System.out.println(s);  
  58.         }  
  59.     }  
  60. }   

①  
TreeMap类通过使用红黑树完毕Map接口;

java.lang.Comparable 接口

②  
TreeMap提供按排序依次存款和储蓄键/值对的有用手腕,同期同意火速找出;

作者: zccst

③  
不像散列(HashMap),树映射保障它的要素按首要性字升序排序;

 

④  
TreeMap构造方法:

java.lang.Comparable 接口定义的 compareTo() 方法用于提供对实在现类的靶子开始展览一体化排序所急需的比较逻辑。

a)  
TreeMap()

贯彻类基于 compareTo() 方法的排序被誉为自然排序。而 compareTo() 方法的排序被喻为它的本来排序。具体的排序原则可由完结类依据需求而定。用户在重写 compareTo() 方法以定制比较逻辑时,需求确定保证其余等价性剖断形式 equals() 保持一致,即 e1.equals((Object)e2) 和e1.compareTo((Object)e2)==0 具备一样的值,那样的话大家就称本来顺序就和 equals 一致。

b)  
TreeMap(Comparator comp)

其一接口有何样用吧?

c)  
TreeMap(Map m)

假若五个数组中的对象达成了 Compareable 接口,则对这么些数组实行排序极度轻巧: Arrays.sort(); 假若 List 完成了该接口的话 , 大家就足以调用Collections.sort 或然 Arrays 方法给她们排序。实际上 Java 平台库中的全部值类 (value
classes) 都达成了 Compareable 接口。

d)  
TreeMap(SortedMap sm)

Comparable 接口唯有三个办法 compareTo(Object obj)

⑤  
TreeMap完毕SortedMap何况扩大AbstractMap,它自己并不曾定义别的办法;

其中

1         TreeMap<String,String> tmap=new TreeMap<String, String>();
2         tmap.put("zhang", "张三");
3         tmap.put("jack", "小明");
4         tmap.put("mary", "小红");
5         tmap.put("free", "小叶");
6         tmap.put("mary", "小草");
7         //tmap.put(null,"小草");//键不能传入null,会抛异常
8         System.out.println(tmap);
9     

this < obj   返回负

默许依据键的自然顺序升序输出

this = obj   返回 0

出口结果:

this > obj   返回正

{free=小叶,
jack=小明, mary=小草, zhang=张三}

将在当前以此指标与钦赐的指标举行依次相比,当该对象小于、等于或超过钦赐对象时,分别重返多少个负整数、 0 或正整数,如若不可能开始展览相比较,则抛出ClassCastException 非常。

 

 

出口全部键值对

实际,有二种方法能够实行联谊排序 :

1     Set<Entry<String,String>> entrys=tmap.entrySet();
2         for(Entry<String,String> entry:entrys){
3             System.out.println(entry.getKey()+"--"+entry.getValue());
4         }

   1. 凑合中目标的所属类达成了 java.lang.Comparable 接口

出口结果:

   2. 为汇聚钦定相比较器 java.lang.Comparator 的完成类

free–小叶

Comparator , Comparable 接口的分别是:

jack–小明

comparable 是通用的接口,用户能够兑现它来造成本身一定的相比,而 comparator 能够看做一种算法的贯彻,在供给容器集结 collection 要求比较效果与利益的时候,来钦定那一个比较器,那能够看看一种设计情势,将算法和数据分离,仿佛 C++
STL 中的函数对象同样。

mary–小草

前端应该相比较固定,和三个现实类相绑定,而后人比较灵活,它能够被用于各种供给相比较效益的类应用。能够说后面一个属于“静态绑定”,而后人能够“动态绑定”。

zhang–张三

二个类完毕了 Camparable 接口申明这些类的指标时期是能够互相比较的。假诺用数学语言描述的话正是这么些类的对象组成的集纳中留存几个全序。那样,那几个类对象组成的聚合就能够运用 Sort 方法排序了。

 

而 Comparator 的机能有四个:

编制多个Person类

   1. 举个例子类的设计员未有思念到 Compare 的难题而从未达成 Comparable 接口,能够透过  Comparator 来落到实处相比较算法实行排序

 1 class Person{
 2     private String name;
 3     private int age;
 4     public Person(String name, int age) {
 5         super();
 6         this.name = name;
 7         this.age = age;
 8     }
 9     public String getName() {
10         return name;
11     }
12     public void setName(String name) {
13         this.name = name;
14     }
15     public int getAge() {
16         return age;
17     }
18     public void setAge(int age) {
19         this.age = age;
20     }
21 }

2. 为了利用分歧的排序标准做希图,比如:升序、降序或任何什么序