15.5 将用户定义的类于Collection中 为了简单,前面的例子在类集中内置的对象,如String或Integer.当然,类集并没有被限制为只能存储内置的对象。完全相反的是,类集的能力是它能存储任何类型的对象,包括你所创建的类的对象。例如,考虑下面的例子,在这个例子中使用LinkedList存储信箱地址。
// A simple mailing list example.
import java.util.*;
class Address {
private String name;
private String street;
private String city;
private String state;
private String code;
Address(String n, String s, String c,
String st, String cd) {
name = n;
street = s;
city = c;
state = st;
code = cd;
}
public String toString() {
return name + "\n" + street + "\n" +
city + " " + state + " " + code;
}
}
class MailList {
public static void main(String args[]) {
LinkedList ml = new LinkedList();
// add elements to the linked list
ml.add(new Address("J.W. West", "11 Oak Ave",
"Urbana", "IL", "61801"));
ml.add(new Address("Ralph Baker", "1142 Maple Lane",
"Mahomet", "IL", "61853"));
ml.add(new Address("Tom Carlton", "867 Elm St",
"Champaign", "IL", "61820"));
Iterator itr = ml.iterator();
while(itr.hasNext()) {
Object element = itr.next();
System.out.println(element + "\n");
}
System.out.println();
}
}
程序的输出如下所示:
J.W. West
11 Oak Ave
Urbana IL 61801
Ralph Baker
1142 Maple Lane
Mahomet IL 61853
Tom Carlton
867 Elm St
Champaign IL 61820
除了在类集中存储用户定义的类之外,关于上面程序的另一个重要的,值得注意的事情是它是非常短的。当考虑用50行代码建立一个能够实现存储,检索,以及处理信箱地址的链表时,类集框架的能力就变得显而易见了。正如大多数读者知道的那样,如果所有这些功能都必须用人工编写代码的话,程序将比现在的长好几倍。类集对许多不同的编程问题提供了现成的解决方案。每当情况出现时,就可以用它们。
15.6 处理映射 正如在本章开始时所谈到的,除了类集, 2还在java.util中增加了映射。映射(map)是一个存储关键字和值的关联或者说是关键字/值对的对象。给定一个关键字,可以得到它的值。关键字和值都是对象。关键字必须是唯一的。但值是可以被复制的。有些映射可以接收null关键字和null值。而有的则不行。
15.6.1 映射接口 因为映射接口定义了映射的特征和本质,因此关于映射的讨论从这里开始。下面的接口支持映射:
接口描述 Map 映射唯一关键字给值
Map.Entry 描述映射中的元素(关键字/值对)。这是Map的一个内部类
SortedMap 扩展Map以便关键字按升序保持
下面对每个接口依次进行讨论。
Map 接口 Map接口映射唯一关键字到值。关键字(key)是以后用于检索值的对象。给定一个关键字和一个值,可以存储这个值到一个Map对象中。当这个值被存储以后,就可以使用它的关键字来检索它。由Map说明的方法总结在表15-6中。当调用的映射中没有项存在时,其中的几种方法会引发一个NoSuchElementException异常。而当对象与映射中的元素不兼容时,引发一个ClassCastException异常。如果试图使用映射不允许使用的null对象时,则引发一个NullPointerException异常。当试图改变一个不允许修改的映射时,则引发一个UnsupportedOperationException异常。
表15-6 由Map 定义的方法
方法描述 void clear( ) 从调用映射中删除所有的关键字/值对boolean containsKey(Object k) 如果调用映射中包含了作为关键字的k,则返回true;否则返回false
boolean containsValue(Object v) 如果映射中包含了作为值的v,则返回true;否则返回falseSet entrySet( ) 返回包含了映射中的项的集合(Set)。该集合包含了类型Map.Entry的对象。这个方法为调用映射提供了一个集合“视图”Boolean equals(Object obj) 如果obj是一个Map并包含相同的输入,则返回true;否则返回falseObject get(Object k) 返回与关键字k相关联的值int hashCode( ) 返回调用映射的散列码boolean isEmpty( ) 如果调用映射是空的,则返回true;否则返回falseSet keySet( ) 返回一个包含调用映射中关键字的集合(Set)。这个方法为调用映射的关键字提供了一个集合“视图”Object put(Object k, Object v) 将一个输入加入调用映射,覆盖原先与该关键字相关联的值。关键字和值分别为k和v.如果关键字已经不存在了,则返回null;否则,返回原先与关键字相关联的值void putAll(Map m) 将所有来自m的输入加入调用映射Object remove(Object k) 删除关键字等于k的输入
续表
方法描述 int size( ) 返回映射中关键字/值对的个数Collection values( ) 返回一个包含了映射中的值的类集。这个方法为映射中的值提供了一个类集“视图”映射循环使用两个基本操作:get( )和put( )。使用put( )方法可以将一个指定了关键字和值的值加入映射。为了得到值,可以通过将关键字作为参数来调用get( )方法。调用返回该值。
正如前面谈到的,映射不是类集,但可以获得映射的类集“视图”。为了实现这种功能,可以使用entrySet( )方法,它返回一个包含了映射中元素的集合(Set)。为了得到关键字的类集“视图”,可以使用keySet( )方法。为了得到值的类集“视图”,可以使用values( )方法。类集“视图”是将映射集成到类集框架内的手段。
SortedMap 接口 SortedMap接口扩展了Map,它确保了各项按关键字升序排序。由SortedMap说明的方法总结在表15-7中。当调用映射中没有的项时,其中的几种方法引发一个NoSuchElementException异常。当对象与映射中的元素不兼容时,则引发一个ClassCastException异常。当试图使用映射不允许使用的null对象时,则引发一个NullPointerException异常。表15-7 由SortedMap 定义的方法
方法描述 Comparator comparator( ) 返回调用排序映射的比较函数。如果调用映射使用的是自然顺序的话,则返回nullObject firstKey( ) 返回调用映射的第一个关键字SortedMap headMap(Object end) 返回一个排序映射,该映射包含了那些关键字小于end的映射输入Object lastKey( ) 返回调用映射的最后一个关键字SortedMap subMap(Object start, Object end) 返回一个映射,该映射包含了那些关键字大于等于start同时小于end的输入SortedMap tailMap(Object start) 返回一个映射,该映射包含了那些关键字大于等于start的输入排序映射允许对子映射(换句话说,就是映射的子集)进行高效的处理。使用headMap( ),tailMap( )或subMap( )方法可以获得子映射。调用firstKey( )方法可以获得集合的第一个关键字。而调用lastKey( )方法可以获得集合的最后一个关键字。
Map.Entry 接口 Map.Entry接口使得可以操作映射的输入。回想由Map接口说明的entrySet( )方法,调用该方法返回一个包含映射输入的集合(Set)。这些集合元素的每一个都是一个Map.Entry对象。表15-8总结了由该接口说明的方法。
表15-8 由Map.Entry 定义的方法
方法描述 boolean equals(Object obj) 如果obj是一个关键字和值都与调用对象相等的Map.Entry,则返回trueObject getKey( ) 返回该映射项的关键字Object getValue( ) 返回该映射项的值int hashCode( ) 返回该映射项的散列值Object setValue(Object v) 将这个映射输入的值赋给v.如果v不是映射的正确类型,则引发一个ClassCastException 异常。如果v 存在问题, 则引发一个IllegalArgumentException异常。如果v是null而映射又不允许null关键字,则引发一个NullPointerException异常。如果映射不能被改变,则引发一个UnsupportedOperationException异常。
15.6.2 映射类 有几个类提供了映射接口的实现。可以被用做映射的类总结如下:
类描述 AbstractMap 实现大多数的Map接口
HashMap 将AbstractMap扩展到使用散列表
TreeMap 将AbstractMap扩展到使用树
WeakHashMap 将AbstractMap扩展到使用弱关键字散列表
注意AbstractMap对三个具体的映射实现来说,是一个超类。WeakHashMap实现一个使用“弱关键字”的映射,它允许映射中的元素,当该映射的关键字不再被使用时
【责编:admin】
--------------------next---------------------