1. 简单函数系列

/* 返回元素个数 */
public int size() { return size; }
/* 是否包含指定的key */
public boolean containsKey(Object key) { return getEntry(key) != null; }
/* 是否包含指定的value值,从 getFirstEntry()获取首节点(最小节点)开始 */
public boolean containsValue(Object value) {
	/* 查找 e 的后继节点 */
    for(Entry<K,V> e = getFirstEntry(); e != null; e = successor(e))
        if (valEquals(value, e.value))
            return true;
    return false;
}
/* 返回当前的比较器 */
public Comparator<? super K> comparator() {
    return comparator;
}

2. put(K key, V value)

  • 若key存在,更新新值为 value,返回oldValue,若不存在,添加新节点,返回 null
public V put(K key, V value) {
    Entry<K,V> t = root;
    /* 空树的节点添加 */
    if (t == null) {
    	/* 类型检查 */
        compare(key, key);

        root = new Entry<>(key, value, null);
        size = 1;
        modCount++;
        return null;
    }
    int cmp;
    Entry<K,V> parent;
    // 比较器 == null 判断,不为 null 直接使用,为null 将key强转类型
    Comparator<? super K> cpr = comparator;
    if (cpr != null) {
        do {
            parent = t;
            cmp = cpr.compare(key, t.key);
            if (cmp < 0)
                t = t.left;
            else if (cmp > 0)
                t = t.right;
            else
                return t.setValue(value);
        } while (t != null);
    }
    else {
        if (key == null)
            throw new NullPointerException();
        @SuppressWarnings("unchecked")
            Comparable<? super K> k = (Comparable<? super K>) key;
        do {
            parent = t;
            cmp = k.compareTo(t.key);
            if (cmp < 0)
                t = t.left;
            else if (cmp > 0)
                t = t.right;
            else
                return t.setValue(value);
        } while (t != null);
    }
    /* 找到添加节点的位置 */
    Entry<K,V> e = new Entry<>(key, value, parent);
    if (cmp < 0)
        parent.left = e;
    else
        parent.right = e;
    /* 添加节点平衡操作,后面详讲 */    
    fixAfterInsertion(e);
    /* 更新 size,modCount,返回null */
    size++;
    modCount++;
    return null;
}

3. putAll(Map<? extends K, ? extends V> map)

  • 添加 map集合,使用TreeMap的排序方法
public void putAll(Map<? extends K, ? extends V> map) {
    int mapSize = map.size();
    /* 当前TreeMap size 为0 && mapSize 不为 0 && map 是SortedMap的实例 */
    if (size==0 && mapSize!=0 && map instanceof SortedMap) {
    	/* 获取比较器 */
        Comparator<?> c = ((SortedMap<?,?>)map).comparator();
        /* 若c 与 TreeMap使用的比较器相同 */
        if (c == comparator || (c != null && c.equals(comparator))) {
            ++modCount; // 更新 modCount
            try {
            	/* 添加所有的元素,后面详讲 */
                buildFromSorted(mapSize, map.entrySet().iterator(),
                                null, null);
            } catch (java.io.IOException cannotHappen) {
            } catch (ClassNotFoundException cannotHappen) {
            }
            return;
        }
    }
    /* 这里调用父类的putAll(),循环内部还是调用的put()方法 */
    super.putAll(map);
}

4. get(Object key)

  • 获取指定key 的value值
/* 获取指定key 的value值 */
public V get(Object key) {
	/* 调用getEntry 获取节点 */
    Entry<K,V> p = getEntry(key);
    return (p==null ? null : p.value);
}
/* 根据key值获取 entry节点,找不到返回null */
final Entry<K,V> getEntry(Object key) {
    /* 当前比较器存在,使用指定的比较器查找 */
    if (comparator != null)
        return getEntryUsingComparator(key);
    /* null 异常检测 */    
    if (key == null)
        throw new NullPointerException();
    /* 强转key的类型,使用强转的比较器(默认自然排序)进行比较 */    
    @SuppressWarnings("unchecked")
    Comparable<? super K> k = (Comparable<? super K>) key;
    Entry<K,V> p = root;
    while (p != null) {
        int cmp = k.compareTo(p.key);
        if (cmp < 0)
            p = p.left;
        else if (cmp > 0)
            p = p.right;
        else
            return p;
    }
    return null;
}
/* 使用指定的比较器获取节点 */
final Entry<K,V> getEntryUsingComparator(Object key) {
    @SuppressWarnings("unchecked")
        K k = (K) key;
    Comparator<? super K> cpr = comparator;
    if (cpr != null) {
        Entry<K,V> p = root;
        while (p != null) {
            int cmp = cpr.compare(k, p.key);
            if (cmp < 0)
                p = p.left;
            else if (cmp > 0)
                p = p.right;
            else
                return p;
        }
    }
    return null;
}

