List集合代表一个有序集合,集合中每个元素都有其对应的顺序索引。List集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。

1、List接口和ListIterator接口

List作为Collection接口的子接口,可以使用Collection接口里的全部方法。List是有序集合,所以List集合里增加了一些根据索引来操作集合元素的方法:

  • void add(int index, Object element):将元素element插入在List集合的index处。
  • boolean addAll(int index, Collection c):将集合c所包含的所有元素都插入在List集合的index处。
  • Object get(int index):返回集合index索引处的元素。
  • int lastIndexOf(Object o):返回对象o在List集合中最后一次出现的位置索引。
  • Object remove(int index):删除并返回index索引处的元素。
  • Object set(int index, Object element):将index索引处的元素替换成element对象,返回新元素。
  • List subList(int fromIndex, int toIndex):返回从索引fromIndex(包含)到索引toIndex(不包含)处所有集合元素组成的子集合。

List集合可以根据索引来插入、替换和删除集合元素。

示例程序:

public class TestList
{
public static void main(String[] args)
{
List books = new ArrayList();
//向books集合中添加三个元素
books.add(new String("轻量级J2EE企业应用实战"));
books.add(new String("Struts2权威指南"));
books.add(new String("基于J2EE的Ajax宝典"));
System.out.println(books);
//将新字符串对象插入在第二个位置
books.add(1 , new String("ROR敏捷开发最佳实践")); //已添加的对象,和下面语句做对比
for (int i = 0 ; i < books.size() ; i++ )
{
System.out.println(books.get(i));
}
//删除第三个元素
books.remove(2);
System.out.println(books);
//判断指定元素在List集合中位置:输出1,表明位于第二位
System.out.println(books.indexOf(new String("ROR敏捷开发最佳实践"))); //新创建的对象
//将第二个元素替换成新的字符串对象
books.set(1, new String("Struts2权威指南"));
System.out.println(books);
//将books集合的第二个元素(包括)到第三个元素(不包括)截取称子集合
System.out.println(books.subList(1 , 2)); }
}

程序运行结果:

[轻量级J2EE企业应用实战, Struts2权威指南, 基于J2EE的Ajax宝典] 
轻量级J2EE企业应用实战 
ROR敏捷开发最佳实践 
Struts2权威指南 
基于J2EE的Ajax宝典 
[轻量级J2EE企业应用实战, ROR敏捷开发最佳实践, 基于J2EE的Ajax宝典] 

[轻量级J2EE企业应用实战, Struts2权威指南, 基于J2EE的Ajax宝典] 
[Struts2权威指南]

程序说明:List集合可以使用普通for循环来遍历集合元素。List判断两个对象相等只要通过equals方法比较返回true即可。如在判断“ROR敏捷开发最佳实践”字符串的位置是,新创建了一个新字符串对象,但是程序仍返回第一次创建字符串对象的位置。当调用List的set(int index, Object element)方法来改变List集合指定索引处元素时,指定的索引必须是List集合的有效索引。

与set只提供了一个iterator()方法不同,List还额外提供了一个listIteratro()方法,该方法返回一个ListIterator对象,ListIterator接口继承了Iterator接口,提供了专门操作List的方法。

ListIterator接口在Iterator接口基础上增加了如下方法:

  • boolean hasPrevious():返回该迭代器关联集合是否还有上一个元素。
  • Object previous():返回该迭代器上一个元素。
  • void add():在指定位置插入一个元素。

程序示例:

public static void main(String[] args)
{
String[] books = {
"Struts2权威指南",
"轻量级J2EE企业应用实战"
};
List bookList = new ArrayList();
for (int i = 0; i < books.length ; i++ )
{
bookList.add(books[i]);
}
ListIterator lit = bookList.listIterator();
while (lit.hasNext())
{
System.out.println(lit.next());
lit.add("-------分隔符-------");
}
System.out.println("==========下面开始反向迭代===========");
while(lit.hasPrevious())
{
System.out.println(lit.previous());
}
}
}

程序运行结果:

Struts2权威指南 
轻量级J2EE企业应用实战 
==========下面开始反向迭代=========== 
-------分隔符------- 
轻量级J2EE企业应用实战 
-------分隔符------- 
Struts2权威指南

程序说明:List通过ListTterator迭代集合时,即可采用next()方法进行正向迭代,迭代过程中可以使用add()方法向上一次迭代元素的后面添加一个新元素。同时程序演示了向前迭代。

