9.1.1将集合的接口与实现分离
队列(queue)接口:“先进先出”。
队列通常有两种实现方式:
- 使用循环数组;
循环数组比链表更高效。循环数组是一个有界集合,即容量有限。如果程序 中要收集的对象数量没有上限,就最好使用链表来实现。
- 使用链表;
9.1.2 Collection接口
iterator方法用于返回一个实现了Iterator接口的对象。可以使用这个迭代器对象一次访问结合中的元素。
9.1.3迭代器
Iterator
通过反复调用next方法,可以逐个访问集合中的每个元素。 调用next之前调用hasNext。
当调用next时,迭代器就越过下个元素,并返回刚刚越过的那个元素的引用。
remove方法将会删除上次调用next方法时返回的元素。
Iterator< String> it = c.iterator(); it.next();//skip over the first slement it.remove();//now remove it
remove之前没有调用next是不合法的。
编译器简单地将"for each"循环翻译为带有迭代器的循环。
"for each"循环可以与任何实现了Iterable接口的对象一起工作,这个接口只包含了一个抽象方法。
public interface Iterable< E>{ Iterable< E> iterator(); }
Collection接口扩展了Iterable接口。因此,对于标准库中的任何集合都可以使用"for each"循环。
Java SE 8 中可以调用forEachREmaining方法提供一个lambda表达式。将对迭代器的每一个元素调用这个lambda表达式,直到没有元素为止。
iterator.forEachRemaining(element -> do something )
访问顺序:ArrayList迭代器索引从0开始。HashSet按照某种随机的次序出现。
9.1.4泛型实用方法
java.util.Collection< E>
- retainAll(Collection<?> other)
从这个集合中删除所有与other集合中不同的元素。如果由于这个调用改变了集合,则返回true。- < T> toArray(T [] arrayToFill)
返回这个集合的对象数组。如果arrayToFill足够大,就将集合中的元素填入这个数组中,剩余空间填null;
retain 英[rɪˈteɪn] 美[rɪˈteɪn]
- v. 保持; 持有; 保留; 继续拥有; 继续容纳; 聘请(律师等);否则,分配一个新数组,其成员类型与arrayToFill的成员类型相同,其长度等于集合的大小,并填充集合元素。
9.1.5集合框架中的接口
集合框架两个基本接口:Collection和Map。
List是一个有序集合(Ordered collection)。元素会增加到容器的特定位置。可以采用两种方式访问:使用迭代器访问,或使用一个整数索引来访问。后一种方法称为随机访问(random access) ,因为这样可以按任意顺序访问元素。使用迭代器访问时,必须按顺序地访问元素。
ListIterator接口是Iterator的一个子接口。它定义了一个方法用于在迭代器位置前面增加一个元素:
void add(Element)
Set接口等同于Collection接口,不过其方法行为更加有更严谨的定义。集(Set)的add方法不允许增加重复的元素。要适当的定义集的equals方法:只要两个集合包含同样的元素就认为是相等的,而不要求这些元素有相同的顺序。hashCode方法的定义要保证包含相同元素的两个集会得到相同的散列码。