设为首页 加入收藏

TOP

Map大家族的那点事儿(3) :TreeMap(四)
2018-09-05 11:46:47 】 浏览:553
Tags:Map 大家族 那点 事儿 TreeMap
); return (e == null || tooLow(e.key)) ? null : e; } // 下面的逻辑就都很简单了,注意会先判断key是否越界, // 如果越界就返回绝对值。 final TreeMap.Entry<K,V> absCeiling(K key) { if (tooLow(key)) return absLowest(); TreeMap.Entry<K,V> e = m.getCeilingEntry(key); return (e == null || tooHigh(e.key)) ? null : e; } final TreeMap.Entry<K,V> absHigher(K key) { if (tooLow(key)) return absLowest(); TreeMap.Entry<K,V> e = m.getHigherEntry(key); return (e == null || tooHigh(e.key)) ? null : e; } final TreeMap.Entry<K,V> absFloor(K key) { if (tooHigh(key)) return absHighest(); TreeMap.Entry<K,V> e = m.getFloorEntry(key); return (e == null || tooLow(e.key)) ? null : e; } final TreeMap.Entry<K,V> absLower(K key) { if (tooHigh(key)) return absHighest(); TreeMap.Entry<K,V> e = m.getLowerEntry(key); return (e == null || tooLow(e.key)) ? null : e; } /** 返回升序遍历的绝对上限 */ final TreeMap.Entry<K,V> absHighFence() { return (toEnd ? null : (hiInclusive ? m.getHigherEntry(hi) : m.getCeilingEntry(hi))); } /** 返回降序遍历的绝对下限 */ final TreeMap.Entry<K,V> absLowFence() { return (fromStart ? null : (loInclusive ? m.getLowerEntry(lo) : m.getFloorEntry(lo))); } // 剩下的就是实现NavigableMap的方法以及一些抽象方法 // 和NavigableSubMap中的集合视图函数。 // 大部分操作都是靠当前实例map的方法和上述用于判断边界的方法提供支持 ..... }

一个局部视图最重要的是要能够判断出传入的key是否属于该视图的范围内,在上面的代码中可以发现NavigableSubMap提供了非常多的辅助函数用于判断范围,接下来我们看看NavigableSubMap的迭代器是如何实现的:

/**
 * Iterators for SubMaps
 */
abstract class SubMapIterator<T> implements Iterator<T> {
    TreeMap.Entry<K,V> lastReturned;
    TreeMap.Entry<K,V> next;
    final Object fenceKey;
    int expectedModCount;
    SubMapIterator(TreeMap.Entry<K,V> first,
                   TreeMap.Entry<K,V> fence) {
        expectedModCount = m.modCount; 
        lastReturned = null;
        next = first;
        // UNBOUNDED是一个虚拟值(一个Object对象),表示无边界。
        fenceKey = fence == null ? UNBOUNDED : fence.key;
    }
    // 只要next不为null并且没有超过边界
    public final boolean hasNext() {
        return next != null && next.key != fenceKey;
    }
    final TreeMap.Entry<K,V> nextEntry() {
        TreeMap.Entry<K,V> e = next;
        // 已经遍历到头或者越界了
        if (e == null || e.key == fenceKey)
            throw new NoSuchElementException();
        // modCount是一个记录操作数的计数器
        // 如果与expectedModCount不一致
        // 则代表当前map实例在遍历过程中已被修改过了(从其他线程)
        if (m.modCount != expectedModCount)
            throw new ConcurrentModificationException();
        // 向后移动next指针
        // successor()返回指定节点的继任者
        // 它是节点e的右子树的最左节点
        // 也就是比e大的最小的节点
        // 如果e没有右子树,则会试图向上寻找
        next = successor(e);
        lastReturned = e; // 记录最后返回的节点
        return e;
    }
    final TreeMap.Entry<K,V> prevEntry() {
        TreeMap.Entry<K,V> e = next;
        if (e == null || e.key == fenceKey)
            throw new NoSuchElementException();
        if (m.modCount != expectedModCount)
            throw new ConcurrentModificationException();
        // 向前移动next指针
        // predecessor()返回指定节点的前任
        // 它与successor()逻辑相反。
        next = predecessor(e);
        lastReturned = e;
        return e;
    }
    final void removeAscending() {
        if (lastReturned == null)
            throw new IllegalStateException();
        if (m.modCount != expectedModCount)
            throw new ConcurrentModificationException();
        // 被删除的节点被它的继任者取代
        // 执行完删除后,lastReturned实际指向了它的继任者
        if (lastReturned.left != null && lastReturned.right != null)
            next = lastReturned;
        m.deleteEntry(lastReturned);
首页 上一页 1 2 3 4 5 下一页 尾页 4/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇JVM( 5 ):Tomcat 性能调优和性.. 下一篇按钮条件逻辑配置化的可选技术方案

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目