最早的版本java只是为最常用的数据结构提供一组类: Vector、Stack、Hashtable、BitSet与Enumeration接口。其中Enumeration接口提供一种用于访问任意容器中各个元素的抽象机制。后续的版本中设计者对整个体系进行优化,希望将传统的类融入新的框架中,并使得整体类库规模小利于学习。
集合接口与实现分离 与现代数据结构类库的常见做法一样,java集合类库也将接口与实现分离。下面以队列为例: 队列接口指出可以在队列的尾部添加元素,在头部删除元素。并且可以查找队列中元素个数。
队列接口的最简形式大概如下: public interface Queue<E> //a simplified form of the interface in the standard library { void add(E element); E remove(); int size(); } 队列的实现方法有循环数组和链表两种 下面是逻辑上的模仿,不与库中的实际代码完全相同 public class CircularArrayQueue<E> implements Queue<E> { private int head; private int tail; CircularArrayQueue(int capacity){...} public void add(E element){...} public E remove(){...} public int size(){...} private E[] elements; } public class LinkedListQueue<E> implements Queue<E> { private Link head; private Link tail; LinkedListQueue(){...} public void add(E element){...} public E remove(){...} public int size(){...} }此时的构造就变成了:
Queue <Customer> expressLane = new CircularArrayQueue<>(100); expressLane.add(new Customer("Harry"));————————————————————————
Collection接口 在java类库中,集合类的基本接口是Collection接口,这个接口有两个基本方法:
public interface Collection<E> { boolean add(E element ); Iterator<E> iterator(); ... }add用于向集合中添加元素。 iterator方法用于返回一个实现Iterator接口的对象。可以使用这个迭代器对象一次访问集合中的元素。
————————————————————————
迭代器
Iterator接口包含四个方法:
public interface Interator<E> { E next(); boolean hasNext(); void remove(); default void forEachRemaining(Consumer <? super E>action) }通过反复调用next方法可以遍历集合中所有元素。但是到了集合末尾的话,next方法将抛出一个NoSuchElementException。因此,需要在调用next之前调用hasNext方法。如果迭代器还有多个可以访问的元素则返回true。
请求一个迭代器后遍历集合:
Collection<String> c= ...; Iterator<String> iter = c.iterator(); while (iter.hasNext()) { String element = iter.next(); //do something with elements }用for each循环的相同操作:
for (String element:c) { //do something with element }for-each循环可以处理任何实现了Iterable接口的对象,这个接口只包含一个抽象方法:
public interface Iterable<E> { Iterator <E> iterator(); ... }Collection接口扩展了Iterable接口。因此对标准类库中所有的集合都能应用 for-each循环。
也可以不用循环,使用forEachRemaining方法并提供一个lambda表达式。将对所有元素进行表达式中的处理
iterator.forEachRemaining(element -> //do something with element )这种操作的顺序决定于集合类型:ArrayList,从0开始一个个迭代。Hashset中的元素则会按照一种基本上随机的顺序获得。
———————————————————————————— 集合的next理解 有一种思路是讲Iterator.next与InputStream.read看做等效的。从数据流中读取一个字符,就会自动的"消耗掉"这个字节。下一次调用read将会消耗并返回输入的下一个字节。用同样的方式,反复的调用next就可以读取集合中的所有元素。
next将会返回此时越过的元素
Iterator接口的remov方法将会删除上次调用next方法时返回的元素。 如下,删除一个字符串集合中第一个元素: Iterator <String> it = c.iterator(); it.next();//skip over the first element it.remove();//now remove it next()、remove()方法之间存在依赖性。如果在一个remove调用前没有调用next是不合法的。将会抛出一个IllegalStateException异常如果想删除两个相邻的元素,不能直接这样调用:
it.remove(); it.remove();实际上,必须用next先越过要删除的元素:
it.remove(); it.next(); it.remove();由于Collection和Iterator都是泛型接口,这意味着可以编写处理任何集合类型的实用方法。例如,下面是一个检测任意集合是否包含指定元素的泛型方法:
public static <E> boolean contains(Collection<E> c,Object object) { for(E element: c) if(element.equals(obj)) return true; return false; }事实上,Collection接口声明了很多有用的方法,但是所有的类必须实现这些方法,这很实用但是也很累人。java类库中提供了一个实现Collection的类AbstractCollection,它保持基础方法size和Iterator仍为抽象方法,但是对例行的实用方法进行了实现,
p372中提供了这些方法的大概功能需求。 具体的实现集合还是看书吧2333.