第11章 Java容器类

第11章 Java容器类_第1张图片

观察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 x = new ArrayList();

使用接口的目的:当需要改变具体类的实现的时候,只需要在创建的地方修改它。当然,也会有例外的情况,比如当某些类具有额外的实现的时候,像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 cs = new LinkedList();
    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 collection) {
        collection.add("rat");
        collection.add("cat");
        collection.add("dog");
        collection.add("dog");
        return collection;
    }
 
    static Map fill(Map 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()));
        print(fill(new LinkedList()));
        print(fill(new HashSet()));
        print(fill(new TreeSet()));
        print(fill(new LinkedHashMap()));
        print(fill(new HashMap()));
        print(fill(new TreeMap()));
        print(fill(new LinkedHashMap()));
    }
}

输出:

[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(){
			@Override
			public 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

 

你可能感兴趣的:(Think,in,Java学习小结,ThinKing,in,Java,学习小记,Java,容器类,迭代器)