list.contains(o) :遍历集合所有元素,用每个元素和传入的元素进行 equals 比较,如果集合元素有 n 个,则会比较 n 次,所以时间复杂度为 O(n) 。方法源码如下:
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 ;
}
set.contains(o) :set 集合是用 HashMap 实现的,其中 add 方法将每个元素当做键,以一个object 对象作为值放在 HashMap 中,而 set 的 contains 方法调用了 HashMap 的 containKey 方法,直接获取传入元素的键值对信息做判断,所以 contains 的方法复杂度为 O(1) 。方法源码如下:
public boolean add ( E e) {
return map . put ( e, PRESENT) == null;
}
public boolean contains ( Object o) {
return map . containsKey ( o) ;
}
public boolean containsKey ( Object key) {
return getNode ( hash ( key) , key) != null;
}
final Node< K, V> getNode ( int hash, Object key) {
Node< K, V> [ ] tab; Node< K, V> first, e; int n; K k;
if ( ( tab = table) != null && ( n = tab. length) > 0 &&
( first = tab[ ( n - 1 ) & hash] ) != null) {
if ( first. hash == hash &&
( ( k = first. key) == key || ( key != null && key. equals ( k) ) ) )
return first;
if ( ( e = first. next) != null) {
if ( first instanceof TreeNode)
return ( ( TreeNode< K, V> ) first) . getTreeNode ( hash, key) ;
do {
if ( e. hash == hash &&
( ( k = e. key) == key || ( key != null && key. equals ( k) ) ) )
return e;
} while ( ( e = e. next) != null) ;
}
}
return null;
}
public V get ( Object key) {
Node< K, V> e;
return ( e = getNode ( hash ( key) , key) ) == null ? null : e. value;
}
在进行contians判断时,全部用Set集合的contains方法,避免踩坑