一、ArrayList及LinkedList面试问题小结
1、ArrayList 默认初始化大小?
jdk 1.6 是 10,1.7跟1.8 都是0。
直接上源码
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
注释依然写的默认10…
2、LinkedList默认构造方法
/**
* Constructs an empty list.
*/
public LinkedList() {
}
3、ArrayList 为何线程不安全?
主要由add()方法引起
在这里插入代码片
4、ArrayList 扩容机制?
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
int newCapacity = oldCapacity + (oldCapacity >> 1) 这是1.8的扩容机制,即1.5倍。
int newCapacity = (oldCapacity * 3)/2 + 1; 1.6的代码,10会变成16.
5、LinkedList 是否需要扩容?
不需要
6、LinkedList get(index)查找
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
/**
* Returns the (non-null) Node at the specified element index.
*/
Node<E> node(int index) {
// assert isElementIndex(index);
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
虽然LinkedList是链表结构,需要一个一个遍历,但是使用了二分查找法,根据index判断从头开始查找还是尾部,还是提高了效率。
7、LinkedList 是单向链表还是双向链表?
transient int size = 0;
/**
* Pointer to first node.
* Invariant: (first == null && last == null) ||
* (first.prev == null && first.item != null)
*/
transient Node<E> first;
/**
* Pointer to last node.
* Invariant: (first == null && last == null) ||
* (last.next == null && last.item != null)
*/
transient Node<E> last;
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
由源码可得出,主要是静态内部类Node的成员变量,可得出是双向链表。
…未完待续