面向对象语言对事物的描述都是以对象的形式体现的,所以为了方便对多个对象的操作就对对象进行存储,集合(Collection)就是存储对象最常用的一种方式。其实,Collection就是一个接口,在Collection下有很多子接口,其中List和Set是常见的两个接口集合,其他的有Iterator,ListIterator,Comparable和Comparator
Collection是层次结构中的根接口,Collection 表示一组对象,这些对象也称为 collection 的元 素,此接口是 Java Collections Framework 的一个成员。
Collection接口中的两个常见子接口List和Set
Collection
|- -List:元素是有序的,元素可以重复,因为该集合体系有索引
|- -Set :元素是无序的,元素不可以重复
其中List集合有3个常用的子类对象:
List
|- -ArrayList:底层的数据结构是数组结构。 特点:查询速度很快,但是增删稍慢(元素越多表现越
明显),线程是不同步的,效率较高
|- -LinkedList: 底层是链表数据结构,特点: 增删速度很快,查询稍慢
|- -Vector:底层是数组数据结构(JDK1.0版本中就已经有了此容器,vector是同步的,效率较低,
被ArrayList代替了),而且支持枚举
ArrayList和Vector都是数组数据结构的,是固定长度的,而集合是可变长度的,ArrayList默认长度是 10,当要插入的数据超过默认长度时它会new一个新的数组,
长度是50%延长,变成15,然后把原来数组中的元素copy新的数组中来,再将新的元素加入到其后,所以是不断new数组产生的,而Vector默认长度也为10,超过默认时,它是
100%延长,比较浪费内存空间,所以Vector已经不用了
List的特有方法:
凡是可以操作角标(index)的方法都是该体系特有的方法
增:
add(index,element); 在指定位置插入元素
addAll(index,Collection); 在指定位置插入一个集合
删:
remove(index); 在指定位置插入元素
改:
set(index,element); 在指定位置更改元素
查:
get(index); 获取指定元素
subList(frmoIndex,toIndex); 获取子列表(包含头,不包含尾),注意此方法访问的是List
listIterator(); 返回此列表元素的列表迭代器(比较特殊)
indexOf(Object o); 获取元素索引,即获取元素第一次出现的位置,若没有此元素返回-1
迭代器Iterator
迭代器,取出集合中元素的方式,返回值类型比较特殊,是迭代器对象,其中Iterator是Java.util包中的一个接口,迭代器必须依赖具体的容器,因为每一个容器的数据结构都不同, 所以该迭代器对象是在容器中进行内部实现的,对于使用容器者而言,具体是如何实现的不重要,只要通过容器获取到该实现的迭代器的对象即可。也就是iterator()方法
Iterator接口就是对所有的Collection容器进行元素取出的公共接口
正向和逆向遍历迭代器:
boolean hasPrevious() 如果以逆向遍历列表,列表迭代器有多个元素,则返回true
迭代器 Iterator原理示意图1:
迭代器 Iterator原理示意图2:
List集合基本方法代码示例:
public class ListDemo {
public static void main(String[] args) {
BaseMethod();
ListIteratorDemo();
}
//定义一个打印方法
public static void sop(Object obj){
System.out.println(obj);
}
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循环进行遍历,但凡操作角标都用数组原理)方式1:用for循环
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 voidListIteratorDemo(){
ArrayList al = new ArrayList();
al.add("Jay");
al.add("SHE");
al.add("Summer");
al.add("Blue");
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);
}
列表迭代器 ListIterator
ListIterator的产生:
在以下代码中,出现了ConcurrentModificationException的异常错误,这个是并发修改异常原因是对以下的元素操作有两种方式,集合和迭代器两种,此时操作的是同一组元素,当迭代器正在对元素进行取出操作 时,有用到集合的元素在操作元素(a1.add("java007");),就有可能产生安全隐患,这个就是并发访问,不能对同一组元素进行多种同时操作,不能既用集合又用迭代器,否则就会出现并发修改异常
所以在使用迭代器时不能使用集合的方法
/*
Iterator it = al.iterator();
while(it.hasNext()){
Object obj = it.next();
if(obj.equals("SHE"))
a1.add("java007");
}
*/
列表迭代器ListIterator继承了迭代器Iterator,具有除了判断,取出,删除之外的添加,修改等功能。 用迭代器对元素只能进行三个操作,判断it.hasNext(), 取出it.next()和删除it.remove()。 添加动作它不能实现
迭代器有一定的局限性 ,因此会用带列表迭代器