Java 中的HashMap
在实现Map
接口的集合类中。 它用于存储键值对。 每个键都映射到映射中的单个值。
键是唯一的。 这意味着我们只能在映射中插入键K
一次。 不允许重复的键。 虽然值V
可以映射到多个键。
1. java.util.HashMap
类
1.1 HashMap
类声明
HashMap
已声明如下:
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
1.2 HashMap
类层次结构
如上所示,HashMap
实现Map
接口并扩展AbstractMap
类。
HashMap
层次结构
2. Java HashMap
特性
HashMap
不能包含重复的键。HashMap
允许多个null
值,但只允许一个null
键。HashMap
是无序集合。 它不保证元素的任何特定顺序。HashMap
是不是线程安全的。 您必须显式同步对HashMap
的并发修改。 或者,您可以使用Collections.synchronizedMap(hashMap)
来获取HashMap
的同步版本。- 只能使用关联的键来检索值。
HashMap
仅存储对象引用。 因此,必须将原始类型与其对应的包装器类一起使用。 例如int
将存储为Integer
。HashMap
实现了Clonable
和serializable
接口。
3. HashMap
内部实现
HashMap
按照哈希原理工作。 在将任何公式/算法应用于其属性之后,哈希是一种为任何变量/对象分配唯一代码的方法。 Java 中的每个对象都有其哈希码,这样两个相等的对象必须一致地产生相同的哈希码。
3.1 HashMap.Entry
类
键值对存储为内部类HashMap.Entry
的实例,该内部类将键和值映射存储为属性。 键已标记为final
。
static class Entry<K ,V> implements Map.Entry<K, V>
{
final K key;
V value;
Entry<K ,V> next;
final int hash;
...//More code goes here
}
3.2 内部工作
Entry
类的所有实例都存储在声明为transient Entry[] table
的数组中。 对于要存储在HashMap
中的每个键值,使用键的哈希码计算哈希值。 该哈希值用于计算数组中用于存储Entry
对象的索引。
在冲突的情况下,其中多个键映射到单个索引位置,形成的链表用来存储所有应该放在单个数组索引位置的所有键值对。
通过键检索值时,使用键的哈希码可以找到第一个索引位置。 然后,在链表中迭代所有元素,并使用equals()
方法识别正确的键,从而找到正确的值对象。
4. Java HashMap
示例
让我们快速浏览一些示例,以在 Java 中使用HashMap
。
4.1 添加键值 – HashMap.put()
import java.util.HashMap;
public class HashMapExample
{
public static void main(String[] args) throws CloneNotSupportedException
{
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "A");
map.put(2, "B");
map.put(3, "C");
System.out.println(map);
}
}
程序输出。
{1=A, 2=B, 3=C}
4.2 通过键获取值 – HashMap.get()
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "A");
map.put(2, "B");
map.put(3, "C");
String value = map.get(2);
System.out.println("The value is :: "+ value );
程序输出:
The value is :: B
4.3 通过键删除偶对 – HashMap.remove()
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "A");
map.put(2, "B");
map.put(3, "C");
System.out.println(map);
map.remove(3);
System.out.println(map);
程序输出:
{1=A, 2=B, 3=C}
{1=A, 2=B}
4.4 迭代HashMap
请注意,此类的迭代器为快速失败,如果在创建迭代器后进行了任何结构修改,它将抛出ConcurrentModificationException
。
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "A");
map.put(2, "B");
map.put(3, "C");
System.out.println("//Iterate over keys");
Iterator<Integer> itr = map.keySet().iterator();
while (itr.hasNext())
{
Integer key = itr.next();
String value = map.get(key);
System.out.println("The key is :: " + key + ", and value is :: " + value );
}
System.out.println("//Iterate over entries set");
Iterator<Entry<Integer, String>> entryIterator = map.entrySet().iterator();
while (entryIterator.hasNext())
{
Entry<Integer, String> entry = entryIterator.next();
System.out.println("The key is :: " + entry.getKey() + ", and value is :: " + entry.getValue() );
}
程序输出:
//Iterate over keys
The key is :: 1, and value is :: A
The key is :: 2, and value is :: B
The key is :: 3, and value is :: C
//Iterate over entries set
The key is :: 1, and value is :: A
The key is :: 2, and value is :: B
The key is :: 3, and value is :: C
5. HashMap
方法
HashMap 类中的方法列表及其简短描述。
void clear()
:从HashMap
中删除所有键值对。Object clone()
:返回指定HashMap
的浅表副本。boolean containsKey(Key key)
:根据是否在映射中找到指定的键,返回true
或false
。boolean containsValue(Value Value)
:类似于containsKey()
方法,它查找指定的值而不是键。Value get(Key key)
:返回HashMap
中指定键的值。boolean isEmpty()
:检查映射是否为空。Set keySet()
:返回HashMap
中存储的所有键的Set
。Object put(Key k, Value v)
:将键值对插入HashMap
中。int size()
:返回映射的大小,该大小等于存储在HashMap
中的键值对的数量。Collection values()
:返回映射中所有值的集合。Value remove(Key key)
:移除指定键的键值对。void putAll(Map m)
:将映射的所有元素复制到另一个指定的映射。
6. HashMap 教程和示例
HashMap
在 Java 中的工作方式- 不同方式对
HashMap
进行迭代的性能比较 - 如何为
HashMap
设计好的自定义键对象 - Java 中
HashMap
和Hashtable
之间的区别 - Java 按键对映射进行排序(升序和降序)
- Java 按值对映射进行排序(升序和降序)
- Java
hashCode()
和equals()
- 契约,规则和最佳做法 HashMap
和ConcurrentHashMap
面试问题- Java
ConcurrentHashMap
最佳实践 - 将 JSON 转换为
Map
并映射为 JSON - Java 中的 Marshal 和 Unmarshal
HashMap
- 如何使用
HashMap
查找字符串中的重复单词 - 比较两个
HashMap
- 同步
HashMap
- 合并两个
HashMaps
- 如何克隆
HashMap
学习愉快!