JAVA集合接口

集合接口,JAVA集合类库将接口与实现分离。下面以队列(queue)是如何分离的。

队列接口指出可以在队列的尾部添加元素,在队列的头部删除元素,并且可以查找队列中元素的个数,队列的特点是“先进先出”。一个队列接口的最小形式类似下面这样:

interface Queue<E> 
{
    void add(E element);
    E remove();
    int size();
}

 

上面的接口没有说明队列是怎么实现的,队列的实现一般有两种方式(1)使用循环数组,在Java SE 6中可以通过使用ArrayDeque实现 (2)使用链表,可以使用LinkedList实现。

当在程序中使用队列时,一旦构建了集合就不需要知道就行使用了哪种实现,因此,只有在构建集合对象时,使用具体的类才有意义。可以使用接口类型存放集合的引用。

Queue<Customer> expressLane = new CircularArrayQueue<Customer>(100);
expressLane.add(new Customer("Harry"));

 利用这种方式,一旦改变了想法,可以轻松的使用另外一种实现,只需要对调用构造器的地方作出修改,如改为LinkedListQueue实现

Queue<Customer> expressLane = new LinkedListQueue<Customer>();
expressLane.add(new Customer("Harry"));

为什么选择这种实现而不选择另外一种实现呢?循环数组要比链表更高效,然而,循环数组是一个有界集合,即容量有限,如果程序中要收集的对象数量没有上限,就最好用链表来实现。

另外在API文档中,还会发现一组名字以Abstract开头的类,例如AbstractQueue,这些类市委类库实现这而设计的,如果实现自己的队列类,扩展AbstractQueue要比扩展Queue接口更方便。

 

Java类库中的集合接口和迭代接口

在Java类库中,集合类的基本接口是Collection接口,这个接口有两个基本方法。即

public interface Collection<E>
{
    boolean add(E element);
    Iterator<E> iterator();
    ……
}

 add方法用于向集合中添加元素,如果添加元素确实改变了集合就返回true,如果集合没有发生变化就返回false,例如在一个set中不允许有重复的对象,如果向set中再add一个已经存在的对象,那么这个请求就没有实效。

 iterator方法用于返回一个实现了Iterator接口的对象,可以使用这个迭代器对象依次访问结合中的元素。

迭代器Iterator

Iterator接口包含3个方法:

public interface Iterator<E>
{
    E next();
    boolean hasNext();
    void remove();
}

 

通过反复调用next()  方法,可以逐个访问集合中的每个元素,但是如果到达了集合的末尾,next方法将抛出一个NoSuchElementException异常。因此需要在next之前调用hasnext进行判断。下面实现访问集合中的所有元素:

Collection<String> c = . . .;
Iterator<String> iter = c.iterator();
while (iter.hasNext())
{
    String element = iter.next();
    do something with element
}

 

从Java SE5 开始,可以使用for each 循环

for (String element :c)
{
    do something with element
}

 

编译器简单的将“for each”循环翻译为带有迭代器的循环。“for each”循环可以与任何实现了Iterable接口的对象一起工作,这个接口只包含一个方法:

public interface Iterable<E>
{
    Iterator<E> iterator();
}

 Collection接口扩展了Iterable接口,因此,对于标准类库中的任何集合都可以使用“for each”循环。

元素访问的顺序取决于集合类型,对于Arraylist进行迭代,从索引0开始,对于HashSet中的元素,按照某种随机的次序出现。

删除元素

Iterable接口的remove方法将会删除上次调用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();  //error!  之前必须 添加一个 it.next();

 泛型实用方法

由于Colletion与Iterator都是泛型接口,可以编写操作任何集合类型的使用方法,如下:下面检测任意集合是否包含指定元素的泛型方法:

public static <E> boolean contains(Collection<E> c, Object obj)
{
for (E element : c)
if (element.equals(obj))
return true;
return false;
}

 

Collection接口中声明的类似的有用的方法还包括如下一些,所有实现类都必须提供这些方法的实现。

int size()
boolean isEmpty()
boolean contains(Object obj)
boolean containsAll(Collection<?> c)
boolean equals(Object other)
boolean addAll(Collection<? extends E> from)
boolean remove(Object obj)
boolean removeAll(Collection<?> c)
void clear()
boolean retainAll(Collection<?> c)
Object[] toArray()
<T> T[] toArray(T[] arrayToFill)

 为了方便的实现接口中以上的各类方法,Java类库提供了一个类AbstractCollection

 

你可能感兴趣的:(java,C++,c,C#)