java集合框架list案例_java集合框架——List

一、List接口概述

List有个很大的特点就是可以操作角标。

下面开始介绍List接口中相对于Collection接口比较特别的方法。在Collection接口中已经介绍的方法此处就不再赘述。

1.添加

void

E element)

在列表的指定位置插入指定元素(可选操作)。

boolean

Collection extends E> c)

将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。

这两个方法相对于Collection接口,可以直接在特定的地方插入新的元素或者集合。

2.删除。

移除列表中指定位置的元素(可选操作)。

这个方法相对于Collection接口来说,可以直接删除特定位置上的元素。

3.修改

E element)

用指定元素替换列表中指定位置的元素(可选操作)。

这个方法可以将指定位置上的元素替换为另外一个元素(对象)。

4.查找

返回列表中指定位置的元素。

int

int

返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。

可以看出,上述List所有特有的方法都是和角标操作有关的,这是和List“有序”特点造成的。

5.List接口的特有方法:listIterator

案例:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagep01.BaseCollectionDemo;importjava.util.ArrayList;importjava.util.Iterator;importjava.util.List;public classListIteratorDemo {public static voidmain(String[] args)

{

List al=newArrayList();

al.add("abc1");

al.add("abc2");

al.add("abc3");

al.add("abc4");

Demo1(al);

}private static voidDemo1(List al) {for(Iterator it=al.iterator();it.hasNext();)

{

String str=(String)it.next();

System.out.println(str);if(str=="abc1")

{

al.add("abc5");

}

}

}

}

View Code

运行结果出现了异常:

bdfe64a5b5fb1255a3f1feb2511dc819.png

分析:查看API,可以得到API对ConcurrentModificationException异常的描述:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。程序首先是单线程,怎么就对对象作了并发修改呢?真正的原因是,迭代器在遍历之前就已经确定了容器内对象的数量,如果容器内再增加对象,迭代器将无法确定容器内对象的个数。迭代器在迭代对象,而add方法在添加对象,这就造成了对对象的并发修改。API对此类异常的说明是:如果单线程发出违反对象协定的方法调用序列,则该对象可能抛出此异常。例如,如果线程使用快速失败迭代器在 collection 上迭代时直接修改该 collection,则迭代器将抛出此异常。简单来说,不允许迭代的时候集合对元素进行修改。

解决方法:使用ListIterator迭代器。

ListIterator迭代器是List专门的迭代器,对其他集合的迭代并不适用。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagep01.BaseCollectionDemo;importjava.util.ArrayList;importjava.util.Iterator;importjava.util.List;importjava.util.ListIterator;public classListIteratorDemo {public static voidmain(String[] args)

{

List al=newArrayList();

al.add("abc1");

al.add("abc2");

al.add("abc3");

al.add("abc4");//Demo1(al);

Demo2(al);

}private static voidDemo2(List al) {for(ListIterator li=al.listIterator();li.hasNext();)

{

String str=(String)li.next();if(str.equals("abc1"))

{

li.add("abc5");

}

}

System.out.println(al);

}private static voidDemo1(List al) {for(Iterator it=al.iterator();it.hasNext();)

{

String str=(String)it.next();

System.out.println(str);if(str=="abc1")

{

al.add("abc5");

}

}

}

}

View Code

运行结果:

[abc1, abc5, abc2, abc3, abc4]

解决问题的关键就是使用ListIterator中的add方法添加元素。也就是说无论是迭代还是修改元素,都交给ListIterator来完成。迭代的时候集合对元素进行修改仍然是不允许的。

ListIterator listIterator(int index);方法则是指定了迭代的位置,这个位置可以自行制定,而默认(无参)的情况下是0。

此外,ListIterator还提供了比较有趣的两个方法:

boolean

true。

通过这两个方法可以实现逆向遍历。

6.List接口常用“子类”的特点。

List下有三个类比较常用:Vector、ArrayList、LinkedList。

6.1 Vector类