5. remove(Object key)

  • 删除指定的key对应的节点,找不到返回 null
public V remove(Object key) {
	/* 获取key对应的节点,找不到返回null */
    Entry<K,V> p = getEntry(key);
    if (p == null)
        return null;
	/* 找到获取旧值,删除节点,返回旧值 */
    V oldValue = p.value;
    deleteEntry(p); // 后面详讲
    return oldValue;
}

6. clear()

  • 清空当前treemap,直接将 root 置为null
public void clear() {
    modCount++;
    size = 0;
    root = null;
}

7. 小总结

import java.util.TreeMap;

public class TreeMapTest01 {
    public static void main(String[] args) {
        TreeMap<Integer, Integer> treeMap = new TreeMap<>((o1, o2)-> o1.compareTo(o2));

        for(int i = 1; i <= 4; i++) {
            treeMap.put(i, i);
        }
        System.out.println("now treemap.size(): " + treeMap.size());
        System.out.println("now treemap.comparator(): " + treeMap.comparator());
        System.out.println("now treemap: " + treeMap);
        System.out.println("====================================");
        TreeMap<Integer, Integer> treeMap01 = new TreeMap<>((o1, o2)-> o2.compareTo(o1));
        for(int i = 5; i <= 8; i++) {
            treeMap01.put(i, i);
        }
        System.out.println("now treemap01.size(): " + treeMap01.size());
        System.out.println("now treemap01.comparator(): " + treeMap01.comparator());
        System.out.println("now treemap01: " + treeMap01);
        System.out.println("====================================");
        treeMap.putAll(treeMap01);
        System.out.println("now treemap.size(): " + treeMap.size());
        System.out.println("putAll(treemap01), now treemap: " + treeMap);
        System.out.println("=====================================");
        System.out.println("treeMap.get(1): " + treeMap.get(1));
        System.out.println("treeMap.get(10): " + treeMap.get(10));
        System.out.println("treeMap.getOrDefault(1,10): " + treeMap.getOrDefault(1, 10));
        System.out.println("treeMap.getOrDefault(10,10): " + treeMap.getOrDefault(10, 10));
        System.out.println("=====================================");
        System.out.println("treeMap.containsKey(1): " + treeMap.containsKey(1));
        System.out.println("treeMap.containsKey(10): " + treeMap.containsKey(10));
        System.out.println("treeMap.containsValue(1): " + treeMap.containsValue(1));
        System.out.println("treeMap.containsValue(10): " + treeMap.containsValue(10));
        System.out.println("=====================================");
        System.out.println("now treemap: " + treeMap);
        treeMap.clear();
        System.out.println("treeMap.clear(), now treemap: " + treeMap);

    }
}

TreeMap获取字符串 treemap获取最后一个元素_TreeMap获取字符串

导航方法相关

8. 简单函数合集

/* 获取节点中的key,具有 null异常判断 */
static <K> K key(Entry<K,?> e) {
    if(e==null)
        throw new NoSuchElementException();
    return e.key;
}
/* 获取节点中的key,节点为null返回null,不会报错 */
static <K,V> K keyOrNull(TreeMap.Entry<K,V> e) {
    return (e == null) ? null : e.key;
}
/* 获取第一个节点的 key */
public K firstKey() {
    return key(getFirstEntry());
}
/* 获取最后一个节点的 key */
public K lastKey() {
    return key(getLastEntry());
}

9 -12 为内部方法,防止外部修改entry节点。

9. getCeilingEntry(K key)

  • 获取 >= key 的最小节点,找不到返回 null