2、ArrayList和Vector实现类

ArrayList和Vector作为List类的两个典型实现,完全支持前面介绍的List接口全部功能。

ArrayList和Vector类都是基于数组实现的List类,他们封装了一个动态再分配的Object[]数组。每个ArrayList或Vector对象有一个capacity属性,表示它们所封装的Object[]数组的长度。capacity会添加元素的个数而自动增加。当向集合中添加大量元素时,可以使用ensureCapacity方法一次性地增加capacity。这可以减少增加重分配次数,从而提供性能。capacity大小也可以在创建时就指定,该属性默认为10.

ArrayList和Vector提供如下两个方法来操作capacity属性:

  • void ensureCapacity(int minCapacity):将ArrayList或Vector集合的capacity增加minCapacity。
  • void trimToSize():调整ArrayList或Vector集合的capacity为列表当前大小。程序可调用该方法来减少ArrayList或Vector集合对象存储空间。

ArrayList和Vector用法几乎相同,Vector是一个古老的集合(从JDK1.0),起初Java还没有提供系统的集合框架,所以Vector里提供了一些方法名很长的方法:例如addElement(Object obj), 等同于add()方法。从JDK1.2以后,Java提供了系统的集合框架,就将Vector改为实习List接口,作为List的实习之一,从而导致Vector里有一些功能重复的方法。Vector具有很多缺点,通常尽量少用Vector实现类。

ArrayList和Vector的区别:ArrayList是线程不安全的,多个线程访问同一个ArrayList集合时,如果有超过一条线程修改了ArrayList集合,则程序必须手动保证该集合的同步性。Vector集合则是线程安全的,无线程序保证该集合的同步性。因为Vector是线程安全的,所以Vector的性能比ArrayList的性能要低。实际上,即使保证List集合线程安全,同样不推荐使用Vector实现类。Collections工具类,可以将一个ArrayList变成线程安全的。

Vector还提供了一个Stack子类,它用于模拟了”栈“这种数据结构,”栈“通常是指”后进先出“(LIFO)的容器。最后”push“进栈的元素,将最先被”pop“出栈。与Java中其他集合一样,进栈出栈的都是Object,因此从栈中取出元素后必须做类型转换,除非你只是使用Object具有的操作。所以stack类提供了如下几个方法:

  • Object peek():返回”栈“的第一个元素,但并不将该元素”pop“出栈。
  • Object pop():返回”栈“的第一个元素,并将该元素”pop“出栈。
  • void push(Object item):将一个元素”push“进栈,最后一个进”栈“的元素总是位于”栈“顶。

程序示例:

public class TestVector
{
public static void main(String[] args)
{
Stack v = new Stack();
//依次将三个元素push入"栈"
v.push("Struts2权威指南");
v.push("轻量级J2EE企业应用实战");
v.push("ROR敏捷开发最佳实践");
//输出:[Struts2权威指南, 轻量级J2EE企业应用实战, ROR敏捷开发最佳实践]
System.out.println(v);
//访问第一个元素,但并不将其pop出"栈",输出:ROR敏捷开发最佳实践
System.out.println(v.peek());
//依然输出:[Struts2权威指南, 轻量级J2EE企业应用实战, ROR敏捷开发最佳实践]
System.out.println(v);
//pop出第一个元素,输出:ROR敏捷开发最佳实践
System.out.println(v.pop());
//依然输出:[Struts2权威指南, 轻量级J2EE企业应用实战]
System.out.println(v);
}
}

程序运行结果:

[Struts2权威指南, 轻量级J2EE企业应用实战, ROR敏捷开发最佳实践] 
ROR敏捷开发最佳实践 
[Struts2权威指南, 轻量级J2EE企业应用实战, ROR敏捷开发最佳实践] 
ROR敏捷开发最佳实践 
[Struts2权威指南, 轻量级J2EE企业应用实战]

3、LinkedList实现类

