现实生活中,我们经常需要成对存储某些信息。比如,我们使用的微信,一个手机号只能对应一个微信账户。这就是一种成对存储的关系。
Map就是用来存储“键(key)-值(value) 对”。 Map类中存储的“键值对”通过键来标识,所以“键对象”不能重复。
Map 接口的实现类有:
HashMap、TreeMap、HashTable、Properties等。
常用的方法:
方法
说明
Object put(Object key, Object value)
存放键值对
Object get(Object key)
通过键对象查找得到值对象
Object remove(Object key)
删除键对象对应的键值对
boolean containsKey(Object key)
Map容器中是否包含键对象对应的键值对
boolean containsValue(Object value)
Map容器中是否包含值对象对应的键值对
int size()
包含键值对的数量
boolean isEmpty()
Map是否为空
void putAll(Map t)
将t的所有键值对存放到本map对象
void clear()
清空本map对象所有键值对
HashMap
HashMap采用哈希算法实现,是Map接口最常用的实现类。 由于底层采用了哈希表存储数据,我们要求键不能重复,如果发生重复,新键值对会替换旧的键值对。 HashMap在查找、删除、修改方面都有非常高的效率。
【示例1】Map接口中常用方法的使用
public class Test {
public static void main(String[] args) {
Map
Map
m1.put(1, "one");
m1.put(2, "two");
m1.put(3, "three");
m2.put(1,"一");
m2.put(2,"二");
System.out.println(m1.size());
System.out.println(m1.containsKey(1));
System.out.println(m2.containsValue("two"));
m1.put(3, "third"); //键重复了,则会替换旧的键值对
Map
m3.putAll(m1);
m3.putAll(m2);
System.out.println("m1:"+m1);
System.out.println("m2:"+m2);
System.out.println("m3:"+m3);
}
}
示例1 运行效果图
HashTable
HashTable类和HashMap用法几乎一样,底层实现几乎一样,只不过HashTable的方法添加了Synchronized关键字确保线程同步检查,效率较低。
HashMap与HashTable的区别
1) HashMap: 线程不安全,效率高. 允许key或value为null
2) HashTable:线程安全,效率低. 不允许key或value为null
HashMap底层实现
HashMap底层实现采用了哈希表,这是一种非常重要的数据结构。对于我们以后理解很多技术都非常有帮助(比如:redis数据库的核心技术和HashMap一样),因此,非常有必要让大家理解。
数据结构中有数组和链表来实现对数据的存储,他们各有特点。
数组:占用空间连续。 寻址容易,查询速度快。但是,增加和删除效率非常低。
链表:占用空间不连续。 寻址困难,查询速度慢。但是,增加和删除效率非常高。
那么,我们能不能结合“数组+链表”,可以结合双方优点(即查询快,增删效率也高)的结构呢? 答案就是“哈希表”。 哈希表的本质就是“数组+链表”。
老鸟建议
对于本章中频繁出现的“底层实现”讲解,建议学有余力的童鞋将他搞通。刚入门的童鞋如果觉得有难度,可以暂时跳过。入门期间,掌握如何使用即可,底层原理是扎实内功,便于大家应对一些大型企业的笔试面试。
下节,我们继续深入讨论「HashMap底层实现」
「全栈Java笔记」是一部能帮大家从零到一成长为全栈Java工程师系列笔记。笔者江湖人称 Mr. G,10年Java研发经验,曾在神州数码、航天院某所研发中心从事软件设计及研发工作,从小白逐渐做到工程师、高级工程师、架构师。精通Java平台软件开发,精通JAVAEE,熟悉各种流行开发框架。
笔记包含从浅入深的六大部分:
A-Java入门阶段
B-数据库从入门到精通
C-手刃移动前端和Web前端
D-J2EE从了解到实战
E-Java高级框架精解
F-Linux和Hadoop