final Entry<K,V> getCeilingEntry(K key) {
    Entry<K,V> p = root;
    while (p != null) {
        int cmp = compare(key, p.key);
        /* key < p.key 则往左找,若p左子节点为null,则 p 为大于 key 的最小节点 */
        if (cmp < 0) {
            if (p.left != null)
                p = p.left;
            else
                return p;
        } else if (cmp > 0) { // key > p.key
        	/* 往右查找 */
            if (p.right != null) {
                p = p.right;
            } else {
            	/* 这里的逻辑有点绕,但总体分为以下两种,以root节点为例
            	 * 1. 从根节点出发,没有过某个节点的p.key > key 的情况,
            	 * 		直至最大右节点也找不到比key大的节点,则返回null
            	 * 2. 从根节点出发,至少经历过1次某个节点的p.key > key,假设这个节点为root
            	 * 		以root.left出发,直至最大节点,所有节点的p.key都比key小,那么大于key的最小节点则为 root */
                Entry<K,V> parent = p.parent;
                Entry<K,V> ch = p;
                while (parent != null && ch == parent.right) {
                    ch = parent;
                    parent = parent.parent;
                }
                return parent;
            }
        } else
        	/* key == p.key 则返回 p */
            return p;
    }
    return null;
}

10. getHigherEntry(K key)

  • 获取 > key 的最小节点,找不到返回 null,与 getCeilingEntry 的差别为Node.key == key 时继续往右比较
final Entry<K,V> getHigherEntry(K key) {
    Entry<K,V> p = root;
    while (p != null) {
        int cmp = compare(key, p.key);
        if (cmp < 0) {
            if (p.left != null)
                p = p.left;
            else
                return p;
        } else {
            if (p.right != null) {
                p = p.right;
            } else {
                Entry<K,V> parent = p.parent;
                Entry<K,V> ch = p;
                while (parent != null && ch == parent.right) {
                    ch = parent;
                    parent = parent.parent;
                }
                return parent;
            }
        }
    }
    return null;
}

11. getFloorEntry(K key)

  • 获取 <= key 的最大节点,找不到返回 null
final Entry<K,V> getFloorEntry(K key) {
    Entry<K,V> p = root;
    while (p != null) {
        int cmp = compare(key, p.key);
        /* key > p.key,往右查找是否有 p.key 与 key 之间的节点 */
        if (cmp > 0) {
            if (p.right != null)
                p = p.right;
            else
                return p;
        /* key < p.key,往左查找 */        
        } else if (cmp < 0) {
            if (p.left != null) {
                p = p.left;
            } else {
            	/* 这里的逻辑有点绕,但总体分为以下两种,以root节点为例
            	 * 1. 从根节点出发,没有过某个节点的p.key < key 的情况,
            	 * 		直至最小左节点也找不到比key小的节点,则返回null
            	 * 2. 从根节点出发,至少经历过1次某个节点的p.key < key,假设这个节点为root
            	 * 		以root.right出发,直至最小节点,所有节点的p.key都比key大,那么小于key的最大节点则为 root */
                Entry<K,V> parent = p.parent;
                Entry<K,V> ch = p;
                while (parent != null && ch == parent.left) {
                    ch = parent;
                    parent = parent.parent;
                }
                return parent;
            }
        } else
            return p;

    }
    return null;
}

12. getLowerEntry(K key)

  • 获取 < key 的最大节点,找不到返回 null,与 getFloorEntry 的差别为Node.key == key 时继续往左比较
final Entry<K,V> getLowerEntry(K key) {
    Entry<K,V> p = root;
    while (p != null) {
        int cmp = compare(key, p.key);
        if (cmp > 0) {
            if (p.right != null)
                p = p.right;
            else
                return p;
        } else {
            if (p.left != null) {
                p = p.left;
            } else {
                Entry<K,V> parent = p.parent;
                Entry<K,V> ch = p;
                while (parent != null && ch == parent.left) {
                    ch = parent;
                    parent = parent.parent;
                }
                return parent;
            }
        }
    }
    return null;
}

13. getFirstEntry()、getLastEntry()

/* 获取第一个节点 */
final Entry<K,V> getFirstEntry() {
    Entry<K,V> p = root;
    if (p != null)
        while (p.left != null)
            p = p.left;
    return p;
}
/* 获取最后一个节点 */
final Entry<K,V> getLastEntry() {
    Entry<K,V> p = root;
    if (p != null)
        while (p.right != null)
            p = p.right;
    return p;
}

14. firstEntry()、lastEntry()、pollFirstEntry()、pollLastEntry()

  • 先来看 exportEntry,导出节点,这里是生成一个新节点导出,防止原有节点受到破坏