List还有一个LinkedList的实现,它是一个基于链表实现的List类,对于顺序访问集合中的元素进行了优化,特别是当插入、删除元素时速度非常快。因为LinkedList即实现了List接口,也实现了Deque接口(双向队列),Deque接口是Queue接口的子接口,它代表一个双向列表,Deque接口里定义了一些可以双向操作队列的方法:

  • void addFirst(Object e):将制定元素插入该双向队列的开头。
  • void addLast(Object e):将制定元素插入该双向队列的末尾。
  • Iterator descendingIterator():返回以该双向队列对应的迭代器,该迭代器将以逆向顺序来迭代队列中的元素。
  • Object getFirst():获取、但不删除双向队列的第一个元素。
  • Object getLast(): 获取、但不删除双向队列的最后一个元素。
  • boolean offerFirst(Object e): 将指定的元素插入该双向队列的开头。
  • boolean offerLast(Object e): 将指定的元素插入该双向队列的末尾。
  • Object peekFirst(): 获取、但不删除该双向队列的第一个元素:如果此双端队列为空,则返回null。
  • Object peekLast():获取、但不删除该双向队列的最后一个元素:如果此双端队列为空,则返回null。
  • Object pollFirst():获取、并删除该双向队列的第一个元素:如果此双端队列为空,则返回null。
  • Object pollLast():获取、并删除该双向队列的最后一个元素:如果此双端队列为空,则返回null。
  • Object pop():pop出该双向队列所表示的栈中第一个元素。
  • void push(Object e):将一个元素push进该双向队列所表示的栈中(即该双向队列的头部)。
  • Object removerFirst():获取、并删除该双向队列的最后一个元素。
  • Object removeFirstOccurrence(Object o):删除该双向队列的第一次的出现元素o。
  • Object removeLast():获取、并删除该双向队列的最后一个元素。
  • Object removeLastOccurrence(Object o):删除该双向队列的最后一次出现的元素o。

从上面方法中可以看出,LinkedList不仅可以当成双向队列使用,也可以当成“栈”使用。同时,LinkedList实现了List接口,所以还被当成List使用。

程序示例:

public class TestLinkedList
{
public static void main(String[] args)
{
LinkedList books = new LinkedList();
//将字符串元素加入队列的尾部
books.offer("Struts2权威指南");
//将一个字符串元素入栈
books.push("轻量级J2EE企业应用实战");
//将字符串元素添加到队列的头部
books.offerFirst("ROR敏捷开发最佳实践");
for (int i = 0; i < books.size() ; i++ )
{
System.out.println(books.get(i));
}
//访问、并不删除队列的第一个元素
System.out.println(books.peekFirst());
//访问、并不删除队列的最后一个元素
System.out.println(books.peekLast());
//采用出栈的方式将第一个元素pop出队列
System.out.println(books.pop());
//下面输出将看到队列中第一个元素被删除
System.out.println(books);
//访问、并删除队列的最后一个元素
System.out.println(books.pollLast());
//下面输出将看到队列中只剩下中间一个元素:轻量级J2EE企业应用实战
System.out.println(books); }
}

程序运行结果:

ROR敏捷开发最佳实践 
轻量级J2EE企业应用实战 
Struts2权威指南 
ROR敏捷开发最佳实践 
Struts2权威指南 
ROR敏捷开发最佳实践 
[轻量级J2EE企业应用实战, Struts2权威指南] 
Struts2权威指南 
[轻量级J2EE企业应用实战]

说明:程序中示范了LinkedList作为双向队列、栈和List集合的用法。LinkedList与ArrayList、Vector的实现机制完全不同,ArrayList、Vector内部以数组的形式来保存集合中的元素,因此随机访问集合元素上有较好的性能;而LinkedList内部以链表的形式来保存集合中的元素,因此随机访问集合时性能较差,但在插入、删除元素时性能非常出色(只需改变指针所指的地址即可)。Vector因实现了线程同步功能,所以各方面性能有所下降。

关于使用List集合的几点建议:

  • 如果需要遍历List集合元素,对应ArrayList、Vector集合,则应该使用随机访问方法(get)来遍历集合元素,这样性能更好。对应LinkedList集合,则应采用迭代器(Iterator)来遍历集合元素。
  • 如果需要经常执行插入、删除操作来改变Lst集合大小,则应该使用LinkedList集合,而不是ArrayList。
  • 如果多条线程需要同时访问List集合中的元素,可以考虑使用Vector这个同步实现。

转载:http://www.cnblogs.com/zhxxcq/archive/2012/04/18/2455916.html

