集合专题
二、容器
18.java 容器都有哪些?
Collection:
list:
arraylist: 数组实现,线程不安全,查询快,默认长度10,元素个数超过容量,扩容1.5倍+1
linkedlist: 链表实现,线程不安全,插入删除快,双向链表,没有初始化值,也没有扩容机制
vector:数组实现,线程安全,默认长度10,元素个数超过容量,扩容2倍
set:
hashset:基于hashmap实现,value值固定为object不重复,默认长度16,元素个数超过容量75%扩容,扩容2倍
linkedhashset:
treeset:二叉树实现
Map:
hashmap:entry数组加链表实现,线程不安全,默认长度16,默认长度16,元素个数超过容量75%扩容,扩容2倍
linkedhashmap:链表加hash表实现
WeakHashMap
treemap:红黑树实现
identifyHashMap
19.Collection 和 Collections 有什么区别?
Collection是集合接口,Collections是工具类。
20.List、Set、Map 之间的区别是什么?
list/set是单列集合,map是双列集合
list有序 可重复
set无序 不可重复
21.HashMap 和 Hashtable 有什么区别?
hashmap线程不安全,
Hashtable线程安全,效率低
22.如何决定使用 HashMap 还是 TreeMap?
23.说一下 HashMap 的实现原理?
数组和链表的结合
hashmap里放的是Entry数组,每个entry对象里有一条链表,链的每个节点上有key/value/next
put/get:通过hash算法计算放在entry数组index,找到链,再通过equals计算在链上面的位置
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {
Node<K,V> e; K k;
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof TreeNode)
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Node<K,V> next;
Node(int hash, K key, V value, Node<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
public final K getKey() { return key; }
public final V getValue() { return value; }
public final String toString() { return key + "=" + value; }
public final int hashCode() {
return Objects.hashCode(key) ^ Objects.hashCode(value);
}
public final V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
}
public final boolean equals(Object o) {
if (o == this)
return true;
if (o instanceof Map.Entry) {
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
if (Objects.equals(key, e.getKey()) &&
Objects.equals(value, e.getValue()))
return true;
}
return false;
}
}
24.说一下 HashSet 的实现原理?
add方法调用的hashmap的put方法,value是固定的Object PRESENT = new Object()对象。不存在key则插入,存在则不保存。
25.ArrayList 和 LinkedList 的区别是什么?
Arraylist是数组实现,查询快
linkedlist是双向链表,删除新增快
数组:
静态分配内存,需要连续的空间,浪费内存;大小固定,不能动态拓展
查询的时间复杂度是o(1)(一个常量,时间不随数据量的变化而增大);插入删除的时间复杂度是o(n)(数据量扩大n倍,时间扩大n倍);
链表:
动态分配内存,不需要连续的空间,节约内存;大小不固定,比较灵活;
查询需要从头开始往后查,查询的时间复杂度是0(n),插入删除的时间复杂度是o(1);
26.如何实现数组和 List 之间的转换?
String[] strs = new String[] {"aaa", "bbb", "ccc"};
数组转list,List<String> list = Arrays.asList(strs);
list转数组,String[] str = list.toArray(new String[]{list.size()});
27.ArrayList 和 Vector 的区别是什么?
28.Array 和 ArrayList 有何区别?
29.在 Queue 中 poll()和 remove()有什么区别?
30.哪些集合类是线程安全的?
31.迭代器 Iterator 是什么?
32.Iterator 怎么使用?有什么特点?
33.Iterator 和 ListIterator 有什么区别?
34.怎么确保一个集合不能被修改?

浙公网安备 33010602011771号