List

1.3.1        概述

前面我们讲述的Collection接口实际上并没有直接的实现类。而List是容器的一种,表示列表的意思。当我们不知道存储的数据有多少的情况,我们就可以使用List 来完成存储数据的工作。例如前面提到的一种场景。我们想要在保存一个应用系统当前的在线用户的信息。我们就可以使用一个List来存储。因为List的最大的特点就是能够自动的根据插入的数据量来动态改变容器的大小。下面我们先看看List接口的一些常用方法。

1.3.2         常用方法

List 就是列表的意思,它是Collection 的一种,继承了 Collection 接口,以定义一个允许重复项的有序集合。该接口不但能够对列表的一部分进行处理,还添加了面向位置的操作。List 是按对象的进入顺序进行保存对象,而不做排序或编辑操作。它除了拥有Collection接口的所有的方法外还拥有一些其他的方法。

面向位置的操作包括插入某个元素或 Collection 的功能,还包括获取、除去或更改元素的功能。在 List 中搜索元素可以从列表的头部或尾部开始,如果找到元素,还将报告元素所在的位置。

void add(int index, Object element) :添加对象element到位置index上

boolean addAll(int index, Collection collection) :在index位置后添加容器collection中所有的元素

Object get(int index) :取出下标为index的位置的元素

int indexOf(Object element) :查找对象element 在List中第一次出现的位置

int lastIndexOf(Object element) :查找对象element 在List中最后出现的位置

Object remove(int index) :删除index位置上的元素

Object set(int index, Object element) :将index位置上的对象替换为element 并返回老的元素。

先看一下下面表格:

 

简述

实现

操作特性

成员要求

List

提供基于索引的对成员的随机访问

ArrayList

提供快速的基于索引的成员访问,对尾部成员的增加和删除支持较好

成员可为任意Object子类的对象

LinkedList

对列表中任何位置的成员的增加和删除支持较好,但对基于索引的成员访问支持性能较差

成员可为任意Object子类的对象

在“集合框架”中有两种常规的 List 实现:ArrayList 和 LinkedList。使用两种 List 实现的哪一种取决于您特定的需要。如果要支持随机访问,而不必在除尾部的任何位置插入或除去元素,那么,ArrayList 提供了可选的集合。但如果,您要频繁的从列表的中间位置添加和除去元素,而只要顺序的访问列表元素,那么,LinkedList 实现更好。

我们以ArrayList 为例,先看一个简单的例子:

例子中,我们把12个月份存放到ArrayList 中,然后用一个循环,并使用get()方法将列表中的对象都取出来。

而LinkedList 添加了一些处理列表两端元素的方法(下图只显示了新方法):

使用这些新方法,您就可以轻松的把 LinkedList 当作一个堆栈、队列或其它面向端点的数据结构。

我们再来看另外一个使用LinkedList 来实现一个简单的队列的例子:

import java.util.*;

public class ListExample {

  public static void main(String args[]) {

    LinkedList queue = new LinkedList();

    queue.addFirst("Bernadine");

    queue.addFirst("Elizabeth");

    queue.addFirst("Gene");

    queue.addFirst("Elizabeth");

    queue.addFirst("Clara");

    System.out.println(queue);

    queue.removeLast();

    queue.removeLast();

    System.out.println(queue);

  }

}

运行程序产生了以下输出。请注意,与 Set 不同的是 List 允许重复。

[Clara, Elizabeth, Gene, Elizabeth, Bernadine]

[Clara, Elizabeth, Gene]

该的程序演示了具体 List 类的使用。第一部分,创建一个由 ArrayList 支持的 List。填充完列表以后,特定条目就得到了。示例的 LinkedList 部分把 LinkedList 当作一个队列,从队列头部添加东西,从尾部除去。

List 接口不但以位置友好的方式遍历整个列表,还能处理集合的子集:

ListIterator listIterator() :返回一个ListIterator 跌代器,默认开始位置为0

ListIterator listIterator(int startIndex) :返回一个ListIterator 跌代器,开始位置为startIndex

List subList(int fromIndex, int toIndex) :返回一个子列表List ,元素存放为从 fromIndex 到toIndex之前的一个元素。

