一、List接口概述。

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

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

1.添加

 void add(int index, E element) 
          在列表的指定位置插入指定元素(可选操作)。
 boolean addAll(int index, Collection<? extends E> c) 
          将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。

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

2.删除。

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

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

3.修改

 E set(int index, E element) 
          用指定元素替换列表中指定位置的元素(可选操作)。

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

4.查找

 E get(int index) 
          返回列表中指定位置的元素。
 int indexOf(Object o) 
          返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。
 int lastIndexOf(Object o) 
          返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 -1。
 List<E> subList(int fromIndex, int toIndex) 
          返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。

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

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

 ListIterator<E> listIterator() 
          返回此列表元素的列表迭代器(按适当顺序)。
 ListIterator<E> listIterator(int index) 
          返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。

案例:

 package p01.BaseCollectionDemo;

 import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; public class ListIteratorDemo { public static void main(String[] args)
{
List al=new ArrayList();
al.add("abc1");
al.add("abc2");
al.add("abc3");
al.add("abc4");
Demo1(al);
} private static void Demo1(List al) {
for(Iterator it=al.iterator();it.hasNext();)
{
String str=(String)it.next();
System.out.println(str);
if(str=="abc1")
{
al.add("abc5");
}
}
} }

运行结果出现了异常:

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

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

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

 package p01.BaseCollectionDemo;

 import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator; public class ListIteratorDemo { public static void main(String[] args)
{
List al=new ArrayList();
al.add("abc1");
al.add("abc2");
al.add("abc3");
al.add("abc4");
// Demo1(al);
Demo2(al);
} private static void Demo2(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 void Demo1(List al) {
for(Iterator it=al.iterator();it.hasNext();)
{
String str=(String)it.next();
System.out.println(str);
if(str=="abc1")
{
al.add("abc5");
}
}
} }

运行结果:

[abc1, abc5, abc2, abc3, abc4]

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

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

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

 boolean hasPrevious() 
          如果以逆向遍历列表,列表迭代器有多个元素,则返回 true。
 E previous() 
          返回列表中的前一个元素。

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

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

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

6.1Vector类。

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<E> elements()
          返回此向量的组件的枚举。

而Enumeration又是什么呢?

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

 boolean hasMoreElements()
          测试此枚举是否包含更多的元素。
 E nextElement()

          如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。

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

 boolean hasNext()
          如果仍有元素可以迭代,则返回 true。
 E next()

          返回迭代的下一个元素。

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

3.代码示例。

 package p02.VectorDemo;

 import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector; public class VectorDemo
{
public static void main(String[] args) {
Vector v=new Vector();
v.add("abc1");
v.add("abc2");
v.add("abc3");
v.add("abc4"); Demo1(v);
Demo2(v);
} private static void Demo2(Vector v) { for(Iterator it=v.iterator();it.hasNext();)
{
System.out.println(it.next());
} } private static void Demo1(Vector v)
{
for (Enumeration e = v.elements(); e.hasMoreElements();)
{
System.out.println(e.nextElement());
}
} }

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

三、LinkedList类。

1.概述。

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

2.LinkedList特有的方法。

2.1.添加。

 void addFirst(E e)
          将指定元素插入此列表的开头。
 void addLast(E e)

          将指定元素添加到此列表的结尾。

2.2.删除

 E removeFirst()
          移除并返回此列表的第一个元素。
 E removeLast()
          移除并返回此列表的最后一个元素。
 E pollFirst()
          获取并移除此列表的第一个元素;如果此列表为空,则返回 null。
 E pollLast()

          获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。

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

2.3.获取。

 E getFirst()
          返回此列表的第一个元素。
 E getLast()

          返回此列表的最后一个元素。
 E peekFirst()
          获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。
 E peekLast()

          获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。

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

四、ArrayList类。

1.概述。

ArrayList和Vector类几乎相同,略。

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

2.方法。

略。

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

【JAVA集合框架之List】的更多相关文章

  1. Java集合框架List,Map,Set等全面介绍

    Java集合框架的基本接口/类层次结构: java.util.Collection [I]+--java.util.List [I]   +--java.util.ArrayList [C]   +- ...

  2. Java集合框架练习-计算表达式的值

    最近在看<算法>这本书,正好看到一个计算表达式的问题,于是就打算写一下,也正好熟悉一下Java集合框架的使用,大致测试了一下,没啥问题. import java.util.*; /* * ...

  3. 【集合框架】Java集合框架综述

    一.前言 现笔者打算做关于Java集合框架的教程,具体是打算分析Java源码,因为平时在写程序的过程中用Java集合特别频繁,但是对于里面一些具体的原理还没有进行很好的梳理,所以拟从源码的角度去熟悉梳 ...

  4. Java 集合框架

    Java集合框架大致可以分为五个部分:List列表,Set集合.Map映射.迭代器.工具类 List 接口通常表示一个列表(数组.队列.链表 栈),其中的元素 可以重复 的是:ArrayList 和L ...

  5. Java集合框架之map

    Java集合框架之map. Map的主要实现类有HashMap,LinkedHashMap,TreeMap,等等.具体可参阅API文档. 其中HashMap是无序排序. LinkedHashMap是自 ...

  6. 22章、Java集合框架习题

    1.描述Java集合框架.列出接口.便利抽象类和具体类. Java集合框架支持2种容器:(1) 集合(Collection),存储元素集合 (2)图(Map),存储键值对.

  7. Java集合框架实现自定义排序

    Java集合框架针对不同的数据结构提供了多种排序的方法,虽然很多时候我们可以自己实现排序,比如数组等,但是灵活的使用JDK提供的排序方法,可以提高开发效率,而且通常JDK的实现要比自己造的轮子性能更优 ...

  8. (转)Java集合框架:HashMap

    来源:朱小厮 链接:http://blog.csdn.net/u013256816/article/details/50912762 Java集合框架概述 Java集合框架无论是在工作.学习.面试中都 ...

  9. Java集合框架

    集合框架体系如图所示 Java 集合框架提供了一套性能优良,使用方便的接口和类,java集合框架位于java.util包中, 所以当使用集合框架的时候需要进行导包. Map接口的常用方法 Map接口提 ...

  10. Java集合框架(常用类) JCF

    Java集合框架(常用类) JCF 为了实现某一目的或功能而预先设计好一系列封装好的具有继承关系或实现关系类的接口: 集合的由来: 特点:元素类型可以不同,集合长度可变,空间不固定: 管理集合类和接口 ...

随机推荐

  1. Linux的后台执行进程之nohup

    nohup 用途:LINUX命令用法,不挂断地运行命令.  语法:nohup Command [ Arg ... ] [ & ]  描述:nohup 命令运行由 Command 参数和任何相关 ...

  2. HDU——PKU题目分类

    HDU 模拟题, 枚举1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 ...

  3. python入门教程链接

    python安装 选择 2.7及以上版本 linux: 一般都自带 windows: https://www.python.org/downloads/windows/ mac os: https:/ ...

  4. ndk学习13: proc

    一.进程相关信息 /proc目录中包含许多以数字命名的子目录,这些数字表示系统当前正在运行进程的进程号,里面包含对应进程相关的多个信息文件 结构如下: 进程相关的信息如下: 部分信息如下 cmdlin ...

  5. mysql中You can't specify target table for update in FROM clause错误

    原SQL delete from DEP_SYSTEM_PORTLET_SETTINGS where ID in ( select ID from DEP_SYSTEM_PORTLET_SETTING ...

  6. yum服务器搭建(深入理解yum工作原理)

    作者:firefoxbug 时间:July 27, 2014 分类:Linux 前言 在前面一篇rpm包制作描述了rpm的打包过程,这篇文章主要讲述yum的工作原理. yum 运行原理 yum的工作需 ...

  7. meeting room I & II

    Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si ...

  8. jq获取元素

    <tr><td><div id="add"></div></td></tr>$("#add&quo ...

  9. POJ 2479

    ---恢复内容开始--- http://poj.org/problem?id=2479 #include <stdio.h> #include <iostream> using ...

  10. mysql grant ,User,revoke

    mysql的权限一直都都是很关心的重点,我知道的也只是很少的一部分,对于每个数据库我习惯创建一个一个用户,该用户只对自己从属的数据库产生进行操作,在一部分的程度上可以保护自己的数据库, 比如我有一个数 ...