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

时间:2021-01-18 00:47:38

TreeMap及常用API

①   TreeMap类通过使用红黑树实现Map接口;

②   TreeMap提供按排序顺序存储键/值对的有效手段,同时允许快速检索;

③   不像散列(HashMap),树映射保证它的元素按关键字升序排序;

④   TreeMap构造方法:

a)   TreeMap()

b)   TreeMap(Comparator comp)

c)   TreeMap(Map m)

d)   TreeMap(SortedMap sm)

⑤   TreeMap实现SortedMap并且扩展AbstractMap,它本身并没有定义其他方法;

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

默认按照键的自然顺序升序输出

输出结果:

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

输出所有键值对

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

输出结果:

free--小叶

jack--小明

mary--小草

zhang--张三

编写一个Person类

 class Person{
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
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;
}
}

在主方法中创建并添加元素,输出

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

运行结果:

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

 

方法一:实现Comparable接口

class Person implements Comparable<Person>{ }

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

     @Override
public int compareTo(Person o) {
if (this.age - o.getAge() > 0) {
return 1;
} else if (this.age - o.getAge() < 0) {
return -1;
}
return 0;
}

然后再执行,输出结果:

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

完整的Person类如下:

     class Person implements Comparable<Person> {
private String name;
private int age; public Person(String name, int age) {
super();
this.name = name;
this.age = age;
} 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;
} @Override
public int compareTo(Person o) {
if (this.age - o.getAge() > 0) {
return 1;
} else if (this.age - o.getAge() < 0) {
return -1;
}
return 0;
}
}

方法二:Person中不使用Comparable接口,在主方法中使用匿名内部类:

 TreeMap<Person, String> pdata = new TreeMap<Person, String>(new Comparator<Person>() {

             @Override
public int compare(Person o1, Person o2) {
if(o1.getAge()>o2.getAge()){
return 1;
}
else if(o1.getAge()<o2.getAge()){
return -1;
}
return 0;
}
});

输出结果与上面相同

上面都是使用int年龄进行排序,使用String名字排序方法如下:

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

输出结果:

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

因为zhangsan相同则被替换了,修改如下:

         @Override
public int compare(Person o1, Person o2) {
if(o1.getName().compareTo(o2.getName())>0){
return 1;
}
else if(o1.getName().compareTo(o2.getName())<0){
return -1;
}
else{
//年龄相同时还是会替换
return o1.getAge()-o2.getAge();
}
}

Comparator和Comparable接口

①   TreeMap的key存储引用类型数据,需要满足一定条件

a)   要么引用类型实现Comparable接口

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