List接口List是一个有序的Collection(有时称为序列),列表可能包含重复元素,除了从Collection继承的操作之外,List接口还包括以下操作:位置访问 — 根据列表中的数字位置操纵元素,这包括get、set、add、addAll和remove等方法。搜索 — 搜索列表中的指定对象并返回其数字位置,搜索方法包括indexOf和lastIndexOf。迭代 — 扩展Iterator语义以利用列表的顺序性,listIterator方法提供此行为。范围视图 — sublist方法对列表执行任意范围操作。Java平台包含两个通用的List实现,ArrayList,通常是性能更好的实现,而LinkedList在某些情况下提供更好的性能。集合操作假设你已经熟悉它们,那么从Collection继承的操作都可以完成你期望它们做的事情,如果你不熟悉Collection,现在是阅读Collection接口部分的好时机,remove操作始终从列表中删除指定元素的第一个匹配项,add和addAll操作始终将新元素附加到列表的末尾,因此,以下语法将一个列表连接到另一个列表。list1.addAll(list2);这是这个语法的非破坏性形式,它产生第三个List,其中包含附加到第一个列表的第二个列表。List<Type> list3 = new ArrayList<Type>(list1);list3.addAll(list2);请注意,此语法在其非破坏性形式中利用了ArrayList的标准转换构造函数。这是一个将一些名称聚合到List中的示例(JDK 8及更高版本):List<String> list = people.stream().map(Person::getName).collect(Collectors.toList());与Set接口一样,List强化了对equals和hashCode方法的需求,因此可以比较两个List对象的逻辑相等性,而不考虑它们的实现类,如果两个List对象包含相同顺序的相同元素,则它们是相等的。位置访问和搜索操作基础的位置访问操作是get、set、add和remove(set和remove操作返回被覆盖或删除的旧值),其他操作(indexOf和lastIndexOf)返回列表中指定元素的第一个或最后一个索引。addAll操作从指定位置开始插入指定Collection的所有元素,元素按指定Collection的迭代器返回的顺序插入,此调用是Collection的addAll操作的位置访问模拟。这是在List中交换两个索引值的一个小方法。public static <E> void swap(List<E> a, int i, int j) { E tmp = a.get(i); a.set(i, a.get(j)); a.set(j, tmp);}当然,有一个很大的区别,这是一个多态算法:它交换任何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));}此算法包含在Java平台的Collections类中,使用指定的随机源随机置换指定的列表,这有点微妙:它从底部向上运行列表,反复将随机选择的元素交换到当前位置。不像大多数天真的洗牌尝试,这是公平的(假设一个公平的随机源,所有排列都有相同的可能性)和快速(需要完全list.size()-1交换),以下程序使用此算法以随机顺序打印其参数列表中的单词。import java.util.;public class Shuffle { public static void main(String[] args) { List<String> list = new ArrayList<String>(); for (String a : args) list.add(a); Collections.shuffle(list, new Random()); System.out.println(list); }}事实上,这个程序可以更短、更快,Arrays类有一个名为asList的静态工厂方法,它允许将数组视为List,此方法不会复制数组,List中的更改会写入数组,反之亦然。生成的List不是通用List实现,因为它没有实现(可选)add和remove操作:数组不可调整大小。利用Arrays.asList并调用shuffle的库版本(使用默认的随机源),你将得到以下微小程序,其行为与前一个程序相同。import java.util.;public class Shuffle { public static void main(String[] args) { List<String> list = Arrays.asList(args); Collections.shuffle(list); System.out.println(list); }}迭代器正如你所期望的那样,List的iterator操作返回的Iterator以适当的顺序返回列表的元素,List还提供了一个更丰富的迭代器,称为ListIterator,它允许你在任一方向遍历列表、在迭代期间修改列表、并获取迭代器的当前位置。ListIterator从Iterator继承的三个方法(hasNext、next和remove)在两个接口中完全相同,hasPrevious和previous操作和hasNext和next的很相似,前一个操作引用(隐式)游标之前的元素,而后者引用游标之后的元素,previous操作向后移动光标,而next向前移动光标。这是在列表中向后迭代的标准语法。for (ListIterator<Type> it = list.listIterator(list.size()); it.hasPrevious(); ) { Type t = it.previous(); …}请注意前面的语法中listIterator的参数,List接口有两种形式的listIterator方法,不带参数的形式返回位于列表开头的ListIterator,带有int参数的形式返回一个位于指定索引处的ListIterator。索引引用初始调用next返回的元素,对previous的初始调用将返回索引为index-1的元素,在长度为n的列表中,index有n+1个有效值,从0到n(包括n)。直观地说,游标总是在两个元素之间 — 一个将通过调用previous返回,一个将通过调用next返回。n+1个有效索引值对应于元素之间的n+1个间隙,从第一个元素之前的间隙到最后一个元素之后的间隙,下图显示了包含四个元素的列表中的五个可能的游标位置。