[转载]List接口的使用的更多相关文章

  1. 转载-- http接口、api接口、RPC接口、RMI、webservice、Restful等概念

     http接口.api接口.RPC接口.RMI.webservice.Restful等概念 收藏 Linux一叶 https://my.oschina.net/heavenly/blog/499661 ...

  2. 网络转载——java接口的概念

    为什么会出现接口? 接口的出现是为了扩展java中的类继承的单调性.这样使得功能更加丰富. 接口关键字? 定义接口interface,实现一个接口  implements 什么接口呢? 接口是一种特殊 ...

  3. 转载:《TypeScript 中文入门教程》 3、接口

    版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 TypeScript的核心原则之一是对值所具有的shape进行类型检查. 它有时 ...

  4. 浅谈 PHP 与手机 APP 开发(API 接口开发) -- 转载

    转载自:http://www.thinkphp.cn/topic/5023.html 这个帖子写给不太了解PHP与API开发的人 一.先简单回答两个问题: 1.PHP 可以开发客户端? 答:不可以,因 ...

  5. 转载:详细解析Java中抽象类和接口的区别

    在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力.abstract class和int ...

  6. 【转载】关于Alipay支付宝接口(Java版)

    转载自:http://blog.163.com/lai_chao/blog/static/70340789201412724619514/ 1.alipay 双功能支付简介 2.alipay 提交支付 ...

  7. Java _Map接口的使用(转载)

    转载自:http://blog.csdn.net/tomholmes7/article/details/2663379.转载请注明原作者地址 Map Map以按键/数值对的形式存储数据,和数组非常相似 ...

  8. (转载)Linux系统调用及用户编程接口(API)

    (转载)http://www.farsight.com.cn/news/emb167.htm 1 Linux系统调用 所谓系统调用是指操作系统提供给用户程序调用的一组“特殊”接口,用户程序可以通过这组 ...

  9. Android开发---支付宝功能接口(支付功能)(转载!)

    最近在做一个关于购物商城的项目,项目里面付款这块我选的是调用支付宝的接口,因为用的人比较多. 在网上搜索了以下,有很多这方面的教程,但大部分教程过于陈旧,而且描述的过于简单.而且支付宝提供的接口一直在 ...

随机推荐

  1. 解决SSH远程执行命令找不到环境变量的问题

    通过SSH执行远程主机的命令或脚本时,经常会出现找不到自定义环境变量的问题.但是,如果通过SSH登录远程主机,然后再执行相同的命令或脚本,那么此时执行又是成功的.两种相似的方法,得到的结果却截然不同, ...

  2. 初步了解,vue的转发机制(proxyTable)

    vue的转发机制(proxyTable),proxyTable代理功能可以实现转发机制,需要修改config里面修改index.js文件 修改index.vue中请求的代码(该功能是webpack-s ...

  3. 对于react中rredux的理解

    1.什么是redux? redux是一个应用数据流框架,主要作用是对于应用状态的管理 2.reducer特点 : (1)默认的state (2)state是只可读不可修改 (3)必须返回一个纯函数 3 ...

  4. react中对于redux的封装

    const createStore = (reducer)=>{ //默认的state对象 let state = {}; //将所有订阅的事件存在在这个数组中 let listeners = ...

  5. 加域电脑登陆系统后桌面文件丢失,登录系统提示用户名为“Temp”。

    注册表中定位到“HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\ProfileList”, ...

  6. linux查看服务器并发连接数

    netstat -n | awk '/^tcp/ {++S[$NF]} END {for(key in S) print key,"\t",S[key]}'

  7. 2018年-2019年第二学期第五周C#学习个人总结

    在本周我学习了第五章面向对象高级中的5.3多态,5.3多态中主要包括重写父类方法,多态的实现,base关键字,里氏转换原则,Object类.在重写父类方法中要求当重写父类的方法时,要求子类的方法名,参 ...

  8. chrome浏览器导出文件提示病毒扫描失败

    转自https://zhidao.baidu.com/question/758059392558639324.html 1.windows+R,打开运行 2.输入regedit.exe,确定,打开注册 ...

  9. iOS imageNamed 与 imageWithContentsOfFile 的区别

    imageNamed 方法 1)后面的参数是icon的名字,图片可以存在项目中,也可以存在Asset中 2)该方法只适合一些中小型的图片读取,而一些比较大的资源图片并不适合用这个方法 3)这个方法加载 ...

  10. linux下 如何切换到root用户

    默认安装完成之后并不知道root用户的密码,那么如何应用root权限呢? (1)sudo 命令 xzm@ubuntu:~$  sudo 这样输入当前管理员用户密码就可以得到超级用户的权限.但默认的情况 ...