Map映射
public interface Map<K,V>
- 将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
- 类型参数:
-
K
- 此映射所维护的键的类型 -
V
- 映射值的类型
- 实现类:HashMap、Hashtable、LinkedHashMap
- 总结:
- Map存储的是键值对及他们之间的映射关系
- Map的key不能重复
- Map中每个key只能对应一个value
方法
V put(K key, V value)
:将指定的值与此映射中的指定键关联(可选操作)。
- 如果map中已经存在当前key,调用put方法添加则会覆盖之前的Value值;
- 如果map中没有当前添加的key,则返回值为null;如果map中已经存在当前key,返回值为被覆盖掉的值;
void clear()
: 从此映射中移除所有映射关系(可选操作)。boolean containsKey(Object key)
:如果此映射包含指定键的映射关系,则返回 true。boolean containsValue(Object value)
: 如果此映射将一个或多个键映射到指定值,则返回 true。V get(Object key)
: 返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 nullboolean isEmpty()
:如果此映射未包含键-值映射关系,则返回 true。Set<K> keySet()
:返回此映射中包含的键的 Set 视图
返回值是Set集合的原因是:Map的key是唯一的Collection<V> values()
:返回此映射中包含的值的 Collection 视图V remove(Object key)
:如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。int size()
:返回此映射中的键-值映射关系数。Set<Map.Entry<K,V>> entrySet()
:返回此映射中包含的映射关系的 Set 视图。
public class MapDemo2 {
public static void main(String[] args) {
// 创建Map的对象
Map<String,Integer> map = new HashMap<String,Integer>();
// put() 添加元素
System.out.println(map.put("001",28)); // null
System.out.println(map.put("002",17)); // null
System.out.println(map.put("001",60)); //28
// 编译不报错,如果重复则对value进行覆盖
// 重写toString() Key = Value
System.out.println(map); // {001=60, 002=17}
// containsKey()
System.out.println(map.containsKey("002")); // true
// containsValue()
System.out.println(map.containsValue(28)); // false
// equals()
Map<String, Integer> copyMap = new HashMap<String,Integer>();
copyMap.putAll(map);
System.out.println(map.equals(copyMap)); // true
// get(key)
int num = map.get("001"); // 自动拆箱
// int num1 = map.get("008"); // error
// map.get("008"); 返回null
// 自动拆箱时调用 null.intValue() -- > 空指针异常
System.out.println(map.get("008")); // null
// Set<K> keySet():将key值放入一个Set
Set<String> keys = map.keySet();
// Values(): 返回values形成的集合
Collection<Integer> col = map.values();
System.out.println(keys+"\n"+col);
// remove(key)
int tmp = copyMap.remove("001");
System.out.println(tmp);
// size()
System.out.println(map.size());
}
}
如何遍历Map
- 方案一:
- KeySet获取所有key的Set
- 遍历Set集合
- 根据key的值获取对应的value
- 方案二:
- 调用entrySet()获取代表Map键值对的Entry对象的Set集合
- 遍历Set集合
- 调用Entry的方法,分别获取Key,Value
- K getKey():返回与此项对应的键。
- V getValue(): 返回与此项对应的值 。
// 遍历
// 方案一:
// 1. keySet 获取所有key的set集合
Set<String> keys = map.keySet();
// 2. 遍历set集合
for (String str: keys){
// 3. 根据key的值获取对应value
System.out.println(str+"="+map.get(str));
}
// 方案二:
// 1. 调用entrySet()获取代表Map键值对的Entry对象的Set集合
Set<Map.Entry<String,Integer>> entries = map.entrySet();
// 2.遍历Set集合
for (Map.Entry<String,Integer> entry : entries){
// 3. 调用Entry的方法,分别获取Key,Value
System.out.println(entry.getKey() + "=" + entry.getValue());
}
// 简化版
for(Map.Entry<String,Integer> entry: map.entrySet()){
System.out.println(entry.getKey() + "=" + entry.getValue());
}
HashMap
- 基于数组&链表实现
- HashMap底层为了提高效率,会做相应的优化
- JDK1.8,当链表的链长超过8时,转成红黑树;删除元素后,当链表的长度小于6时,又转回链表
- HashMap的key可以为null,但是只有一个;HashMap的value可以为null,不限制个数
- 异步式线程不安全
- 构造方法:
- HashMap():构造一个具有默认初始容量 (16) 和默认加载(负载、装载)因子 (0.75) 的空 HashMap;当超过16*0.75=12时开始扩容,每次扩容一倍
- 方法:无特殊方法
Hashtable
- 从以下版本开始: JDK1.0
- 特点:键值都不能为null
- 同步式线程安全
- 构造方法
- Hashtable() :用默认的初始容量 (11) 和加载因子 (0.75) 构造一个新的空哈希表。
public class HashtableDemo {
public static void main(String[] args) {
// 创建对象 Hashtable
Hashtable<String,Integer> table = new Hashtable<String, Integer>();
//
table.put("start",12); // 自动装箱
table.put("hello",15);
table.put("java",30);
System.out.println(table);
// 遍历
// 1. 迭代器 elements,只能输出value
Enumeration<Integer> ele = table.elements();
Enumeration<String> keys = table.keys();
while(keys.hasMoreElements()){
System.out.println(keys.nextElement() + "=" + ele.nextElement());
}
// 2. entrySet()
Set<Map.Entry<String,Integer>> entries = table.entrySet();
for(Map.Entry<String,Integer> entry: entries){
System.out.println(entry.getKey() + "=" + entry.getValue());
}
// 简化版
for(Map.Entry<String,Integer> entry: table.entrySet()){
System.out.println(entry.getKey() + "=" + entry.getValue());
}
}
}
HashMap和Hashtable的区别:
- HashMap JDK1.2;Hashtable JDK1.0
- HashMap 初始容量为16,加载因子0.75;扩容每次扩容一倍;
Hashtable 初始容量为11,加载因子0.75;扩容每次扩容一倍+1; - HashMap 异步式线程不安全,效率高
HashTable 同步式线程安全,效率低 - HashMap 键值可以为null,键只能有一个null
Hashtable 键值都不能为null
注意:HashMap和Hashtable都是无序的,LinkedHashMap能够保证存入的顺序