处理 subList() 时,位于 fromIndex 的元素在子列表中,而位于 toIndex 的元素则不是,提醒这一点很重要。以下 for-loop 测试案例大致反映了这一点:

for (int i=fromIndex; i<toIndex; i++) {

// process element at position i

}

此外,我们还应该提醒的是:对子列表的更改(如 add()、remove() 和 set() 调用)对底层 List 也有影响。

ListIterator 接口

ListIterator 接口继承 Iterator 接口以支持添加或更改底层集合中的元素,还支持双向访问。

以下源代码演示了列表中的反向循环。请注意 ListIterator 最初位于列表尾之后(list.size()),因为第一个元素的下标是0。

List list = ...;
ListIterator iterator = list.listIterator(list.size());
while (iterator.hasPrevious()) {
  Object element = iterator.previous();
  // Process element
}

正常情况下,不用 ListIterator 改变某次遍历集合元素的方向 — 向前或者向后。虽然在技术上可能实现时,但在 previous() 后立刻调用 next(),返回的是同一个元素。把调用 next() 和 previous() 的顺序颠倒一下,结果相同。

我们看一个List的例子:

import java.util.*;

public class ListIteratorTest {

   public static void main(String[] args) {

      List list = new ArrayList();

      list.add("aaa");

      list.add("bbb");

      list.add("ccc");

      list.add("ddd");  

      System.out.println("下标0开始:"+list.listIterator(0).next());//next()

      System.out.println("下标1开始:"+list.listIterator(1).next());

      System.out.println("子List 1-3:"+list.subList(1,3));//子列表

      ListIterator it = list.listIterator();//默认从下标0开始

      //隐式光标属性add操作 ,插入到当前的下标的前面

      it.add("sss");

      while(it.hasNext()){

         System.out.println("next Index="+it.nextIndex()+",Object="+it.next());

      }    

      //set属性

      ListIterator it1 = list.listIterator();

      it1.next();

      it1.set("ooo");

      ListIterator it2 = list.listIterator(list.size());//下标

      while(it2.hasPrevious()){

         System.out.println("previous Index="+it2.previousIndex()+",Object="+it2.previous());

      }

   }

}

程序的执行结果为:

下标0开始:aaa

下标1开始:bbb

子List 1-3:[bbb, ccc]

next Index=1,Object=aaa

next Index=2,Object=bbb

next Index=3,Object=ccc

next Index=4,Object=ddd

previous Index=4,Object=ddd

previous Index=3,Object=ccc

previous Index=2,Object=bbb

previous Index=1,Object=aaa

previous Index=0,Object=ooo

我们还需要稍微再解释一下 add() 操作。添加一个元素会导致新元素立刻被添加到隐式光标的前面。因此,添加元素后调用 previous() 会返回新元素,而调用 next() 则不起作用,返回添加操作之前的下一个元素。下标的显示方式,如下图所示:

对于List 的基本用法我们学会了,下面我们来进一步了解一下List的实现原理,以便价升我们对于集合的理解。

 

