映射表

来源:互联网 发布:centos 桥接模式 编辑:程序博客网 时间:2024/06/05 12:40

集是一个集合,它可以快速地寻找现有的元素,但是要查看元素,就需要查看的元素的精确副本。这不是一种非常通用的查找方式。通常,我们知道某些键的信息,并想要查找与之相对应的元素。映射表(map)数据结构就是为此设计的。映射表用来存放键值对。如果提供了键就能查找到相应的值。例如,有一张关于员工信息的记录表,键为员工ID,值为Employee对象。

Java 类库为映射表提供了两种通用的实现:HashMap和TreeMap。这两个类都实现了Map接口。

散列映射表对键进行散列,树映射表用键的整体顺序对元素进行排序,并将其组织成为搜索树。散列或者比较函数只能用于键。与键关联的值不能用来散列或者比较。

应该选择散列映射表呢?还是树映射表呢?与集一样,散列稍微地快一些,如果不需要按照排列顺序访问,就最好使用散列。

下列代码为存储的员工信息建立了一个散列映射表:

[java] view plain copy
  1. Map<String, Employee> staff = new HashMap<String, Employee>();  
  2. Employee Harry = new Employee("Harry Hacker");  
  3. staff.put("987-98-9996");  
每当往映射表中添加对象时,必须同时提供一个键。在这里键是一个字符串,对应的值是一个Employee对象。

想要检索一个对象,必须提供一个键。

[java] view plain copy
  1. String s = "987-98-9996";  
  2. e = staff.get(s);  

如果在映射表中没有给定键对应的信息,那么get将会返回一个null。

键必须是唯一的。不能对同一个键存放两个值。如果对同一个键两次调用put方法,第二个值就会取代第一个值。实际上,put将返回用这个键参数存储的上一个值。

remove方法用于从映射表中删除给定键对应的元素。size方法用于返回映射表中的元素数。

集合框架并没有将映射表本身视为一个集合(其他的数据结构框架则将映射表视为对(pairs)或者视为用键作为索引值的集合)。然而,可以获得映射表的视图,这是一组实现Collection接口的对象,或者它的子接口视图。

有三个视图,他们分别是:键集、值集合(不是集)和键/值对集。键与键值对形成了一个集,这是因为在映射表中一个键只能有一个副本。下列的方法将返回这3个视图(条目集的元素是静态内部类Map.Entry的对象)。

[java] view plain copy
  1. Set<K> keySet()  
  2. Collection<K> values ()  
  3. Set <Map.Entry<K,V>> entrySet()  
注意KeySet既不是HashSet,也不是TreeSet,而是实现了Set接口的某个其他类的对象。Set接口扩展了collection接口,因此可以与使用任何集合一样使用KeySet。

例如可以枚举映射表中的所有键:

[java] view plain copy
  1. Set<String> keys = map.keySet();  
  2. for(String key :keys)  
  3. {  
  4.    do something with the keys  
  5. }  

提示:如果想要同时查看键与值,就可以枚举各个条目(entires)查看,以避免对值进行查找。 可以使用下面这段代码框架:

[java] view plain copy
  1. for(Map.Entry<String,Employee> entry:staff.entrySet())  
  2. {  
  3.       String key = entry.getKey();  
  4.       Employee value = entry.getValue();  
  5.       do something with the key,value   
  6. }  
如果调用迭代器的remove方法,实际上就从映射表中删除了键以及对应的值。但是不能将元素添加到键集的视图中。如果只添加键不添加值是毫无意义的,如果试图调用add方法,会抛出一个UnsupportedOperationException异常。条目集视图也有同样的限制,不过从概念上讲,添加新的键值对是有意义的。

下面的代码显示了映射表的整个操作过程。首先将键值对添加到映射表中,然后从映射表中删除一个键,同时与之对应的值也被删除了。接下来修改与某一个键对应的值,并调用get方法查看这个值。最后对条目集进行迭代。

[java] view plain copy
  1. import java.util.*;  
  2.   
  3. /** 
  4.  * This program demonstrates the use of a map with key type String and value type Employee. 
  5.  * @version 1.10 2004-08-02 
  6.  * @author Cay Horstmann 
  7.  */  
  8. public class MapTest  
  9. {  
  10.    public static void main(String[] args)  
  11.    {  
  12.       Map<String, Employee> staff = new HashMap<String, Employee>();  
  13.       staff.put("144-25-5464"new Employee("Amy Lee"));  
  14.       staff.put("567-24-2546"new Employee("Harry Hacker"));  
  15.       staff.put("157-62-7935"new Employee("Gary Cooper"));  
  16.       staff.put("456-62-5527"new Employee("Francesca Cruz"));  
  17.   
  18.       // print all entries  
  19.   
  20.       System.out.println(staff);  
  21.   
  22.       // remove an entry  
  23.   
  24.       staff.remove("567-24-2546");  
  25.   
  26.       // replace an entry  
  27.   
  28.       staff.put("456-62-5527"new Employee("Francesca Miller"));  
  29.   
  30.       // look up a value  
  31.   
  32.       System.out.println(staff.get("157-62-7935"));  
  33.   
  34.       // iterate through all entries  
  35.   
  36.       for (Map.Entry<String, Employee> entry : staff.entrySet())  
  37.       {  
  38.          String key = entry.getKey();  
  39.          Employee value = entry.getValue();  
  40.          System.out.println("key=" + key + ", value=" + value);  
  41.       }  
  42.    }  
  43. }  
  44.   
  45. /** 
  46.  * A minimalist employee class for testing purposes. 
  47.  */  
  48. class Employee  
  49. {  
  50.    /** 
  51.     * Constructs an employee with $0 salary. 
  52.     * @param n the employee name 
  53.     */  
  54.    public Employee(String n)  
  55.    {  
  56.       name = n;  
  57.       salary = 0;  
  58.    }  
  59.   
  60.    public String toString()  
  61.    {  
  62.       return "[name=" + name + ", salary=" + salary + "]";  
  63.    }  
  64.   
  65.    private String name;  
  66.    private double salary;  
  67. }  

原创粉丝点击