/* e不为null则生成一个 SimpleImmutableEntry */
static <K,V> Map.Entry<K,V> exportEntry(TreeMap.Entry<K,V> e) {
    return (e == null) ? null :
        new AbstractMap.SimpleImmutableEntry<>(e);
}
/* 获取第一个节点,底层调用getFirstEntry()获取节点后,生成返回的新节点 */
public Map.Entry<K,V> firstEntry() {
    return exportEntry(getFirstEntry());
}
/* 获取最后一个节点,底层调用getLastEntry()获取节点后,生成返回的新节点 */
public Map.Entry<K,V> lastEntry() {
    return exportEntry(getLastEntry());
}
/* 获取并删除第一个节点,底层调用getFirstEntry()获取节点后,生成返回的新节点 */
public Map.Entry<K,V> pollFirstEntry() {
    Entry<K,V> p = getFirstEntry();
    Map.Entry<K,V> result = exportEntry(p);
    if (p != null)
        deleteEntry(p); // 删除节点
    return result;
}
/* 获取并删除最后一个节点,底层调用getLastEntry()获取节点后,生成返回的新节点 */
public Map.Entry<K,V> pollLastEntry() {
    Entry<K,V> p = getLastEntry();
    Map.Entry<K,V> result = exportEntry(p);
    if (p != null)
        deleteEntry(p); // 删除节点
    return result;
}

15. lowerKey(K key)、floorKey(K key)、floorKey(K key)、higherKey(K key)

  • 底层调用对应的getXXXEntry,获取节点后进而获取key
/* 获取 < key 的最大节点的key */
public K lowerKey(K key) {
    return keyOrNull(getLowerEntry(key));
}
/* 获取 <= key 的最大节点的key */
public K floorKey(K key) {
    return keyOrNull(getFloorEntry(key));
}
/* 获取 >= key 的最小节点的key */
public K ceilingKey(K key) {
    return keyOrNull(getCeilingEntry(key));
}
/* 获取 > key 的最小节点的key */
public K higherKey(K key) {
    return keyOrNull(getHigherEntry(key));
}

16. lowerEntry(K key)、floorEntry(K key)、ceilingEntry(K key)、 higherEntry(K key)

  • 底层调用对应的getXXXEntry,获取 entry 节点
/* 获取  < key 的最大节点,找不到返回 null */
public Map.Entry<K,V> lowerEntry(K key) {
    return exportEntry(getLowerEntry(key));
}
/* 获取  <= key 的最大节点,找不到返回 null */
public Map.Entry<K,V> floorEntry(K key) {
    return exportEntry(getFloorEntry(key));
}
/* 获取 >= key 的最小节点,找不到返回 null */
public Map.Entry<K,V> ceilingEntry(K key) {
    return exportEntry(getCeilingEntry(key));
}
/* 获取 > key 的最小节点,找不到返回 null */
public Map.Entry<K,V> higherEntry(K key) {
    return exportEntry(getHigherEntry(key));
}

17 总结

import java.util.TreeMap;

public class TreeMapTest02 {
    public static void main(String[] args) {
        TreeMap<Integer, Integer> treeMap = new TreeMap<>();
        for(int i = 1; i <= 10; i++) {
            treeMap.put(i, i);
        }
        System.out.println("now treemap: " + treeMap);
        System.out.println("treeMap.firstKey(): " + treeMap.firstKey());
        System.out.println("treeMap.firstEntry(): " + treeMap.firstEntry());
        System.out.println("treeMap.lastKey(): " + treeMap.lastKey());
        System.out.println("treeMap.lastEntry(): " + treeMap.lastEntry());
        System.out.println("=======================");
        System.out.println("now treemap: " + treeMap);
        System.out.println("treeMap.pollFirstEntry(): " + treeMap.pollFirstEntry());
        System.out.println("now treemap: " + treeMap);
        System.out.println("treeMap.pollLastEntry(): " + treeMap.pollLastEntry());
        System.out.println("=======================");
        System.out.println("now treemap: " + treeMap);
        System.out.println("treeMap.lowerKey(5): " + treeMap.lowerKey(5));
        System.out.println("treeMap.lowerEntry(5): " + treeMap.lowerEntry(5));
        System.out.println("treeMap.floorKey(5): " + treeMap.floorKey(5));
        System.out.println("treeMap.floorKey(5): " + treeMap.floorKey(5));
        System.out.println("=======================");
        System.out.println("treeMap.ceilingKey(5): " + treeMap.ceilingKey(5));
        System.out.println("treeMap.ceilingEntry(5): " + treeMap.ceilingEntry(5));
        System.out.println("treeMap.higherKey(5): " + treeMap.higherKey(5));
        System.out.println("treeMap.higherEntry(5): " + treeMap.higherEntry(5));

    }
}

TreeMap获取字符串 treemap获取最后一个元素_TreeMap_02