Java中的AbstractMap
AbstractMap 类是Java Collection Framework的一部分。它直接实现Map接口以为其提供一个结构,通过这样做,使得更多的实现更容易。正如其名称所示,AbstractMap是一个抽象类的定义,因此不能用于创建对象。从AbstractMap继承的具体类可以用于创建对象。
声明:
public abstract class AbstractMap<K,V> extends Object, implements Map<K,V>
这里, K 是键的类型、 V 是值的类型。
AbstractMap的层次结构
这个类实现了Map<K, V>接口并扩展了Object类。
AbstractMap的构造函数
构造函数 | 定义 |
---|---|
protected AbstractMap() | 这个构造函数不能用来创建对象。这个构造函数的存在是为了让继承类调用它,这个调用是隐含的。 |
基本操作
1. 添加元素
要向AbstractMap中添加元素,我们使用put()方法。注意,该方法实际上不是AbstractMap类型的,而是扩展类的,对此对象的引用类型为AbstractMap。映射表的条目是键值对类型的。在这里,key的类型是Integer,value的类型是String,这在对象实例化时声明。
// Java程序演示将
//元素添加到AbstractMap
import java.util.*;
public class AddElements {
public static void main(String[] args)
{
// 由于AbstractMap是一个抽象类
//使用HashMap创建对象
AbstractMap<Integer, String> absMap
= new HashMap<Integer, String>();
// 向AbstractMap中添加值
//请注意,我们不创建
// AbstractMap的对象
absMap.put(1, "This");
absMap.put(2, "is");
absMap.put(3, "an");
absMap.put(4, "AbstractMap");
// 使用entrySet()显示映射
//获取集合视图
System.out.println("The Set view of the mappings:");
System.out.println(absMap.entrySet());
}
}
输出
The Set view of the mappings:
[1=This, 2=is, 3=an, 4=AbstractMap]
2. 删除元素
我们可以使用remove()方法从AbstractMap中删除映射。remove的语法如下所示:
mapName.remove(Object key);
这将删除与指定键映射的值。我们可以使用clear()方法清除整个AbstractMap,如下所示。
// Java程序演示如何从AbstractMap中删除元素
import java.util.*;
public class RemoveElements {
public static void main(String[] args)
{
//由于AbstractMap是一个抽象类,因此使用HashMap创建对象
AbstractMap<Integer, String> absMap
= new HashMap<Integer, String>();
absMap.put(1, "This");
absMap.put(2, "is");
absMap.put(3, "an");
absMap.put(4, "AbstractMap");
//显示映射关系
System.out.println("AbstractMap的映射关系:");
System.out.println(absMap);
//使用remove()方法删除一个键值对
absMap.remove(1);
//显示映射关系
System.out.println("AbstractMap的映射关系:");
System.out.println(absMap);
//使用clear()方法清空整个映射表
absMap.clear();
//显示映射关系
System.out.println("\n映射关系的Set视图:");
System.out.println(absMap);
}
}
输出
AbstractMap的映射关系:
{1=This, 2=is, 3=an, 4=AbstractMap}
AbstractMap的映射关系:
{2=is, 3=an, 4=AbstractMap}
映射关系的Set视图:
{}
3. 替换条目
我们可以使用replace()方法替换与键关联的值,如下所示。
// Java程序演示如何替换AbstractMap的元素
import java.util.AbstractMap;
import java.util.HashMap;
public class ReplaceElements {
public static void main(String[] args)
{
//由于AbstractMap是一个抽象类,因此使用HashMap创建对象
AbstractMap<Integer, String> absMap
= new HashMap<Integer, String>();
//向AbstractMap添加值
//注意我们不创建AbstractMap对象
absMap.put(1, "This");
absMap.put(2, "is");
absMap.put(3, "a");
absMap.put(4, "AbstractMap");
//显示映射关系
System.out.println("AbstractMap的映射关系:");
System.out.println(absMap);
//替换与3关联的映射
absMap.replace(3, "an");
//显示映射关系
System.out.println("\nAbstractMap的映射关系:");
System.out.println(absMap);
}
}
输出
AbstractMap的映射关系:
{1=This, 2=is, 3=a, 4=AbstractMap}
AbstractMap的映射关系:
{1=This, 2=is, 3=an, 4=AbstractMap}
4. 遍历
有不同的方法可以遍历AbstractMap,下面的代码中讨论了两种方法。第一种方法是使用entrySet()方法,它返回地图的一个集合视图。可以使用for each循环遍历此视图。getKey()方法返回键,getValue()方法返回相关联的值。第二种方法是使用Iterator接口。我们使用keySet()方法在键集上创建迭代器。此迭代器用于使用next()方法遍历地图,该方法返回地图中的下一个条目。
// Java程序演示
// 遍历AbstractMap
import java.util.*;
public class Traversing {
public static void main(String[] args)
{
// 由于AbstractMap是抽象类
// 使用HashMap创建对象
AbstractMap<Integer, String> absMap
= new HashMap<Integer, String>();
// 向AbstractMap添加值
// 注意我们不创建AbstractMap的对象
absMap.put(1, "This");
absMap.put(2, "is");
absMap.put(3, "a");
absMap.put(4, "AbstractMap");
// 方法1
// 利用entrySet()方法遍历映射,
// 其返回映射的集合视图
System.out.println("使用entrySet()方法");
for (AbstractMap.Entry<Integer, String> entry :
absMap.entrySet())
{
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}
// 方法2
// 利用Iterator接口遍历映射
System.out.println("\n使用Iterator接口");
Iterator<Integer> itr = absMap.keySet().iterator();
while (itr.hasNext())
{
int key = itr.next();
System.out.println("Key = " + key + ", Value = " + absMap.get(key));
}
}
}
输出结果
使用entrySet()方法
Key = 1, Value = This
Key = 2, Value = is
Key = 3, Value = a
Key = 4, Value = AbstractMap
使用Iterator接口
Key = 1, Value = This
Key = 2, Value = is
Key = 3, Value = a
Key = 4, Value = AbstractMap
继承类
1. HashMap
HashMap类是Map接口的基本实现,它存储键值对。HashMap是Hashtable的基本Map实现,但是HashMap是非同步的。HashMap中元素的顺序是未定义的。HashMap在插入、删除、遍历和操作的基本操作中提供常数时间性能。
语法:
HashMap< ? , ? > hmName = new HashMap< ? , ? >();
2. IdentityHashMap
IdentityHashMap是Hashtable的Map实现,但它使用引用相等性而不是对象相等性。这意味着IdentityHashMap违反了Map的基本规则,因此它不是通用Map,而是为罕见的情况保留的。在IdentityHashMap中,任何两个对象o1和o2只有在o1==o2即o1和o2的引用相同时才是相等的。
语法:
IdentityHashMap< ? , ? > ihmName = new IdentityHashMap< ? , ? >();
3. WeakHashMap
WeakHashMap是Map接口的Hashtable实现,它使用弱键。当WeakHashMap中的键不再在普通用途中使用时,其将自动丢弃。这意味着映射的存在不会防止键被垃圾回收。WeakHashMap是一个非同步类。
语法:
WeakHashMap< ? , ? > whmName = new WeakHashMap< ? , ? >();
4. TreeMap
TreeMap类是基于红黑树的NavigableMap实现。TreeMap元素排序方式为自然顺序或在构建时提供的比较器。
语法:
TreeMap< ? , ? > tmName = new TreeMap< ? , ? >();
5. EnumMap
EnumMap是Map接口的基于枚举类型的实现。该枚举类型的键必须来自单独的枚举类型,即不能与其他枚举类型的值混合使用。
EnumMap 是 Map 接口的一个特定实现。EnumMap 的键是枚举类型。所有的键必须是相同的枚举类型,可以在构造时显式或隐式地指定。EnumMap 在内部表示为一个数组,非常紧凑和高效。
语法:
EnumMap< enumName, ? > emName = new EnumMap< enumName, ? >();
6. ConcurrentHashMap
ConcurrentHashMap 是 Hashtable 实现,支持通过检索和更新操作实现全并发。这个类与 Hashtable 类非常兼容,并包含 Hashtable 的所有相应方法。虽然操作是线程安全的,但没有放置锁机制,因此检索可以与更新重叠。因此,检索操作反映了最近完成的更新操作。
语法:
ConcurrentHashMap< ? , ? > chmName = new ConcurrentHashMap< ? , ? >();
7. ConcurrentSkipListMap
ConcurrentSkipListMap 是 ConcurrentNavigableMap 接口的可扩展实现。ConcurrentSkipListMap 中的键按自然顺序排序或在对象创建时使用比较器进行排序。ConcurrentSkipListMap 在插入、删除和搜索操作的预期时间成本为 log n。它是一个线程安全的类,因此所有基本操作都可以同时完成。
语法:
ConcurrentSkipListMap< ? , ? > cslmName = new ConcurrentSkipListMap< ? , ? >();
AbstractMap 的方法
方法 | 描述 |
---|---|
clear() | 从此映射中删除所有映射(可选操作)。 |
clone() | 返回此 AbstractMap 实例的浅拷贝: 键和值本身不会被克隆。 |
containsKey(Object key) | 如果此映射包含指定键的映射,则返回 true。 |
containsValue(Object value) | 如果此映射将一个或多个键映射到指定值,则返回 true。 |
equals(Object o) | 将指定对象与此映射进行比较以实现相等性。 |
get(Object key) | 返回指定键映射到的值;如果此映射不包含键的映射,则返回 null。 |
hashCode() | 返回此映射的哈希码值。 |
isEmpty() | 如果此映射未包含键-值映射,则返回 true。 |
keySet() | 返回此映射中包含的键的 Set 视图。 |
put(K key, V value) | 将指定的值与此映射中的指定键相关联(可选操作)。 |
putAll(Map<? extends K,? extends V> m) | 将指定映射中的所有映射复制到此映射(可选操作)。 |
remove(Object key) | 如果存在(可选操作),从此映射中移除一个键的映射。 |
size() | 返回此映射中键-值映射的数量。 |
toString() | 返回此映射的字符串表示形式。 |
values() | 返回此映射中包含的值的 Collection 视图。 |
java.util.Map接口中声明的方法
方法 | 描述 |
---|---|
compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) | 尝试为指定的键及其当前的映射值(如果没有当前映射,则为null)计算映射。 |
computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction) | 如果指定的键尚未与值关联(或映射到null),则尝试使用给定的映射函数计算其值并将其输入到此映射中,除非为空。 |
computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) | 如果指定键的值存在且非null,则尝试计算给定键及其当前映射值的新映射。 |
entrySet() | 返回此映射中包含的映射的Set视图。 |
forEach(BiConsumer<? super K,? super V> action) | 对此映射中的每个条目执行给定操作,直到处理所有条目或操作引发异常为止。 |
getOrDefault(Object key, V defaultValue) | 返回指定键映射到的值,如果此映射不包含该键的值,则返回defaultValue。 |
merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction) | 如果指定的键尚未与值关联或已关联为null,则将其与给定的非null值相关联。 |
putIfAbsent(K key, V value) | 如果指定的键尚未与值关联(或已映射到null),则将其与给定的值相关联并返回null,否则返回当前的值。 |
remove(Object key, Object value) | 仅当指定键当前映射到指定值时才会删除该键的条目。 |
replace(K key, V value) | 仅当指定键当前映射到某个值时替换该键的条目。 |
replace(K key, V oldValue, V newValue) | 仅当当前映射到指定值时才替换指定键的条目。 |
replaceAll(BiFunction<? super K,? super V,? extends V> function) | 替换每个条目的值为调用该条目上的给定函数的结果,直到处理完所有条目或函数引发异常为止。 |