J2SE知识点摘记(二十)的更多相关文章

  1. J2SE知识点摘记(二十六)

    为了用“集合框架”的额外部分把排序支持添加到 Java 2 SDK,版本 1.2,核心 Java 库作了许多更改.像 String 和 Integer 类如今实现 Comparable 接口以提供自然 ...

  2. J2SE知识点摘记(二十五)

    Set 1.5.1        概述 Java 中的Set和正好和数学上直观的集(set)的概念是相同的.Set最大的特性就是不允许在其中存放的元素是重复的.根据这个特点,我们就可以使用Set 这个 ...

  3. J2SE知识点摘记(二十四)

     覆写hashCode() 在明白了HashMap具有哪些功能,以及实现原理后,了解如何写一个hashCode()方法就更有意义了.当然,在HashMap中存取一个键值对涉及到的另外一个方法为equa ...

  4. J2SE知识点摘记(二十二)

    Map 1.4.1        概述 数学中的映射关系在Java中就是通过Map来实现的.它表示,里面存储的元素是一个对(pair),我们通过一个对象,可以在这个映射关系中找到另外一个和这个对象相关 ...

  5. J2SE知识点摘记(二十三)

    我们简单介绍一下这个接口: 1.4.3        Comparable 接口 在 java.lang 包中,Comparable 接口适用于一个类有自然顺序的时候.假定对象集合是同一类型,该接口允 ...

  6. J2SE知识点摘记(二)

    1.    对象的声明 "类名 对象名 = new 类名();"例子:Person P;//先声明一个Person类的对象p p=new Person();//用new关键字实例化 ...

  7. J2SE知识点摘记(二十一)

    实现原理 前面已经提了一下Collection的实现基础都是基于数组的.下面我们就已ArrayList 为例,简单分析一下ArrayList 列表的实现方式.首先,先看下它的构造函数. 下列表格是在S ...

  8. 小小知识点(二十六)关于5G发展的28个核心问题,来自华为内部的深度解读

    本文来自微信公众号“腾讯深网”(ID:qqshenwang),作者 马关夏.36氪经授权转载. 一.5G先进性与行业应用 1.5G到底是什么?和4G比有什么不一样? 从国际电信联盟(ITU)的定义来看 ...

  9. J2SE知识点摘记(十二)

    1.      File类 下面的构造方法可以用来生成File对象 File(String directoryPath) geName()用于返回文件名,getParent()返回父目录名,exist ...

随机推荐

  1. spark JavaDirectKafkaWordCount 例子分析

    spark  JavaDirectKafkaWordCount 例子分析: 1. KafkaUtils.createDirectStream( jssc, String.class, String.c ...

  2. <转>泛型的内部原理:类型擦除以及类型擦除带来的问题

    参考:java核心技术 一.Java泛型的实现方法:类型擦除 前面已经说了,Java的泛型是伪泛型.为什么说Java的泛型是伪泛型呢?因为,在编译期间,所有的泛型信息都会被擦除掉.正确理解泛型概念的首 ...

  3. java创建对象的几种常用方法

    java几种常见的创建对象的方法: 1.使用new关键字创建对象 2.利用java的反射机制,通过java.lang.Class或者java.lang.reflect.Constructor创建对象 ...

  4. 使用file_get_content系列函数和使用curl系列函数采集图片的性能对比

    由于公司的一个汽车网站的后台的汽车内容都是主要是来自与汽车之家的,编辑的同事们必须天天手动去对着汽车之家来添加汽车,实在是太蛋疼了.于是乎,为了改变这种状况,作为一个开发码农,我的任务就来了...那就 ...

  5. div模拟textarea以实现高度自适应实例页面

    作为多行文本域功能来讲,textarea满足了我们大部分的需求.然而,textarea有一个不足就是不能像普通div标签一样高度可以跟随内容自适应.textarea总是很自信地显摆它的滚动条,高度固执 ...

  6. Linux软件大全

    https://www.linux-apps.com/browse/cat/239/ord/latest/http://www.cnblogs.com/riskyer/p/3262745.htmlht ...

  7. nginx+redis 实现 jsp页面缓存,提升系统吞吐率

    最近在开发的时候,发现之前APP客户端的一部分页面用的是webview交互,这些页面请求很多,打开一套试卷,将会产生100+的请求量,导致系统性能下降.于是考虑在最靠近客户端的Nginx服务器上做Re ...

  8. linux ssh 不用密码自动登录的几种方法

    1. 自动ssh/scp方法== A为本地主机(即用于控制其他主机的机器) ;B为远程主机(即被控制的机器Server), 假如ip为192.168.60.110;A和B的系统都是Linux 在A上运 ...

  9. POJ 1753 Flip Game (DFS + 枚举)

    题目:http://poj.org/problem?id=1753 这个题在開始接触的训练计划的时候做过,当时用的是DFS遍历,其机制就是把每一个棋子翻一遍.然后顺利的过了.所以也就没有深究. 省赛前 ...

  10. ruby on rails出现的问题ActiveModel::ForbiddenAttributesError

    首先分清楚我们在搞rails时.看资料和所使用的环境的版本号是否同样.看的资料是rails3.2,电脑配置的环境是4.0,就会出现这样的安全防范措施的问题. 这类问题大多出如今new或者create两 ...