集合框架库Map接口 -- TreeMap、LinkedHashMap

如果需要维护key-value结构的大小顺序可以选择TreeMap
如果需要维护key-value结构的插入顺序可以选择LinkedHashMap

1. TreeMap简介

TreeMap是一个大小有序的key-value集合,底层结构是红黑树,不允许插入null,TreeMap采用红黑树的插入和删除方法,通过比较key决定新元素的插入位置,也通过红黑树的有序性质进行删除。通过Compare进行元素的排序。

TreeMap的特点

implements NavigableMap, Cloneable, java.io.Serializable
NavigableMap:实现了NavigableMap接口,则TreeMap支持一系列的导航方法。
Cloneable:允许克隆
Serializable:支持序列化

TreeMap的使用特点

(1) 如果需要维护key-value结构的大小顺序可以选择TreeMap
(2)底层结构:使用红黑树来维护大小顺序。
(3)根据key-value结构中的key进行排序。
key:要能够反应出key-value结构的特点
(4)时间复杂度:不再是hashMap的近似O(1),而是log(2n)
(5)不允许出现重复的key
(6)使用时必须提供比较器(内比较器或者外比较器),否则会抛出异常
异常:没有实现比较器
Exception in thread “main” java.lang.ClassCastException: com.tulun.srcclass.JavaSE.TreeMap.People cannot be cast to java.lang.Comparable

TreeMap的节点结构

K key
V value
Entry left = null;
Entry right = null;
Entry parent = null;
boolean color = BLACK;

2. TreeMap的基本使用

  1. 定义
TreeMap treeMap = new TreeMap<>();
  1. 添加
    不允许插入null元素
People p1 = new People("Tom",24);
        People p2 = new People("Jenny",24);
        //添加元素
        treeMap.put(p1,"1号");
        treeMap.put(p2,"2号");
        //不允许插入null元素
//        treeMap.put(null,"3号");
  1. 删除
treeMap.remove(p2);
  1. 修改
treeMap.replace(p3,"4号");
  1. 查询
//查出key对应的值
System.out.println(treeMap.get(p3));

3. TreeMap的遍历

Iterator> iterator = treeMap.entrySet().iterator();
while(iterator.hasNext()){
    Map.Entry next = iterator.next();
    System.out.println(next.getKey().toString()+" "+next.getValue());
}

4. LinkedHashMap简介

如果需要维护key-value结构的插入顺序,可以选择LinkedHashMap。使用LinkedHashMap实现插入有序。
LinkedHashMap在HashMap的基础上维护了一个双向链表
LinkedHashMap = HashMap + 双向链表,既可以使用HashMap操作数据结构,又使用LinkedList维护插入顺序。

LinkedHashMap节点构成

K key
V value
Entry next
int hash
Entry before
Entry after

相对于HashMap的节点多了after和before,after指向该节点之后插入的节点,before指向该节点之前插入的节点。
其中前四个是从HashMap.Entry中继承过来的,后面两个,是LinkedHashMap独有的。next是用于维护HashMap中table数组中存储的链表。before和after是用于维护节点插入的先后顺序。
继承了HashMap,添加等使用的都是HashMap,重写部分方法,维护before,after。

LinkedHashMap插入维护

定义头指针和尾指针,维护双链表,采用头插和尾插添加元素。
插入操作:
1.从table角度来看,新的Entry节点插入到数组对应的下标里,当有哈希冲突时,采用头插法将新的Entry插入到冲突链表的头部。
2. 从头结点header的角度来看,新的Entry节点插入到双向链表的尾部。
LinkedHashMap的实现就是HashMap + LinkedList的实现方式,以HashMap维护数据结构,以LinkList的方式维护数据插入的顺序。

5. LinkedHashMap的基本使用

  1. 定义
LinkedHashMap linkedHashMap = new LinkedHashMap<>();
  1. 添加
    允许插入null元素
//添加元素
linkedHashMap.put(1,"zhangsan");
//允许添加key或者value为null
linkedHashMap.put(null,null);
  1. 删除
linkedHashMap.remove(2);
  1. 修改
linkedHashMap.replace(3,"caigou");
  1. 查询
//查出key对应的值
System.out.println(linkedHashMap.get(3));

6. LinkedHashMap的遍历

通过entrySet,获得LinkedHashMap的“键值对”的Set集合

//entrySet
Iterator> iterator = linkedHashMap.entrySet().iterator();
while (iterator.hasNext()){
    Map.Entry next = iterator.next();
    System.out.println("key;"+next.getKey()+" "+"value:"+next.getValue());
}

通过keySet,获得LinkedHashMap的“键”的Set集合

//keySet
Iterator iterator1 = linkedHashMap.keySet().iterator();
while (iterator1.hasNext()){
    Integer next = iterator1.next();
    System.out.println("key;"+next);
}

通过values,获得LinkedHashMap的“值”的集合

//values
Iterator iterator2 = linkedHashMap.values().iterator();
while (iterator2.hasNext()){
    String next = iterator2.next();
    System.out.println("value:"+next);
}

你可能感兴趣的:(JavaSE)