拼吾爱程序人生

首页 » 其他编程 » Java » java api 接口篇(二)上
SystemPoster - 2008-7-6 16:26:00
 Map接口  

  Map是一个将键映射为值的对象。一个映射不能包含重复键:每个键最多能映射一个值。Map接口如下所示:  
 
public interface Map {
// Basic Operations
Object put(Object key, Object value);
Object get(Object key);
Object remove(Object key);
boolean containsKey(Object key);
boolean containsValue(Object value);
int size();
boolean isEmpty(); 
 
// Bulk Operations
void putAll(Map t);
void clear(); 
 
// Collection Views
public Set keySet();
public Collection values();
public Set entrySet(); 

// Interface for entrySet element
public interface Entry {
Object getKey();
Object getValue();
Object setValue(Object value);
}
} 

  JDK包含两个新的通用Map实现,一个是HashMap, 它将它的项存储在一个哈希表中,是一种最好的实现;另一个是TreeMap, 它将它的项存储在一个红-黑树上,它可保证迭代的顺序。 另外, Hashtable已被改进以实现Map。  
 
   与哈希表的比较  

  如果你使用过Hashtable, 你应该已经熟悉了Map的一般风格(当然Map是一个接口,而Hashtable是一个具体的实现)。 以下是它们的主要区别:

  Map提供Collection视图,作为Enumeration对象的替代直接支持迭代过程。Collection视图 极大地提高了接口的可表达性,正如后续课程将讲到的。  
 
  Map允许你在键、值或键-值对上进行迭代;Hashtable则不提供第三个选项。  
 
  Map提供了在迭代过程中删除项的安全途径;Hashtable则不能。

  进一步讲,Map修补了Hashtable接口上的某些小缺陷。 Hashtable具有一个称作contains的方法,如果Hashtable包含一个给定值,它将返回true。 从它的名字上理解, 你可能期望如果Hashtable包含一个给定的key, 这个方法也会返回一个true ,因为键是一个Hashtable的主要存取机制。 Map接口通过将这个方法重新命名为containsValue,从而消除了引起混乱的来源;同时也改善了接口的一致性: containsValue与containsKey可很好地对应并行。  
 
  基本操作  
 
  基本操作 (put, get, remove, containsKey, containsValue, s  , a和isEmpty) 的功能与它们在Hashtable中的对等物非常相似。下面的简单程序针对参数列表中的词汇生成一个频率表。频率表将每个词和它在参数列表中所出现的次数相映射。  
 
import java.util.*;
public class Freq { private static final Integer ONE = new Integer(1);
public static void main(String args[]) {
Map m = new HashMap();
// Initialize frequency table from command line
for (int i=0; i$#@60; args.length; i  ) {
Integer freq = (Integer) m.get(args);
m.put(args, (freq==null ? ONE :
new Integer(freq.intValue()  1)));
} 
 
System.out.println(m.size() " distinct words detected:");
System.out.println(m);
}
} 
 
  有关这个程序的一个小技巧是put语句的第二个参数。这是一个条件表达式,它的效果是如果这个词汇以前从未被看到过,则将频率设置为one,如果这个词汇已经被看到,则设置为当前值加1 。让我们来运行这个程序:  
 
% java Freq if it is to be it is up to me to delegate
8 distinct words detected:
{to=3, me=1, delegate=1, it=2, is=2, if=1, be=1, up=1} 
 
  假设你更喜欢以字母顺序排列的频率表,那么所有你要做的工作就是将Map的实现类型从HashMap改变为TreeMap. 这四个字母的改变,使该程序从相同的命令行生成了如下输出:  
 
8 distinct words detected:
{be=1, delegate=1, if=1, is=2, it=2, me=1, to=3, up=1} 
 
  这个接口"酷"吗?怎么样?  
 
  正如Set和List接口一样, Map加强了对equals和hashCode方法的要求, 于是, 两个Map对象可做逻辑等同性比较而不必考虑它们的实现类型。 如果它们显示了相等的键-值映射, 则两个Map对象是相等的。  
 
  按惯例, 所有的Map实现可提供构造函数; 该构造函数提取一个Map对象并将这个新的Map初始化, 使之包含特定Map中的所有键-值映射。这个标准Map构造函数是为Collection实现而设计的标准对象集 构造函数的完全对等物。它允许调用者创建一个期望的实现类型的Map ; 该实现类型初始包含另一个Map的所有映射。 而不考虑其它Map的实现类型。例如,假设你有一个命名为m的Map, 则下列一行代码创建了一个新的HashMap, 它初始包含所有与m相同的键-值映射:  
 
  Map copy = new HashMap(m); 
 
  批量操作(Bulk Operations)  
 

clear操作所完成的工作正象其词义上所表达的那样: 它从Map 中删除所有映射。putAll操作是Collection接口中的addAll操作的Map对等物; 它可将一个Map转储至另一个, 除此之外, 它还有一个更微妙的用处。假设一个Map被用来表示属性-值对(attribute-value pairs ) ; putAll操作将与标准Map构造函数一起提供一种用默认值创建属性表的简捷方法。以下是一个可演示此种技术的静态方法:  
 
