第32 章 : Map集合
139 Map接口简介
二元偶对象(key=value)
Collection集合保存数据是为了输出
Map集合保存数据是为了key查找
常用方法
put 添加数据
get 获取数据
entrySet 将Map转为Set
containsKey 检查存在
keySet 将Map中的key转为Set
remove 删除数据
继承关系
@Map
-@SortedMap
-@NavigableMap
AbstractMap(Map)
-HashMap(Map, Cloneable, Serializable)
-LinkedHashMap(Map)
-TreeMap(NavigableMap, Cloneable, Serializable)
Dictionary
-Hashtable(Map, Cloneable, Serializable)
140 HashMap子类
hash 无序
tree 有序
HashMap 无序存储
import java.util.HashMap;
import java.util.Map;
class Demo {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("one", "one");
map.put("one", "one+"); // key重复 会被覆盖
map.put("two", null); // value 为null
map.put(null, "three"); // key 为null
System.out.println(map.get("one")); // key重复 one+
System.out.println(map.get("two")); // key存在 null
System.out.println(map.get("ten")); // key不存在 null
}
}
put会返回原来的value
Map<String, Integer> map = new HashMap<>();
System.out.println(map.put("one", 1)); // null
System.out.println(map.put("one", 101)); // key重复 1
面试题:HashMap容量扩充
初始容量为16个元素,超过了阈值0.75 相当于 容量 * 阈值 = 12
,会自动扩充
扩充的时候会成倍扩充
面试题:HashMap工作原理
链表O(n)
二叉树O(logn)
JDK < 1.8 链表O(n)
JDK >= 1.8 链表O(n) 数量大于8个元素后变为 红黑树,保证查询性能
141 LinkedHashMap子类
LinkedHashMap(链表实现)按照添加顺序保存数据
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
class Demo {
public static void main(String[] args) {
Map<String, Integer> map = new LinkedHashMap<>();
map.put("two", 2);
map.put("one", 1);
map.put("three", 3);
System.out.println(map);
// HashMap {one=1, two=2, three=3}
// LinkedHashMap {two=2, one=1, three=3}
}
}
142 Hashtable子类
与Vector,Enumeration属于最早的动态数组实现类
Hashtable key 和value都不能为null
import java.util.Hashtable;
import java.util.Map;
class Demo {
public static void main(String[] args) {
Map<String, Integer> map = new Hashtable<>();
map.put("two", 2);
map.put("one", 1);
map.put("three", 3);
System.out.println(map);
// {two=2, one=1, three=3}
}
}
面试题:HashMap与HashTable区别
HashMap 异步操作,非线程安全, 允许null
HashTable 同步操作,线程安全,不允许null
143 Map.Entry内部接口
Map.Entry 作为一个key,value的包装
JDK >= 1.9
144 利用Iterator输出Map集合
存储结构
Collection(Iterator) Map
vlaue Map.Entry(key, value)
vlaue Map.Entry(key, value)
Map对象迭代方式
Map - entrySet() -> Set
Set - iterator() -> Iterator
Iterator -> Map.Entry
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
class Demo {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("Tom", 20);
map.put("Jack", 21);
// 1、将Map转Set
Set<Map.Entry<String, Integer>> set = map.entrySet();
// 2、将Set 转Iterator
Iterator<Map.Entry<String, Integer>> iterator = set.iterator();
while (iterator.hasNext()){
Map.Entry<String, Integer> entry = iterator.next();
System.out.println(entry.getKey() + "= "+ entry.getValue());
}
/**
* Tom= 20
* Jack= 21
*/
}
}
简化写法
import java.util.HashMap;
import java.util.Map;
class Demo {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("Tom", 20);
map.put("Jack", 21);
for(Map.Entry<String, Integer> entry: map.entrySet()){
System.out.println(entry.getKey() + "= "+ entry.getValue());
}
/**
* Tom= 20
* Jack= 21
*/
}
}
145 自定义Map的key类型
通过key获取hash码
常用key:
String
Integer
Long
面试体:HashMap出现Hash冲突
Hash冲突会转为链表
key key key(hash冲突)
value value value
value
value
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
class Person{
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
class Demo {
public static void main(String[] args) {
Map<Person, Integer> map = new HashMap<>();
map.put(new Person("Tom", 20), 20);
System.out.println(map.get(new Person("Tom", 20)));
// 20
}
}