在Java的util包中有一个Collection的接口,即集合,这个接口在用来存储对象的的同时提供了很多对对象进行操作方法。Collection也可以看做一个很大的容器,容器中有 很多小的容器,各大容器因为内在的数据结构不同而形成了独有的和共性的特点。其中Collection有两个常见的子接口就是List<>和Set<>。
对于List子接口可以用以下的结构图进行描述:
Collection
|- - - - List:元素是无序的,元素可以重复(因为该集合体系有索引)
|- - - -ArrayList
|- - - -LinkedList
|- - - -Vector
|- - - - Set: 元素是无序的,元素不可以重复
|- - - -HashSet
|- - - -TreeSet
List常见的三个子类对象是ArrayList,LinkedList和Vector ,它们 的数据结构,特点是不同的
ArrayList:底层的数据结构是数组结构 的,特点是查询速度快,但是增删较慢,元素越多表现的越明显,线程是不同不同步的,但是效率较高。
LinkedList:底层的数据结构是链表结构 ,特点是增删速度很快,查询稍慢
Vector: 底层的数据结构也是数组结构,需要强调的是,JDK1.0版本中就已经有了此子类对象,效率较低,已经被ArrayList取代了,但是它是同步的,并且支持枚举
List特有的方法:
在Java的API文档中凡是有index的方法都是该体系特有的方法
增:
add(index,element); 在指定位置插入元素
addAll(index,Collection); 在指定位置插入一个集合
删:
remove(index); 删除指定位置的元素
改:
set(index,element); 在指定位置更改元素
查:
get(index); 获取指定元素
subList(frmoIndex,toIndex); 获取子列表(包含头,不包含尾),注意此方法访问的是List
listIterator(); 返回此列表元素的列表迭代器(比较特殊)
indexOf(Object o); 获取元素索引,即获取元素第一次出现的位置,若没有此元素返回-1
用迭代器Iterator对元素只能进行三个操作,判断it.hasNext(), 取出it.next()和删除it.remove()。 添加动作它不能实现有一定的局限性 ,因此会用带列表迭代器,ListIterator是集合特有的迭代器,ListIterator是Iterator的子接口,列表迭代器ListIterator继承了迭代器Iterator,具有除了判断,取出,删除之外的添加,修改等功能
boolean hasNext() 以正向遍历列表时,如果列表迭代器有多个元素,则返回 true
boolean hasPrevious() 如果以逆向遍历列表,列表迭代器有多个元素,则返回 true。
以下是代码示例:
package com.itheima.day14;
import java.util.*;
/*
*@author Alan
*@date 2014年6月6日
*/
public class ListDemo {
public static void main(String[] args) {
//BaseMethod();
ListIteratorDemo();
}
public static void BaseMethod(){
ArrayList al = new ArrayList();
//添加元素
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
sop("原集合是:"+al);
//1.在指定位置添加元素
al.add(1,"element01");
sop(al);
//2.删除指定位置的元素
al.remove(2);
sop(al);
//3.修改指定位置的元素
al.set(0, "java007");
sop(al);
//4.通过角标获取元素
al.get(3);
sop("获取的结果是:"+al.get(3));
System.out.println();
/*
//5.获取所有元素
for (int x = 0; x < al.size(); x++) {
System.out.println("al("+x+")="+al.get(x));
}
*/
//方式2:用迭代器
Iterator it = al.iterator();
while(it.hasNext()){
sop("next:"+it.next());
}
//6.获取元素索引,通过indexOf()获取对象位置
sop("index="+al.indexOf("java03"));
//7.获取子类表,(包含头,不包含尾)
List sub = al.subList(1, 3); //包含1,不包含3
sop("sub="+sub);
}
public static void ListIteratorDemo(){
ArrayList al = new ArrayList();
al.add("Jay");
al.add("SHE");
al.add("Summer");
al.add("Blue");
sop(al);
/*
//在迭代过程中,准备添加或者删除元素
Iterator it = al.iterator();
while(it.hasNext()){
Object obj = it.next();
if(obj.equals("SHE")) //当遍历到"SHE"的时候插入"java007"
//a1.add("java007");//出现并发修改异常,不能在使用迭代器的同时使用集合对同一组元素进行操作
it.remove(); //即遍历到"SHE"的时候就把它"SHE"删除
//将"SHE"的引用从集合中删除,但是元素还在集合中,还在被Obj使用,所以被打印,没有看到被删除的结果
sop("obj="+obj);
sop(al);//此时打印的是集合中的元素,所以已经显示删除所删内容
}
*/
//演示列表迭代器
ListIterator li = al.listIterator();
//sop("hasPrevious():"+li.hasPrevious());
//正向遍历
while(li.hasNext()){
Object obj = li.next();
if(obj.equals("Summer"))//若遍历到"Summer"时,就对其进行操作
//li.add("Java009");
li.set("Java007");
}
//逆向遍历
while(li.hasPrevious()){
sop("pre::"+li.previous());
}
//sop("hasNext():"+li.hasNext());
//sop("hasPrevious:"+li.hasPrevious());
sop(al);
}
//定义的一个打印方法
public static void sop(Object obj){
System.out.println(obj);
}
}
常见错误:
在以上的代码中的过程中很容易出现这样的错误 :
Iterator it = al.iterator();
while(it.hasNext()){
Object obj = it.next();
if(obj.equals("SHE"))
a1.add("java007")
以上会出现ConcurrentModificationException的异常错误,这个是并发修改异常,触发此异常的原因是:
对以下的元素操作有两种方式,集合和迭代器两种,此时操作的是同一组元素,当迭代器正在对元素进行取出操作时,有用到集合的元素在操作元素(a1.add("java007");),就有可能产生安全隐患,这个就是并发访问,不能对同一组元素进行多种同时操作,不能既用集合又用迭代器,否则就会出现 。所以在使用迭代器时不能使用集合的方法