Map常用实现类的体系结构
List和Set接口都是Collection的子接口,Map接口是与Map接口完全独立的另外一个体系,他们之间的区别主要在于Collection,set,list,只能操作单个元素,而Map操作的是键值对类型的元素
Map常见实现类有HashMap、LinkedHashMap、TreeMap,这几个实现类之间的特点以及区别如下:
1、HashMap
存储一组无序,key唯一且可以是null,value不唯一的元素,这里的无序是指存进去的顺序和遍历出来的顺序不一样
2、HashTable
存储一组无序,key唯一且不为null,value不唯一的元素,这里的无序是指存进去的顺序和遍历出来的顺序不一样。
它和HashMap的使用基本一致,他们的区别是:HashTable是线程安全的,它的方法基本都是synchroinized修饰,所以性能较相比较HashMap低,HashMap是非线程安全,但是性能较高,从实际开发角度讲,HashMap的使⽤用频率更高。
3、TreeMap
存储一组有序,key唯一且不为null,value不唯一的元素,这里的有序指的是无论以什么顺序存进去,遍历的时候是按key进行有序遍历的,如果key是数值类型,则默认遍历是按照升序的顺序遍历出来,如果key是对象,则要实现compareable类然后重写compareTo方法
代码演示TreeMap元素遍历的顺序
当key是数字时:
public class Demo2 {
public static void main(String[] args) {
Map treeMap = new TreeMap();
treeMap.put(3,"3");
treeMap.put(2,"2");
treeMap.put(1,"1");
Set set = treeMap.keySet();
Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(treeMap.get(iterator.next()));
}
}
}
1
2
3
当key是对象时:若没有实现compareable接口则会报异常,见如下代码:
public class Demo3 {
public static void main(String[] args) {
Map<Student, String> map = new TreeMap<>();
map.put(new Student(5,"王五"),"王五");
map.put(new Student(4,"李四"),"李四");
map.put(new Student(3,"张三"),"张三");
for(Map.Entry<Student, String> entry:map.entrySet()){
System.out.println(entry.getKey()+"--->"+entry.getValue());
}
}
}
class Student{
private int id;
private String name;
public Student(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
Exception in thread "main" java.lang.ClassCastException: map.TreeMap.Student cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(TreeMap.java:1294)
at java.util.TreeMap.put(TreeMap.java:538)
at map.TreeMap.Demo3.main(Demo3.java:16)
所以要实现这个这个compareable接口
public class Demo3 {
public static void main(String[] args) {
Map<Student, String> map = new TreeMap<>();
map.put(new Student(5,"王五"),"王五");
map.put(new Student(4,"李四"),"李四");
map.put(new Student(3,"张三"),"张三");
for(Map.Entry<Student, String> entry:map.entrySet()){
System.out.println(entry.getKey()+"--->"+entry.getValue());
}
}
}
class Student implements Comparable<Student>{
private int id;
private String name;
public Student(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
@Override
public int compareTo(Student o) {
if (this.id > o.id){
return 1;
}else if (this.id < o.id){
return -1;
}else {
return 0;
}
}
}
Student{id=3, name='张三'}--->张三
Student{id=4, name='李四'}--->李四
Student{id=5, name='王五'}--->王五
结果可知,结果会按着key的自然顺序遍历出来而不是随机的,看你重写compareTo方法的比较规则,我这里是按照升序的比较规则进行重写的,当然你也可以按着降序的规则重写,只要把1和-1位置互换就可以;