图片来源于http://blog.csdn.net/u010887744/article/details/50575735
从图看出Collection继承了Iterable,而List集合继承了Collection,所以List集合都可以使用迭代器来遍历集合
List集合,有序,可以重复的集合。
由于 List 接口是继承于 Collection 接口,所以基本的方法如上所示。
怎么记呢?我们可以想象:
数组就像身上编了号站成一排的人,要找第10个人很容易,根据人身上的编号很快就能找到。但插入、删除慢,要望某个位置插入或删除一个人时,后面的人身上的编号都要变。当然,加入或删除的人始终末尾的也快。
链表就像手牵着手站成一圈的人,要找第10个人不容易,必须从第一个人一个个数过去。但插入、删除快。插入时只要解开两个人的手,并重新牵上新加进来的人的手就可以。删除一样的道理。
List接口下有很多个集合,它们存储元素所采用的结构方式是不同的,这样就导致了这些集合有它们各自的特点,供给我们在不同的环境下进行使用。数据存储的常有结构有:堆栈,队列,数组,链表。我们分别来了解一下:
堆栈——采用该结构的集合,对元素的存取有如下的特点:
(1)先进后出(即,存进去的元素,要在它后面的元素依次取出后,才能取出该元素)。
(2)栈的入口,出口都是栈的顶端位置。
(3)压栈:就是存元素。即,把元素存储到栈的顶端位置,栈中已有元素依次向栈底方向移动一个位置。
(4)弹栈:就是取元素,即,把栈顶端位置元素取出,栈中已有元素依次向栈顶方向移动一个位置
整体思想可以用上手枪子弹的思路思考
队列——采取该结构的集合,对元素的存取有如下的特点:
先进先出(即,先存进去的元素,取的时候也是排在前面)
整体思想可以用排队安检
数组——采用该结构的集合,对元素的存取有如下的特点:
(1)查找元素快:通过索引。可以快速访问指定位置的元素
(2)增删元素慢:
在指定位置增加元素,需要创建一个新数组,将指定新元素存储在指定的索引位置,再把原数组根据索引复制到新数组对应的索引位置。
在指定位置删除元素:同理,也要创建一个新数组
链表——采用该结构的集合,对元素的存取有如下的特点:
(1)多个节点之前,通过地址进行连接。例如,多个人手拉手,每个人使用自己的右手拉住下个人的左手,依次类推,这样多个人就连在一起了。
(2)查找元素慢,向查找某个元素,需要通过连接的节点,依次向后查找指定元素
(3)增删元素快:新增只需要修改连接下个元素的地址即可,删除只需要修改连接下个元素的地址即可
——————————————————————————————————————————————————
ArrayList集合
List list1 = new ArrayList();
底层数据结构是数组,查询快,增删慢;线程不安全,效率高
ArrayList 是 java 集合框架中比较常用的数据结构了。继承自 AbstractList,实现了 List 接口。底层基于数组实现容量大小动态变化。允许 null 的存在。同时还实现了 RandomAccess、Cloneable、Serializable 接口,所以ArrayList 是支持快速访问、复制、序列化的。
普通往集合里塞东西
public static void main(String []args){
System.out.println("hello world");
ListTest.arrayList();
}
public static void arrayList(){
List<Object> list = new ArrayList<Object>();
//这里玩一玩ascii码
short num;
char a = 'a';
for(int i=0;i <= 10;i++){
list.add(a);
num = (short)a;
a =(char)++num;
}
System.out.println(list);
}
可以用for也可以用iterator遍历集合
Iterator<Object> iterator = list.iterator();
while(iterator.hasNext()){
Object next = iterator.next();
System.out.println(next);
}
for(int i = 0;i<list.size() ;i++){
System.err.println(list.get(i));
}
有使用过集合的都知道,在用 for 遍历集合的时候是不可以对集合进行 remove操作的,因为 remove 操作会改变集合的大小。从而容易造成结果不准确甚至数组下标越界,更严重者还会抛出 ConcurrentModificationException。
然后做了一个小测试用三种方法遍历Array集合
普通for循环最快,迭代器次之,增强foreach最慢
Arrays的常用函数
添加元素
list.add("1");
将下面的元素添加到第1个位置(往前加入,原角标为0的元素往后排)
list.add(0, "5");
获取第1个元素
System.out.println("the first element is: "+ list.get(0));
根据角标删除元素
arrayList.remove(0);
直接list集合转数组
Object[] array = arrayList.toArray();
list集合指定数组转数组(toArray(T[]a),要传参的那个)
police[] parr = new police[list.size()];
police[] array2 = list.toArray(parr);
System.out.println(array2);
获取ArrayList的大小
list.size()
判断list中是否包含元素(对象要重写hashCode和equals方法)
police policetemplate = new police();
policetemplate.setAge("0");
policetemplate.setNo("0");
boolean contains = arrayList.contains(policetemplate);
System.out.println(contains);
设置第2个元素为10
list.set(1, "10");
判断ArrayList是否为空
list.isEmpty()
放入继承过collection的集合
array.addAll(list);
——————————————————————————————————————————————
LinkedList集合
List list3 = new LinkedList();
底层数据结构是链表,查询慢,增删快;线程不安全,效率高
http://www.cnblogs.com/skywang12345/p/3308807.html、
LinkedList遍历方式
LinkedList支持多种遍历方式。建议不要采用随机访问的方式去遍历LinkedList,而采用逐个遍历的方式。
(01) 第一种,通过迭代器遍历。即通过Iterator去遍历。
for(Iterator iter = list.iterator(); iter.hasNext();)
iter.next();
(02) 通过快速随机访问遍历LinkedList
int size = list.size();
for (int i=0; i<size; i++) {
list.get(i);
}
(03) 通过另外一种for循环来遍历LinkedList
for (Integer integ:list)
;
(04) 通过pollFirst()来遍历LinkedList
while(list.pollFirst() != null)
;
(05) 通过pollLast()来遍历LinkedList
while(list.pollLast() != null)
;
(06) 通过removeFirst()来遍历LinkedList
try {
while(list.removeFirst() != null)
;
} catch (NoSuchElementException e) {
}
(07) 通过removeLast()来遍历LinkedList
try {
while(list.removeLast() != null)
;
} catch (NoSuchElementException e) {
}
效率对比
iteratorLinkedListThruIterator:8 ms
iteratorLinkedListThruForeach:3724 ms
iteratorThroughFor2:5 ms
iteratorThroughPollFirst:8 ms
iteratorThroughPollLast:6 ms
iteratorThroughRemoveFirst:2 ms
iteratorThroughRemoveLast:2 ms
由此可见,遍历LinkedList时,使用removeFist()或removeLast()效率最高。但用它们遍历时,会删除原始数据;若单纯只读取,而不删除,应该使用第3种遍历方式。
无论如何,千万不要通过随机访问去遍历LinkedList!
但是也发现了按顺序遍历的话效率也不慢
常用api与array不同的也就是多了些addfrist removelast这些 没什么特别的
应用场景和效率总结