第11章 Java容器类

来源:互联网 发布:java web服务开发 pdf 编辑:程序博客网 时间:2024/05/16 05:03


观察Java容器的简图。有MapListSetQueue四种容器。常用的容器用黑色粗线框标出,点线框表示接口,实线框表示具体的类,空心箭头表示实现接口,实心箭头表示某个类可以生成所指向的对象。

 

Java容器类的用途是“保存对象”,分为CollectionMap两个概念。

Collection:独立元素的序列,包括ListSetQueue

Map:一组成对的“键值对”对象。包括HashMapTreeMap

 

List:以特定顺序保存的一组元素。

两种类型:

ArrayList:长于随机访问元素

LinkedList:长于在List中间进行插入和删除操作,提供了优化的顺序访问,特性集更大。

Stack:栈,“先进后出”,是通过LinkedList实现的。

Java1.0Stack设计欠佳,现在默认的Stack都是使用net.mindview.util而不是原来的java.util.Stack。使用后者需要使用全限定名称)

 

Set:元素不能重复。

HashSet:最快的查询速度。使用散列函数存储。

TreeSet:保持元素处于排序状态。使用红黑树存储。

LinkedHashSet:以插入顺序保存元素。使用链表维护元素的插入顺序,使用散列加快查询。

 

Queue:队列,“先进先出”。

PriorityQueue:优先队列,弹出优先级最高的元素。

 

HashMap:用于快速访问。

TreeMap:保持“键”始终处于排序状态。

LinkedHashMap:保持元素插入的顺序,使用散列加快查询。

 

关于上述具体类的使用不做更多解释,需要使用时自会使用。

 

创建容器实例

应用预定义的泛型

使用尖括号括起来的是参数类型(可以有多个),它指定了这个容器实例可以保存的类型。

上转型

一般创建一个具体类的对象,将其转换为对应的接口,然后在其余的代码中都使用这个接口。

List<Apple> x = new ArrayList<Apple>();

使用接口的目的:当需要改变具体类的实现的时候,只需要在创建的地方修改它。当然,也会有例外的情况,比如当某些类具有额外的实现的时候,像LinkedList具有在List接口中未包含的额外方法。

 

迭代器

迭代器(也是一种设计模式)是一个对象,它的工作是遍历并选择序列中的对象。

迭代器通常被称为轻量级对象:创建的代价小。

JavaIterator只能单向移动。

Iterator用法:

1. 使用方法iterator()为容器返回一个IteratorIterator将准备好返回序列的第一个元素。

2. 使用next()获得序列中的下一个元素。

3. 使用hasNext()检查序列中是否还有元素。

4. 使用remove()将迭代器新近返回的元素删除。

使用该迭代子即可逐一访问Collection中每一个元素。典型的用法如下:

Iterator it = collection.iterator(); // 获得一个迭代子while(it.hasNext()) {Object obj = it.next(); // 得到下一个元素}

ListIterator是一个更加强大的Iterator的子类型,它只能用于各种List类的访问。ListIterator可以双向移动。

ListIterator的用法:

1. listIterator()返回的ListIterator指向开始位置,listIterator(n)返回的ListIterator指向列表索引为n的元素处。

2. add(E e): 将指定的元素插入列表,插入位置为迭代器当前位置之前

3. hasNext():正向遍历,如果列表迭代器后面还有元素,则返回 true,否则返回false

4. hasPrevious():逆向遍历,列表迭代器前面还有元素,则返回 true,否则返回false

5. next():返回列表中ListIterator指向位置后面的元素

6. nextIndex():返回列表中ListIterator所需位置后面元素的索引

7. previous():返回列表中ListIterator指向位置前面的元素

8. previousIndex():返回列表中ListIterator所需位置前面元素的索引

9. remove():从列表中删除next()previous()返回的最后一个元素

10. set(E e)用e替换它访问的最后一个元素。

 

容器类的共性

Collection是描述所有序列容器共性的根接口。

Java遵循C++的方式,使用迭代器而不是Collection来表示容器之间的共性。

实现Collection意味着需要提供Iterator()方法。

Java SE5引入了Iterator接口,该接口包含一个能够产生Iteratoriterator()方法,并且Iterable接口被foreach用来在序列中移动。

 

Foreach

Collection是对Iterable接口的拓展。故所有的Collection对象都可以使用foreach方式,对元素进行方便的遍历。

import java.util.*;public class ForEachCollections {    public static void main(String[] args) {    Collection<String> cs = new LinkedList<String>();    Collections.addAll(cs,        "Take the long way home".split(" "));    for(String s : cs)        System.out.print("‘" + s + "‘ ");    }} 

输出:

Take’ ‘the’ ‘long’ ‘way’ ‘home

 

容器的打印

默认的打印行为(使用容器提供的toString()方法):

Collection打印结果用方括号括住,Map用花括号括住,键值对用等号联系。

看下面的例子:

public class PrintingContainers {    static Collection fill(Collection<String> collection) {        collection.add("rat");        collection.add("cat");        collection.add("dog");        collection.add("dog");        return collection;    }     static Map fill(Map<String, String> map) {        map.put("rat", "Fuzzy");        map.put("cat", "Rags");        map.put("dog", "Bosco");        map.put("dog", "Spot");        return map;    }      public static void main(String[] args) {        print(fill(new ArrayList<String>()));        print(fill(new LinkedList<String>()));        print(fill(new HashSet<String>()));        print(fill(new TreeSet<String>()));        print(fill(new LinkedHashMap<String, String>()));        print(fill(new HashMap<String, String>()));        print(fill(new TreeMap<String, String>()));        print(fill(new LinkedHashMap<String, String>()));    }}

输出:

[rat, cat, dog, dog]

[rat, cat, dog, dog]

[cat, dog, rat]

[cat, dog, rat]

{cat=Rags, dog=Spot, rat=Fuzzy}

{cat=Rags, dog=Spot, rat=Fuzzy}

{rat=Fuzzy, cat=Rags, dog=Spot}


适配器方法惯用法

我们希望在默认前向迭代器的基础上,添加产生反向迭代器的能力。

为了保存原来的前向迭代器功能,我们不选择覆盖,而是添加一个能够产生Iterable对象的方法,该对象可以用于foreach语句。

package cn.collection;import java.util.ArrayList;import java.util.Arrays;import java.util.Collection;import java.util.Iterator;class ReversibleArrayList extends ArrayList {public ReversibleArrayList(Collection c) { super(c); }public Iterable reversed() {return new Iterable(){@Overridepublic Iterator iterator() {return new Iterator(){int current = size() - 1;public boolean hasNext() {return current > -1;}public T next() { return get(current--); }public void remove() {throw new UnsupportedOperationException();}};}};}}public class AdapterMethodIdiom {public static void main(String[] args) {ReversibleArrayList ral =new ReversibleArrayList(Arrays.asList("To be or not to be".split(" ")));for (String s : ral) {System.out.println(s + "  ");};for (String s : ral.reversed()) {System.out.println(s + "  ");};}}

输出:

To be or not to be

be to not or be To

 

0 0
原创粉丝点击