Vector类自JDK1.0就出现了,它可以说是集合框架的元老级干部。集合框架自JDK2.0出现以后,Vector类就加入了集合框架的队伍并归入了List旗下。Vector类的最大特点就是线程安全,这在整个集合框架中都是少见的。正是因为线程安全,所以执行效率低下,到了现在几乎已经废弃。即使在多线程编程中也不会使用它,而是使用ArrayList加锁代替。Vector内部是一个数组结构,并且是可增长的,步长为100%。Vector增删查询都很慢。

6.2ArrayList类。

ArrayList类是为了替代Vector类而出现的,所以它的功能几乎和Vector类完全相同,但它是非同步的。ArrayList内部也维护了一个变长的数组,增长的步长为50%,查询速度很快。

6.3LinkedList类。

LinkedList是List接口链接列表实现。也就是说我们说的链表。LinkedList最大的特点就是增删速度非常快。

7.LinkedList和ArrayList都有get方法,有什么区别?

两者虽然都是List的子类,但是ArrayList的底层是数组数据结构,在内存中是连续的,所以使用get方法并不用从头开始查找;但是LinkedList底层是链表数据结构,即使使用了get方法,但是仍然需要从头开始查找。

二、Vector类

1.概述。

VectorJDK1.0就已经出现了,在JDK1.2被收入JAVA集合框架中,作为List旗下的一员。它和新出现的collection不同,它是线程安全的。正因为同步,所以效率低,后来被ArrayList所取代。

2.Vector比较List

Vector中有很多方法都被新出现的方法所取代。

而Enumeration又是什么呢?

Enumeration是一个接口,它的功能和Iterator是重复的,但是它在JDK1.0就已经出现了。它只有两个方法:

boolean

这两个方法分别对应着Iterator接口中的两个方法:

boolean

true。

新的实现应当优先考虑使用Iterator接口而不是Enumeration 接口。

3.代码示例。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagep02.VectorDemo;importjava.util.Enumeration;importjava.util.Iterator;importjava.util.Vector;public classVectorDemo

{public static voidmain(String[] args) {

Vector v=newVector();

v.add("abc1");

v.add("abc2");

v.add("abc3");

v.add("abc4");

Demo1(v);

Demo2(v);

}private static voidDemo2(Vector v) {for(Iterator it=v.iterator();it.hasNext();)

{

System.out.println(it.next());

}

}private static voidDemo1(Vector v)

{for (Enumeration e =v.elements(); e.hasMoreElements();)

{

System.out.println(e.nextElement());

}

}

}

View Code

使用for循环遍历容器是最靠谱的,这是应当注意的地方。

三、LinkedList类

1.概述。

LinkedList底层是链表数据结构,这就导致了它的内容在内存中并不是连续的。这也使得它增删速度快而查询速度慢。注意,LinkedList中存储的都是对象的地址,即引用,而非对象本身

2.LinkedList特有的方法。

2.1.添加。

void

void

2.2.删除

null。

null。

后者在JDK1.6之后取代了前者,原因是前者在列表为空的时候抛出了NoSuchElementException异常,而后者则返回Null,这为健壮性的判断创造了更好的条件。

2.3.获取。

null。

null。

peekFirst和peekLast方法在JDK1.6之后取代了getFirst方法和getLast方法,原因同上。

四、ArrayList类

1.概述。

ArrayList和Vector类几乎相同,略。

但需要注意的是,ArrayList中存储的是对象的引用,即地址,而非对象本身。如果ArrayList容器发生了al.add(3);这种情况,但是编译器并没有报错,不能认为是集合中可以存储基本数据类型,事实上在这个过程中发生了两件事:自动装箱以及上转型。这和Object obj=3;有着异曲同工之妙。

2.方法。

略。

注意,虽然ArrayList略掉很多,但并不是说它不重要,只是因为方法中和List接口中的差不多,所以就不做介绍了。实际上在开发中最常使用的类就是ArrayList。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值