你的位置:首页 > Java教程

[Java教程]Map容器——TreeMap及常用API,Comparator和Comparable接口


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   @Override2   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   }

然后再执行,输出结果:

{com.iotek.map.Person@2a139a55=张三, com.iotek.map.Person@15db9742=李四, com.iotek.map.Person@6d06d69c=王五, com.iotek.map.Person@7852e922=张三}

 

完整的Person类如下:

 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   @Override28   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     @Override2       public int compare(Person o1, Person o2) {3         return o1.getName().compareTo(o2.getName());4       }

输出结果:

{com.iotek.map.Person@2a139a55=李四, com.iotek.map.Person@15db9742=王五, com.iotek.map.Person@6d06d69c=张三}

因为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接口的比较器对象