Java中Map接口及实现
来源:互联网 发布:淘宝时光机 编辑:程序博客网 时间:2024/04/29 10:07
Map是从键到值的映射,键不允许重复,每个键最多能映射一个值.
public interface Map<K,V> {
// Query Operations
int size();
boolean isEmpty();
boolean containsKey(Object key);
boolean containsValue(Object value);
V get(Object key);
// Modification Operations
V put(K key, V value);
V remove(Object key);
// Bulk Operations
void putAll(Map<? extends K, ? extends V> t);
void clear();
// Views
Set<K> keySet();
Collection<V> values();
Set<Map.Entry<K, V>> entrySet();
interface Entry<K,V> {
K getKey();
V getValue();
V setValue(V value);
boolean equals(Object o);
int hashCode();
}
// Comparison and hashing
boolean equals(Object o);
int hashCode();
}
Entry接口及实现
Map是键到值的映射,Java集合框架在实现上采用一个个Map.Entry来封装每一个键值对,这样,Map中的元素就变成了Map.Entry的集了,这似乎预示着Map和Set有某种相通性.实际上,在HashSet实现中,HashSet的实现中,HashSet的元素存储在底层就是借助于HashMap来进行的(在部分情况下使用了LinkedHashMap).
//AbstractMap中的SimpleEntry类
static class SimpleEntry<K,V> implements Entry<K,V> {
K key;
V value;
public SimpleEntry(K key, V value) {
this.key = key;
this.value = value;
}
public SimpleEntry(Entry<K,V> e) {
this.key = e.getKey();
this.value = e.getValue();
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
public V setValue(V value) {
V oldValue = this.value;
this.value = value;
return oldValue;
}
public boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry e = (Map.Entry)o;
return eq(key, e.getKey()) && eq(value, e.getValue());
}
public int hashCode() {
return ((key == null) ? 0 : key.hashCode()) ^
((value == null) ? 0 : value.hashCode());
}
public String toString() {
return key + "=" + value;
}
private static boolean eq(Object o1, Object o2) {
return (o1 == null ? o2 == null : o1.equals(o2));
}
}
2.Map的实现
在java 2集合框架中的Map接口有两个通用实现:HashMap和TreeMap. HashMap是采用哈希表实现,是Map接口的最好的全面实现.TreeMap实现了Map的子接口SortedMap,采用红黑树作为底层存储结构,提供了按照键排序的Map存储.
2.1HashMap和Hashtable的对比:
HashMap Hashtable
键和值是否允许空 允许 不允许
是否多线程同步 否 是
但是HashMap可以通过如下方式方便地得到HashMap的一个同步视图:
Map synMap = Collections.synchronizedMap (new HashMap(...));
Hashtable已经经过再造,这是为了保持向后的兼容,保证老版本的程序能够继续正常允许;同时也方便Hashtable和新集合框架进行互操作(新的Hashtable实现了Map接口).正是因为Hashtable经过这些修改,反而使得它混合了新旧的很多特性,过于复杂,臃肿.
新的Map接口采用了比原来Hashtable采用的Enumeration功能更加强大的Iterator遍历工具.
Enumeration现在也不推荐使用, 不仅是因为Enumeration没有提供遍历键或值时安全删除Hashtable中的元素的途径;并且Enumeration的名称也不符合Sun的Java命名规范(采用Enumeration更加合适).而Hashtable为了兼容两者,在实现时,不得不提供同时实现了Enumeration和Iterator接口的Enumeration内部类.所以推荐大家用HashMap.
2.2 TreeMap
TreeMap中的Tree是一颗平衡二叉树,即每个内部节点都有一个前导节点或者说或者说父节点和两个子节点.存储后继节点的那个成员被命名为left和right. 二叉树在平衡时或者叶子节点到根结点的高度在一定的范围内时工作起来是最有效的.平衡一个二叉树的原因是为了缩短从根结点(这是在 TreeMap类中惟一能够被直接引用的结点)至每个叶子节点的距离.距离越短,访问那个节点所需时间就会越少.平衡树的定义因实现而异.java2 集合框架中的树采用红黑树.红黑树是一种平衡树,这个平衡树的定义是没有一个叶子节点跟其他叶子节点的深度差超过两步.这个名字就是由于树的每个节点都被着上红色和黑色,节点所着的颜色被用来检测树的平衡性.在对节点插入和删除的操作中,可能会被旋转来保持树的平衡性.一般和最坏情况插入,删除,查找时间都是O(lgn).
TreeMap的put方法:
public V put(K key, V value) {
Entry<K,V> t = root;
if (t == null) {
incrementSize();
root = new Entry<K,V>(key, value, null);
return null;
}
while (true) {
int cmp = compare(key, t.key);
if (cmp == 0) {
return t.setValue(value);
} else if (cmp < 0) {
if (t.left != null) {
t = t.left;
} else {
incrementSize();
t.left = new Entry<K,V>(key, value, t);
fixAfterInsertion(t.left);
return null;
}
} else { // cmp > 0
if (t.right != null) {
t = t.right;
} else {
incrementSize();
t.right = new Entry<K,V>(key, value, t);
fixAfterInsertion(t.right);
return null;
}
}
}
}
2.3 Map实现的选用
在不需要有序存储时,可以采用高效的HashMap;如果需要有序存储,可以采用TreeMap,但是由于TreeMap是以红黑树进行存储的,需要比HashMap更多的空间和时间的开销.
- Java中Map接口及实现
- Java中Map接口及实现
- Map接口及实现
- Java中map接口 遍历map
- Java中map接口 遍历map
- Java中接口定义及实现接口的抽象方法
- JAVA中Collection接口和Map接口的主要实现类
- JAVA中Collection接口和Map接口的主要实现类
- 细说JAVA中Collection接口和Map接口的主要实现类
- java中Map及Map.Entry详解
- Java Map接口练习(Map和List及排序)
- Map接口的实现类--Hashtable和HashMap及TreeMap的区别--------(java复习)
- Java基础-Map接口及其实现
- java SE基础(Map接口及其实现)
- java之Map接口及其实现类
- Java collection接口中list,set,map的区别及用法
- Java中Map接口HashMap与HashTable的区别及HashMap深入理解
- Java中Map接口HashMap与HashTable的区别及HashMap深入理解
- Java中Set接口及其实现
- 李开复:我的传奇人生源于十句箴言
- 关于框架
- WPF
- google好,没想到这么好
- Java中Map接口及实现
- javascript中易错的代码
- Flash手机抽奖程序设计:鼠标右键菜单
- 多用户个人网页系统(网站筹建)
- Session与Cookie的区别
- APUE.2E 随书代码的编译方法
- 编写用户增强
- SqlCommand对象-存储过程的使用
- 一个动态添加panel 和 删除panel的例子