/*
两个查找方法的比较:通过值查找的方法和通过键查找的时间复杂度是不一致的,由于二叉树的数据存储结构是通过关键字的的大小比较来排序创建二叉树的,所以当使用键查找匹配的时候,是可以利用二分法的思想进行查找的,也就是他的查找效率是与树的深度(depth)相关的,时间复杂度是O(logn);而用值的查找方法,由于值在存储过程中是无顺序存储的,所以只能通过类似单链表的通过遍历树的方法查找,所以时间复杂度为O(n);
*/
//代码如下:
public boolean containsKey(Object key) {
return getEntry(key) != null;
}
final Entry<K , V> getEntry(K key) {
if (comparator != null) {//如果有比较器,则需要用通过比较器查找的方法
return getEntryUsingComparator(key);
}
if (key == null) {//因为关键字不能为空,如果传进来的键值是空,则需要抛出运行时异常,空指针异常;
throw new NullPointerException();
}
//如果以上两种情况都不是,那就先把关键字转化为可比较的对象
Comparable<? super K> k = (Comparable<? super K>)key ;//先做一步强转动作,然后通过可比较的类中的compareTo的自然排序比较
Entry<K , V > current = root;
while(current != null) {
int cmp = k.compareTo(p.key);
if (cmp == 0) {
return current;
}else if (cmp < 0) {
current = current.left;
}else {
current = current.right;
}
}
return null;
}
//使用比较器的方法
final Entry<K , V> getEntryUsingComparator(K key) {
if (key == null) {
throw new NullPointerException();
}// 为什么源码中不需要加这一步判断,难道在compare方法中有对出现null的处理么?
Comparator<? super K> cpr = comparator;
Entry<K , V > current = root;
while (current != null) {
int cmp = cpr.compare(key, current.key);
if (cmp == 0) {
return current;
}else if (cmp < 0) {
current = current.left;
}else {
current = current.right;
}
}
return null;
}
public boolean containsValue (Object value) {
for (Entry<K , V> e = getFirstEntry();e != null ; e = successor(e) ) {
if (value == null && e.value == null || value.equals(e.value)) {
return true;
}
}
return false;
}
以上代码是楼主根据源码加上自己的理解写的,有错误的话望大家指正!!!
|
|