static Map newAttributeMap(Map defaults, Map overrides) {
Map result = new HashMap(defaults);
result.putAll(overrides);
return result;
} 
 
  Collection视图  
 
  Collection视图 方法允许以三种方式将一个Map作为一个Collection来视图:

  keySet: 包含在Map中的键的Set。  
 
  values: 包含在Map中的值的Collection。 该Collection不是一个Set, 因为多个键可映射相同的值。
 
  entrySet: 包含在Map中的键-值对的Set 。Map接口提供了一个小的被称作Map.Entry的嵌套接口,它是在这个Set中的元素的类型。  
 
   Collection视图提供了在Map上进行迭代的唯一方法。下面的例子给出了在一个Map上迭代键的标准惯用程序:  
 
for (Iterator i=m.keySet().iterator(); i.hasNext(); )
System.out.println(i.next());

  对值进行迭代的惯用程序是类似的。这是迭代键-值对的惯用程序:

for (Iterator i=m.entrySet().iterator(); i.hasNext(); ) {
Map.Entry e = (Map.Entry) i.next();
System.out.println(e.getKey()  ": "  e.getValue());
} 
 
  第一次提交这些惯用程序时,许多人考虑到每次调用一个Collection视图时,Map都必须创建一个新的Collection对象,因而担心其速度慢。请放心:这是不可能的。如果每次一个Map被要求给出一个特定的Collection视图时,没有道理Map不能总是返回相同的对象。这恰恰是所有JDK的Map实现所要作的事。  
 
  用所有三个Collection视图, 调用一个Iterator的remove的操作可从后备Map中删除相关项(假设该Map支持删除)。用entrySet视图, 通过在迭代过程中调用一个Map.Entry的setValue方法 (再一次假设该Map支持值的更改),也可能改变与一个键相关的值。 请注意这是在迭代过程中更改一个Map的唯一安全途径。  
 
  Collection视图支持它的所有形式的元素删除:remove, removeAll, retainAll, 和clear操作, 以及Iterator.remove操作 (然而,这是建立在假设后备Map支持元素删除的基础之上)。  
 
  Collection视图在任何情况下都不支持元素增加。对keySet和values视图这是无意义的,而对entrySet视 
  Collection视图的奇特用法: Map代数  
 
  在应用Collection视图时,批量操作 (containsAll, removeAll和retainAll) 是一个惊人的有力工具。假设你要了解一个Map是否是另一个的子映射(submap),也就是说,第一个Map是否包含第二个的全部键-值映射,请看下面惯用程序的小技巧:  
 
if (m1.entrySet().containsAll(m2.entrySet())) {
..
}

  对照类似行,假设你要了解两个Map对象是否包含所有所有相同键的映射

if (m1.keySet().equals(m2.keySet())) {
...
} 
图来说,这是没必要的,因为后备Map的put和putAll提供了相同的功能。  
 
  假设你具有一个映射,代表一个属性-值对集合;以及两个sets, 表示要求的属性和允许的属性(允许的属性包括要求的属性)。下列代码可判定该属性映射是否符合那些限定条件,如果不符合,则打印详细的出错消息:  
 
boolean valid = true;
Set attributes = attributeMap.keySet();
if(!attributes.containsAll(requiredAttributes)) {
Set missing = new HashSet(requiredAttributes);
missing.removeAll(attributes);
System.out.println("Missing required attributes: " missing);
valid = false;
} 
 
if (!permissibleAttributes.containsAll(attributes)) {
Set illegal = new HashSet(attributes);
illegal.removeAll(permissibleAttributes);
System.out.println("Contains illegal attributes: " illegal);
valid = false;
} 
 
if (valid)
System.out.println("OK");

  假设你想了解由两个Map对象公用的所有键:

Set commonKeys = new HashSet(a.keySet());
commonKeys.retainAll(b.keySet()); 
 
  类似的惯用程序使你可以获得公  1 2 3 4 5 6 7 8 9 10 11 :
  类 自然排序

  Byte 带符号的数字排序

  Character 不带符号的数字排序

  Long 带符号的数字排序

  Integer 带符号的数字排序

  Short 带符号的数字排序

  Double 带符号的数字排序

  Float 带符号的数字排序

  BigInteger 带符号的数字排序

  BigDecimal 带符号的数字排序

  File 依赖系统的按路径名字母顺序排序

  String 按字母顺序排序

  Date 按年代顺序排序

  CollationKey 特定字符集按字母顺序排序 
    
  如果你要为一个其元素没有实现 Comparable的列表排序,Collections.sort(list) 将扔出一个 ClassCastException。类似的,如果你要为一个其元素没有作相互比较的列表进行排序, Collections.sort 将扔出一个 ClassCastException. 能够被相互比较的元素被称作 mutually comparable(可相互比较的)。 虽然不同类型的元素有可能被相互比较,但以上列出的任何JDK类型都不允许在类之间的比较 (inter-class comparison)。  
 
  如果你只是要为可比较的元素的列表进行排序,或为它们创建排序的对象集, 则这就是你实际需要了解的全部有关 Comparable 接口的内容。如果你要实现你自己的 Comparable 类型,则下一节将会引起你的兴趣。

 您可能对 [Java] 的这些文章也感兴趣:

使用Java Swing 创建一个XML编辑器
用 Java 保存位图文件
在JavaScript程序中整合Java函数
Java布局管理器深入讨论
Enterprise bean的开发
推技术聊天室的实现(下)
推技术聊天室的实现(上)
J2EE概述
从商业角度看J2EE与WINDOWS DNA
XML和J2EE的组合技术
简析J2EE应用程序数据库类设计模式
Java中的两个特殊变量this和super
1
查看完整版本: java api 接口篇(二)上
Modify by pin5i DZNT_ExpandPackage 2.1.3295 2007-2009 pin5i.com
 Total Unique Visitors: