Java大课堂:常用数据结构二(List)
2015-05-20 10:21
381 查看
List框架
List是一个接口,继承Collection接口,但是添加了size,get等方法。由于有很多方法和Collection是重合的,因此用一个抽象类AbstractCollection来实现一些默认方法,然后AbstractList继承这个抽象类。
List家族最重要的是ArrayList和LinkedList。我主要来介绍这两个list。
应用场景
学东西的最终目的是为了能够理解、使用它。下面先概括的说明一下各个List的使用场景,后面再分析原因。如果涉及到“栈”、“队列”、“链表”等操作,应该考虑用List,具体的选择哪个List,根据下面的标准来取舍。
1、对于需要快速插入,删除元素,应该使用LinkedList。
2、对于需要快速随机访问元素,应该使用ArrayList。
3、 对于“单线程环境” 或者 “多线程环境,但List仅仅只会被单个线程操作”,此时应该使用非同步的类(如ArrayList)。对于“多线程环境,且List可能同时被多个线程操作”,此时,应该使用同步的类(如Vector)。
4、因为性能问题,一般不建议用vector和stack。如需要使用栈,可以考虑deque
常见用法
</pre><pre name="code" class="java">public static void main(String []args){ //初始化 List<String> arrayList = Arrays.asList("abc","ab","1234"); List<String> linkedList = new LinkedList<String>(arrayList); //遍历 for(String str : arrayList){ System.out.println(str); } //插入删除 arrayList.add("king"); linkedList.remove("ab"); }
源码分析
大家都知道,ArrayList适合随机读写。linkedList适合插入删除。那么这是为什么呢?我将从源码角度来分析这一问题。首先来看看两者的数据结构。
在ArrayList是transient Object[] elementData.
在LinkedList是 transient Node<E> first;
可以看出两者的不同,一个是数组,另一个是指针。
现在来看看最主要的方法。add和get。
先是ArrayList。
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
注意这个ensureCapacityInternal函数,继续向下看。
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
第一句,如果数组为默认空数组,那么最小需要的容量为max(10,inCapcity)
继续向下看。
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
最小需要的容量大于数组实际长度,就需要扩大。见下面的函数。
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);
}
可以看出新的容量是原来容量的1.5倍。
这里需要分清容量和size的区别。容量是ArrayList最大能放的数据大小。Size是当前放的数据大小。
Get就比较简单,就不细说了。
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
现在看看LikedList的add方法。
public boolean add(E e) {
linkLast(e);
return true;
}
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
linkLast是将数据放到链表最后。
相关文章推荐
- All About JAVA 关于JAVA的几种常用数据结构
- java用数据库获取的list数据构造hashmap树结构
- 数据结构(Java LinkedList模拟)本代码重在学习数据结构思路,代码完整性欠缺,请见谅
- 再论JAVA中核心数据结构——List
- 常用数据结构及复杂度 array、LinkedList、List、Stack、Queue、Dictionary、SortedDictionary、HashSet、SortedSet
- linux 内核常用数据结构及算法——list(循环双向链表)
- Java使用LinkedList模拟一个堆栈或者队列数据结构
- java 把一个list中的数据按照树结构排序
- Java学习笔记-5.常用数据结构
- java中常用数据结构
- 常用数据结构及算法C#/Java实现
- Java数据结构笔记4——LinkedList
- java 中几种常用数据结构
- 数据结构(java)---MyLinkedList
- 智渔课堂官方免费教程三十六:Java数据结构之双向链表结构
- 智渔课堂官方免费教程三十七:Java数据结构之单向链表结构
- Java数据结构与算法之LinkedList单链表
- java学习日记_79:集合框架之数据结构的讲解和引出List子类的特点
- Java 面试常用的数据结构
- Java List Map Set 常用结构比较