4.5 List接口
List是一个有序的Collection,所以有时称为序列。List可能包含重复元素。除了从Collection继承的操作之外,List接口还包括以下操作:
· 位置访问:根据列表中的数字位置操作元素,包括get、set、add、addAll和remove等方法。
· 搜索:搜索列表中的指定对象并返回其数字位置。搜索方法包括indexOf和lastIndexOf。
· 迭代:扩展Iterator语义以利用列表的顺序特性。listIterator方法提供此行为。
· 范围视图:sublist方法对列表执行任意范围操作。
Java平台包含两个通用的List实现:ArrayList通常是性能更好的实现;而LinkedList在某些情况下提供更好的性能。
4.5.1 集合操作
List继承自Collection,因此拥有Collection所继承过来的操作。比如remove操作始终从列表中删除指定元素的第一个匹配项;add和addAll操作始终将新元素附加到列表的末尾。因此,以下示例用于将一个列表连接到另一个列表。
list1.addAll(list2);
上面的操作是非破坏性的,因为它产生第三个List,其中包含了附加到第一个列表的第二个列表。
如果是使用Java 8及之后的版本,则可以使用Stream将数据聚合到List中。示例如下:
List<String> list = people.stream() .map(Person::getName) .collect(Collectors.toList());
4.5.2 位置访问和搜索操作
基本的位置访问操作是get、set、add和remove。其中,set和remove操作返回被覆盖或删除的旧值。还有一些操作,比如indexOf和lastIndexOf用于返回列表中指定元素的第一个或最后一个索引。
addAll操作从指定位置开始插入指定Collection的所有元素。元素按指定Collection的迭代器返回的顺序插入。
4.5.3 List的迭代器
List的迭代器操作返回的迭代器以适当的顺序返回列表的元素。List还提供了一个更丰富的迭代器,称为ListIterator,它允许在任一方向遍历列表,在迭代期间修改列表,并获取迭代器的当前位置。
ListIterator从Iterator继承了3个方法:hasNext、next和remove。ListIterator还有一个hasPrevious方法,用于操作引用游标之前的元素。
以下是在List中向后迭代的标准用法:
请注意前面的listIterator的参数。List接口有两种形式的listIterator方法。没有参数的表单返回位于列表开头的ListIterator;带有int参数的表单返回一个位于指定索引处的ListIterator。索引引用初始调用next返回的元素。对previous的初始调用将返回索引为index-1的元素。在长度为n的列表中,索引从0到n(包括0和n),共有n+1个有效值。
直观地说,游标总是在两个元素之间——一个将通过调用previous返回,一个将通过调用next返回。n+1个有效索引值对应于元素之间的n+1个间隙,从第一个元素之前的间隙到最后一个元素之后的间隙,图4-2显示包含4个元素的列表中的5个可能的游标位置。
图4-2 5个可能的游标位置
4.5.4 范围视图操作
范围视图操作subList(int fromIndex,int toIndex)用于返回此列表的部分List视图,其索引范围从fromIndex(包括)到toIndex(不包括),这个半开放范围反映了典型的for循环:
正如术语视图所暗示的那样,返回的List由调用了subList的List进行备份,因此前者中的更改将反映在后者中。
此方法消除了对显式范围操作的需要(对于数组通常存在的排序),任何期望List的操作都可以通过传递subList视图而不是整个List来用作范围操作。例如,以下语句从List中删除一系列元素:
list.subList(fromIndex, toIndex).clear();
可以构造类似的语句以搜索范围中的元素:
int i = list.subList(fromIndex, toIndex).indexOf(o); int j = list.subList(fromIndex, toIndex).lastIndexOf(o);
注意,前面的语句返回subList中找到的元素的索引,而不是list中的索引。
4.5.5 List常用算法
Collections类中的大多数多态算法专门应用于List。拥有所有这些算法可以很容易地操作列表。下面介绍List的常用算法:
· sort:使用合并排序算法对List进行排序,快速、稳定。稳定排序是指不重新进行相同元素的排序。
· shuffle:随机置换List中的元素。
· reverse:反转List中元素的顺序。
· rotate:将List中的所有元素旋转指定的距离。
· swap:交换列表中指定位置的元素。
· replaceAll:将所有出现的一个指定值替换为另一个。
· fill:用指定的值覆盖List中的每个元素。
· copy:将源列表复制到目标列表。
· binarySearch:使用二进制搜索算法搜索有序List中的元素。
· indexOfSubList:返回一个List的第一个子列表的索引,该列表等于另一个。
· lastIndexOfSubList:返回一个List的最后一个子列表的索引,该列表等于另一个。