ArrayList的contains()方法
ArrayList底层使用数组作为存储,当给定一个Object判断是否存在需要去遍历数组,和每一个元素进行比较
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
从源码可以发现,contains()方法通过调用indexOf()方法来判断,而后者需要遍历数组,因此ArrayList的contains()方法的时间复杂度为O(n)
HashSet的contains()方法
HashSet底层通过HashMap实现,而HashMap底层结构是数组+链表+红黑树
当没有产生哈希冲突时:
调用contains(object)方法时,先调用object的hashCode()方法计算哈希值1,此哈希值经过某种算法(hash())之后,得到哈希值2,哈希值2再经过indexFor()之后得到数组的索引,然后object与索引位置上的元素用equals()方法比较,此时的时间复杂度为O(1)
当产生哈希冲突时:
所要查找的元素在链表上:
此时链表上的元素个数小于8
先以同样的方法找到链表第一个元素所在的数组,然后object的哈希值2与链表上的元素的哈希值2进行比较,如果哈希值2相等,则比较equals方法,相等则找到元素,如果哈希值不相等则比较链表的下一个元素此时的时间复杂度为O(n)
所要查找的元素在红黑树上:
此时链表元素个数>=8,并且数组元素达到64,索引i上的元素使用红黑树进行存储,时间复杂度为O(logn)