除了类集,映射是一个存储关键字和值的管理或者说是关键字/值对的集合。给定一个关键字,可以得到它的值。关键字和值都是对象,每一对关键字/值,叫做一项。关键字必须是唯一的。但值是可以重复的。有些映射可以接受 null 关键字和 null 值,有的则不行。
因为映射接口定义了映射的特征和本质,因此先介绍和映射有关的接口。
接口 | 描述 |
---|---|
Map | 唯一关键字映射到值 |
Map.Entry | 描述映射中的项(关键字/值对)。这是Map的一个内部接口 |
SortedMap | 继承 Map 以便关键字按升序列存储。 |
Map 接口
Map 接口映射唯一关键字到值。 关键字(Key)是以后用于检索值的对象。给定一个关键字和一个值,可以存储这个值到一个 Map 对象中。当这个值被存储以后,就可以使用它的关键字来检索它。当调用的映射中没有项存在时,其中的几种方法会引发一个 NoSuchElementException 异常。 当对象与映射中的元素不兼容时,会引发一个 ClassCastException 异常。如果试图使用映射不允许使用的 null 对象时,则引发一个 NullPointerException 异常。 当试图改变一个不允许修改的映射时,则引发一个 UnsupportedOperationException 异常。
Map 定义的方法
方法 | 描述 |
---|---|
void clear() | 从映射中删除所有的关键字/值对 |
boolean containsKey(Object k) | 如果映射中包含了关键字 K,则返回 true, 否则 返回 false |
boolean containsValue(Object v) | 如果映射中包含了值 v 则返回 true, 否则 返回 false |
Set entrySet() | 返回包含了映射中的项的集合(Set).该集合中的元素类型是 Map.Entry。这个方法为映射提供了一个集合“视图” |
Boolean equals(Object obj) | 如果 obj 是一个Map 并包含相同的项,则返回true,否则返回 false |
Object get(Object k) | 返回与关键字 k 相关联的值 |
int hashCode() | 返回映射的散列值 |
boolean isEmpty() | 如果映射是空的则返回 true ,否则返回 false |
Set keySet() | 返回一个包含调用映射中关键字的集合(Set).这个方法为调用映射的关键字提供了一个集合“视图” |
Object put(Object k,Ojbect v) | 将一个关键字/值对加入调用映射,覆盖原先与该关键字相关联的值。关键字和值分别为 k 和 v |
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 ,它确保了项按关键字升序排序。
方法 | 描述 |
---|---|
Comparator comparator() | 返回排序映射的比较器。如果映射使用的是自然顺序,则返回 null |
Object 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 对象。
Map.Entry接口说明方法:
方法 | 描述 |
---|---|
boolean equals(Object obj) | 如果 obj 是一个关键字和值都与调用对象相等的 Map.Entry ,则返回 true |
Object getKey() | 返回该映射项的关键字 |
Object getValue() | 返回该映射项的值 |
int hashCode() | 返回该映射项的散列值 |
Object setValue(Object v) | 将这个映射项的值赋为 v |
实现 Map 接口的类
有几个类提供了映射接口的实现。可以被作为映射的类总结:
类 | 描述 |
---|---|
AbstractMap | 实现大多数 Map 接口中的方法 |
HashMap | 将 AbstractMap 扩展到使用散列表 |
TreeMap | 将 AbstractMap 扩展到使用树 |
类图关系:
HashMap 类
HashMap 类使用散列表实现 Map 接口。这允许一些基本操作如 get() 和 put() 的运行时间保持恒定,即便对大型集合,也是这样的。
构造函数:
// 构造一个默认散列映射;
HashMap();
// 用 m 的元素初始化散列映射;
HashMap(Map m);
// 将散列映射的容量初始化为 capacity;
HashMap(int capactiy);
// 用它的参数同时初始化散列映射的容量 和填充比。
HashMap(int capactiy, float fillRatio);
HashMap 实现 Map 并继承 AbstractMap。它本身没有添加任何新的方法。
应该注意的是散列映射并不保证它的元素的顺序(由散列函数的特性决定)。因此,元素加入散列映射的顺序并不一定是它们被迭代函数读出的顺序。
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class HashMapDemo {
public static void main(String[] args) {
HashMap<String, Integer> hm = new HashMap<String,Integer>();
hm.put("john",new Integer(96));
hm.put("Tom",new Integer(97));
hm.put("jane",new Integer(98));
hm.put("Hall",new Integer(99));
hm.put("Smith",new Integer(100));
Set set = hm.entrySet();
Iterator <Map.Entry> i = set.iterator();
while(i.hasNext()){
Map.Entry me = i.next();
System.out.print(me.getKey() + ": ");
System.out.println(me.getValue());
}
int balance = hm.get("john").intValue();
hm.put("john", new Integer((int)(balance + 100)));
System.out.println("john's new balance : "+ hm.get("john"));
}
}
// john: 96
// Hall: 99
// jane: 98
// john's new balance : 196
TreeMap 类
treeMap 类使用树实现 Map 接口。 TreeMap 提供了按顺序存储关键字/值对的有效手段,同时允许快速检索。应该注意的是,不像散列映射,树映射保证它的元素按照关键字升序排序。
构造函数:
// 构造一个空树的映射
// 该映射使用其关键字的自然顺序来排序。
TreeMap();
// 构造一个空的基于数的映射,该映射通过使用 Comparator comp 来排序
TreeMap(Comparator comp);
// 用从 m 的映射初始化树映射,该映射使用关键字的自然顺序来排序。
TreeMap(Map m);
// 用 从 sm 的输入来初始化一个树映射,该映射将按照与 sm 相同的顺序来排序。
TreeMap(SortedMap sm);
TreeMap 实现 SortedMap 并且继承 AbstractMap。它本身没有添加任何新的方法。
import java.util.TreeMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class TreeMapDemo {
public static void main(String[] args) {
TreeMap<String, Double> tm = new TreeMap<String, Double>();
tm.put("E",new Double("3444.44"));
tm.put("A",new Double("3444.34"));
tm.put("B",new Double("124.22"));
tm.put("C",new Double("1338.00"));
tm.put("F",new Double("94.22"));
tm.put("D",new Double("-15.08"));
Set set = tm.keySet();
Iterator<String> i = set.iterator();
while(i.hasNext()){
String key = i.next();
System.out.println(key + ": " + tm.get(key).doubleValue());
}
double balance = tm.get("D").doubleValue();
tm.put("D", new Double(balance + 1000));
System.out.println("D's new balance: " + tm.get("D"));
}
}
// A: 3444.34
// B: 124.22
// C: 1338.0
// D: -15.08
// E: 3444.44
// F: 94.22
// D's new balance: 984.92
注意: TreeMap 对关键字进行了 排序。 在使用 Iterator 访问关键字的集合时可以按关键字的自然顺序访问。
比较器(Comparator)
TreeSet 和 TreeMap 都按顺序存储元素, 可以使用比较器精确定义采用何种规则进行排序。通常在默认的情况下,这些类通过使用被 Java 成为 ”自然顺序“ 的顺序存储他们的元素 (A 在 B 的前面),而这种顺序通常也是用户所需要的。如果需要用不同的方法对元素进行排序,可以在构造集合或映射时,指定一个 Comparator 对象。这样做为用户提供了一种精确控制元素将其存储到排序类集合映射中的能力。
Comparator 接口定义了两个方法: compare() 和 equals() 。compare() 方法比较了两个元素,确定它们的顺序:
int compare(Object obj1, Object obj2);
obj1 和 obj2 是被比较的两个对象。当两个对象相等时,该方法返回 0 。当 obj1 大于 obj2 时,返回一个正值;否则,返回一个负值。如果用于比较的对象类型不兼容,则该方法引发一个ClassCastException 异常。通过实现 compare() 可以改变对象排序的方式。例如:通过创建一个比较器,可以实现元素按逆向排序。
这里给出的 equals 方法,可测试两个比较器是否相等:
boolean equals(Object obj);
obj 是被用来进行相等测试的对象。如果 obj 和调用对象都是comparator 的对象并且使用相同的排序,则该方法返回true;否则返回 false.重载 equals() 方法是没有必要的,大多数简单的比较函数都不这样做。
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
public class ComparatorDemo implements Comparator {
public int compare(Object a,Object b){
String aStr,bStr;
aStr = (String) a;
bStr = (String) b;
return bStr.compareTo(aStr);
}
}
public class ArrayListDemo {
public static void main(String[] args) {
TreeSet ts = new TreeSet(new ComparatorDemo());
ts.add("C");
ts.add("A");
ts.add("B");
ts.add("E");
ts.add("F");
ts.add("D");
Iterator i = ts.iterator();
while(i.hasNext()){
Object element = i.next();
System.out.print(element +" ");
}
}
}
// F E D C B A