Java集合框架(四)List接口

List是一个有序(插入顺序)的Collection(有时候也叫做序列)。可以包含重复的元素。除了从Collection继承过来的方法外,还包含下面的操作:

  • 位置访问:基于元素位置索引来操作元素。比如getsetaddaddAllremove
  • 搜索:从List中搜索指定的元素,并且返回其位置索引。如indexOflastIndexOf
  • 迭代:扩展Iterator提供利用List序列特性的遍历操作。listIterator方法返回此类迭代器
  • 区间视图:sublist方法提供任意的区间操作。
    Java平台提供了两种通用的List实现:ArrayListLinkedList

集合相关操作

继承自Collection的相关集合操作,基本都符合你期望的样子。如果对这些不熟悉的话,请查看Collection接口
需要提到的是,remove操作将会移除List中第一个出现的指定元素,addaddAll操作总是会将新的元素添加到原有List末尾。因此,下面的方法可以将一个List添加到另一个List后面。
list1.addAll(list2);
上面这种方式将会改变list1,可以通过下面的方式创建一个新的List来包含list1list2
List<Type> list3 = new ArrayList<Type>(list1);
list3.addAll(list2);

位置访问和搜索操作

基本的位置访问操作是getsetaddremovesetremove操作在元素被覆盖和删除之前会先返回旧的元素。别的操作(indexOf和lastIndexOf)将会返回从List中找到的第一个或者最后一个元素的索引。
addAll操作将指定的Collection中的所有元素,按照Collection的迭代顺序插入到指定位置。此操作是Collection中的addAll的基于位置访问版本。
下面是一个小方法用来交换List的两个不同位置的元素。
public static void swap(List<E> list, int i, int j) {
E tmp = list.get(i);
list.set(i, list.get(j));
list.set(j, tmp);
}
当然,这是一个多态算法:它可用来交换任意List的两个元素,而忽略了List的实现类型。下面是另外一个多态算法,使用了前面的swap方法:
public static void shuffle(List<?> list, Random rnd) {
for (int i = list.size(); i > 1; i--) {
swap(list, i - 1, rnd.nextInt(i));
}
}
这个算法包含在Collections中,用来随机打乱List。实际上,如果List的实现类型是LinkedList,此算法的平均运行时间复杂度将会是O(n2)。因为链表基于位置的查找效率不高,为O(n)。在Collections类中,shuffle方法的实现如下:

Collections中的shuffle方法

注意到,shuffle方法会先去判断List是否实现了RandomAccess类型,而RandomAccess实际上是一个空接口(不定义任何方法),基于名字也可以看出,它用来标记子类实现是否为随机访问。在Java类库中,List的实现者ArrayList类实现了此接口,而LinkedList没有实现此接口。因此,从这里也可以看出,由于链表并非随机访问类型,其直接使用基于位置的混淆效率将会低下。针对这种并非随机访问的List,则先生成其数组形式的引用拷贝,对数组进行位置混淆后,再将打乱的数组写回List
注意不同的List实现可能会影响到算法效率时,可以根据判断List是否实现了RandomAccess接口来区分是否可随机访问这种技巧。

迭代器

Listiterator方法返回Iterator类型的迭代器。同时,还提供给一个增强版ListIterator,由listIterator返回。ListIterator可以让你从两个方向遍历List,在迭代过程中修改列表,并且获取当前遍历的位置。
ListIterator继承自Iterator接口,继承的三个方法(hasNextnextremove)和Iterator接口的方法做完全一样的事情。另外还包含了hasPreviousprevious方法,用来从后向前遍历。从方法名可以看出,其是和hasNextnext方法相对应的。
下面是一个标准的从后向前遍历List的方法:

for (ListIterator<Type> it = list.listIterator(list.size()); it.hasPrevious(); ) {
     Type t = it.previous();
      ……
}

注意到listIterator方法有两种形式。无参数的形式返回一个位置位于List开始处的ListIterator,带一个int参数的返回一个位于指定位置索引(index)的ListIterator。这里的位置索引(index)指向被首次next调用将会返回的元素。而index-1指向被首次previous调用的元素。在一个长度为nList中,indexn+1个有效的值:从0到n。
直观地说,光标位置总是位于两个元素之间——一个由调用previous返回的元素和一个由调用next返回的元素。这n+1个有效index对应于n个元素之间的n+1个间隙。下图展示了一个包含四个元素的List可以有五个可能的光标位置:

五个可能的光标位置

区间视图操作

区间视图操作subList(int fromIndex, int toIndex)返回一个原有List的部分List视图,索引包括fromIndex,不包括toIndex
注意:这个子List并非原有List的拷贝,实际上其为同一List,只不过只给你看你想要的那部分。作用在原有List上的操作将会影响到新的子List。如果修改了原有List,可能导致子List紊乱。同样对子List进行添加和删除将会影响到原有List
任何只需要考虑List一部分的范围操作,都可以考虑用subList来进行替代。比如,下面可以用来删除List的一部分元素:

list.subList(fromIndex, toIndex).clear();
List算法

Collections类中的大部分算法都适用于List,下面是这些算法的一个总结:

  • sort——使用归并排序算法来对List进行排序
  • shuffle——随机打乱List中的元素
  • reverse——对List进行逆序操作
  • rotate——以一个给定的距离旋转List中的所有元素
  • swap—— 交换List中指定位置的元素
  • replaceAll——将在List中所有出现的指定值替换为新的值
  • fill ——用指定值覆盖List中所有元素
  • copy——拷贝源List到墓道目的List
  • binarySearch——使用二分查找算法在一个排好序的List中查找给定的元素
  • indexOfSubList——返回List等于给定子List的第一个出现位置索引
    _ lastIndexOfSubList——返回List中等于给定子List的最后一个出现位置索引

以上文章参考:
http://docs.oracle.com/javase/tutorial/collections/interfaces/list.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容

  • Collection ├List │├LinkedList │├ArrayList │└Vector │└Stac...
    AndyZX阅读 869评论 0 1
  • title: java集合框架学习总结 tags:集合框架 categories:总结 date: 2017-03...
    行径行阅读 1,674评论 0 2
  • 3.3 集合 一方面, 面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就要对对象进行存储。另...
    闫子扬阅读 715评论 0 1
  • 昨日黄花不在 今早青草芬香 早安 今天
    LGH嚯嚯嚯阅读 169评论 0 0
  • 文/Nico -01- 小荼说,联系不到他,我真的快疯了。 可是,拉黑了的好友,还有加回来的必要吗? 小荼说,可是...
    Nico尼可阅读 1,842评论 1 7