/**
* @throws NoSuchElementException {@inheritDoc}
*/
public K firstKey() {
return key(getFirstEntry());
}
/**
* Returns the key corresponding to the specified Entry.
* @throws NoSuchElementException if the Entry is null
*/
static <K> K key(Entry<K,?> e) {
if (e==null)
throw new NoSuchElementException();
return e.key;
}
/**
* Returns the first Entry in the TreeMap (according to the TreeMap's
* key-sort function). Returns null if the TreeMap is empty.
*/
final Entry<K,V> getFirstEntry() {
Entry<K,V> p = root;
if (p != null)
while (p.left != null)
p = p.left;
return p;
}
getFirstEntry方法的作用是获取TreeMap
中的第一个条目(根据TreeMap
的键排序函数)。如果TreeMap
为空,则返回null
。
代码解释:
-
定义方法:
final Entry<K,V> getFirstEntry()
定义了一个方法,该方法返回一个类型为Entry<K,V>
的对象。这个方法是final
的,意味着它不能被子类重写。 -
初始化变量:
Entry<K,V> p = root;
这行代码初始化了一个名为p
的变量,其类型为Entry<K,V>
,并将其设置为TreeMap
的根节点。这是遍历树的起点。 -
检查根节点是否为空:
if (p != null)
这个条件判断确保了树不为空。如果树为空(即根节点为null
),则方法将直接返回null
。 -
遍历左子树:
while (p.left != null) p = p.left;
这个循环是方法的核心。它从根节点开始,沿着树的左边一直向下遍历,直到找到最左边的节点。在二叉搜索树中,最左边的节点包含最小的键,因此这个节点就是TreeMap
中的第一个条目。 -
返回结果:
return p;
最后,这行代码返回找到的最左边的节点。如果树为空,如前所述,方法将返回null
。
为啥遍历左子树?
遍历左子树是因为TreeMap
在Java中是基于红黑树实现的,而红黑树是一种自平衡的二叉搜索树。在二叉搜索树中,对于任意一个节点,其左子树中的所有节点的键都小于该节点的键,而右子树中的所有节点的键都大于该节点的键。这种性质使得二叉搜索树能够以有序的方式存储键值对。
因此,当我们需要找到TreeMap
中的第一个条目,即键最小的条目时,我们需要从根节点开始,一直向左遍历,直到达到最左边的节点。这个最左边的节点没有左子节点,根据二叉搜索树的性质,它的键是整个树中最小的,因此它就是TreeMap
中的第一个条目。
简而言之,遍历左子树是因为:
- 二叉搜索树的性质:左子节点的键小于父节点,右子节点的键大于父节点。
- 寻找最小键值:为了找到最小的键,需要沿着左子树一直向下遍历到最左边的节点。
总结:
这段代码通过从根节点开始,沿着左子树一直向下遍历,来找到并返回TreeMap
中的第一个条目。这个条目包含了最小的键。如果TreeMap
为空,则方法返回null
。这是实现TreeMap
迭代器和其他相关功能的基础逻辑之一。