联系

Java中的Map类似于OC的Dictionary,都是一个个键值对组成,一键对应一值。我在之前的文章中讲解过Set,其实在JAVA底层Set依赖的也是Map,那我们都知道,Set是单列的(只有值),而Map是双列的,怎么会是Set依赖Map呢?其实做法也很简单,Set将Key隐藏,只允许访问value就实现了Set的单列效果。

功能

*a:添加功能
* V put(K key,V value):添加元素。
* 如果键是第一次存储,就直接存储元素,返回null
* 如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值

Map的遍历

方式一
  //通过获取所有的键来遍历值
Map<String, Integer> map = new HashMap<>();
map.put("张三", 23);
map.put("李四", 24);
map.put("王五", 25);
map.put("赵六", 26); Set<String> keySet = map.keySet(); //获取所有键的集合
Iterator<String> it = keySet.iterator(); //获取迭代器
while(it.hasNext()) { //判断集合中是否有元素
String key = it.next(); //获取每一个键
Integer value = map.get(key); //根据键获取值
System.out.println(key + "=" + value);
}

使用迭代器遍历,但是有些复杂,可以改进

方式二 (方式一改进,较简单)

这种遍历方式类似于OC中for···in语法

        //使用增强for循环遍历
for(String key : map.keySet()) { //map.keySet()是所有键的集合
System.out.println(key + "=" + map.get(key));
}
方式三 键值对对象遍历
        //Map.Entry说明Entry是Map的内部接口,将键和值封装成了Entry对象,并存储在Set集合中
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
//获取每一个对象
Iterator<Map.Entry<String, Integer>> it = entrySet.iterator();
while(it.hasNext()) {
//获取每一个Entry对象
Map.Entry<String, Integer> en = it.next(); //父类引用指向子类对象
//Entry<String, Integer> en = it.next(); //直接获取的是子类对象
String key = en.getKey(); //根据键值对对象获取键
Integer value = en.getValue(); //根据键值对对象获取值
System.out.println(key + "=" + value);
}
方式四 (方式三改进)
        for(Entry<String, Integer> en : map.entrySet()) {
System.out.println(en.getKey() + "=" + en.getValue());
}

LinkedHashMap

LinkedHashMap可以保证怎么存就怎么取

    public static void main(String[] args) {
LinkedHashMap<String, Integer> lhm = new LinkedHashMap<>();
lhm.put("张三", 23);
lhm.put("李四", 24);
lhm.put("赵六", 26);
lhm.put("王五", 25); System.out.println(lhm);
}

TreeMap

利用TreeMap可实现对键的自定义排序,同时键应为自定义类对象,同时需要在自定义类中重写compareTo方法,和hashSet里面的排序大致相同。

//按照Student的姓名排序,姓名相同按照年龄排序
public static void main(String[] args) {
//demo1();
TreeMap<Student, String> tm = new TreeMap<>(new Comparator<Student>() { @Override
public int compare(Student s1, Student s2) {
int num = s1.getName().compareTo(s2.getName()); //按照姓名比较
return num == 0 ? s1.getAge() - s2.getAge() : num;
}
});
tm.put(new Student("张三", 23), "北京");
tm.put(new Student("李四", 13), "上海");
tm.put(new Student("赵六", 43), "深圳");
tm.put(new Student("王五", 33), "广州"); System.out.println(tm);
}

利用HashMap统计字符串中每个字符出现的次数

核心思想就是利用HashMap的containsKey()来判断是否重复。

/**
* * A:案例演示
* 需求:统计字符串中每个字符出现的次数
*
* 分析:
* 1,定义一个需要被统计字符的字符串
* 2,将字符串转换为字符数组
* 3,定义双列集合,存储字符串中字符以及字符出现的次数
* 4,遍历字符数组获取每一个字符,并将字符存储在双列集合中
* 5,存储过程中要做判断,如果集合中不包含这个键,就将该字符当作键,值为1存储,如果集合中包含这个键,就将值加1存储
* 6,打印双列集合获取字符出现的次数
*/
public static void main(String[] args) {
//1,定义一个需要被统计字符的字符串
String s = "aaaabbbbbccccccccccccc";
//2,将字符串转换为字符数组
char[] arr = s.toCharArray();
//3,定义双列集合,存储字符串中字符以及字符出现的次数
HashMap<Character, Integer> hm = new HashMap<>();
//4,遍历字符数组获取每一个字符,并将字符存储在双列集合中
for(char c: arr) {
//5,存储过程中要做判断,如果集合中不包含这个键,就将该字符当作键,值为1存储,如果集合中包含这个键,就将值加1存储
/*if(!hm.containsKey(c)) { //如果不包含这个键
hm.put(c, 1);
}else {
hm.put(c, hm.get(c) + 1);
}*/
hm.put(c, !hm.containsKey(c) ? 1 : hm.get(c) + 1);
}
//6,打印双列集合获取字符出现的次数 for (Character key : hm.keySet()) { //hm.keySet()代表所有键的集合
System.out.println(key + "=" + hm.get(key));//hm.get(key)根据键获取值
}
}
案例演示:

集合嵌套之HashMap嵌套HashMap

需求:

一个年级有很多班,
一班定义为一个双列结合,键是学生对象,值是学生的归属地,
二班定义为一个双列结合,键是学生对象,值是学生的归属地。
无论一班二班都是班级对象,所以为了编译统一管理,把这些班级对象添加到某个年级中。

        //定义一班
HashMap<Student, String> hm88 = new HashMap<>();
hm88.put(new Student("张三", 23), "北京");
hm88.put(new Student("李四", 24), "北京");
hm88.put(new Student("王五", 25), "上海");
hm88.put(new Student("赵六", 26), "广州"); //定义二班
HashMap<Student, String> hm99 = new HashMap<>();
hm99.put(new Student("唐僧", 1023), "北京");
hm99.put(new Student("孙悟空",1024), "北京");
hm99.put(new Student("猪八戒",1025), "上海");
hm99.put(new Student("沙和尚",1026), "广州"); //定义年级
HashMap<HashMap<Student, String>, String> hm = new HashMap<>();
hm.put(hm88, "一班");
hm.put(hm99, "二班"); //遍历双列集合
for(HashMap<Student, String> h : hm.keySet()) { //hm.keySet()代表的是双列集合中键的集合
String value = hm.get(h); //get(h)根据键对象获取值对象
//遍历键的双列集合对象
for(Student key : h.keySet()) { //h.keySet()获取集合总所有的学生键对象
String value2 = h.get(key); System.out.println(key + "=" + value2 + "=" + value);
}
}

hashMap和hashTable的区别

共同点:

底层都是哈希算法,都是双列集合

区别:
  1. HashMap是线程不安全的,效率高,JDK1.2版本,Hashtable是线程安全的,效率低,JDK1.0版本的
  2. HashMap可以存储null键和null值,Hashtable不可以存储null键和null值

深入了解Map的更多相关文章

  1. mapreduce中一个map多个输入路径

    package duogemap; import java.io.IOException; import java.util.ArrayList; import java.util.List; imp ...

  2. .NET Core中间件的注册和管道的构建(3) ---- 使用Map/MapWhen扩展方法

    .NET Core中间件的注册和管道的构建(3) ---- 使用Map/MapWhen扩展方法 0x00 为什么需要Map(MapWhen)扩展 如果业务逻辑比较简单的话,一条主管道就够了,确实用不到 ...

  3. Java基础Map接口+Collections工具类

    1.Map中我们主要讲两个接口 HashMap  与   LinkedHashMap (1)其中LinkedHashMap是有序的  怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...

  4. Java基础Map接口+Collections

    1.Map中我们主要讲两个接口 HashMap  与   LinkedHashMap (1)其中LinkedHashMap是有序的  怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...

  5. 多用多学之Java中的Set,List,Map

            很长时间以来一直代码中用的比较多的数据列表主要是List,而且都是ArrayList,感觉有这个玩意就够了.ArrayList是用于实现动态数组的包装工具类,这样写代码的时候就可以拉进 ...

  6. Java版本:识别Json字符串并分隔成Map集合

    前言: 最近又看了点Java的知识,于是想着把CYQ.Data V5迁移到Java版本. 过程发现坑很多,理论上看大部分很相似,实践上代码写起来发现大部分都要重新思考方案. 遇到的C#转Java的一些 ...

  7. MapReduce剖析笔记之八: Map输出数据的处理类MapOutputBuffer分析

    在上一节我们分析了Child子进程启动,处理Map.Reduce任务的主要过程,但对于一些细节没有分析,这一节主要对MapOutputBuffer这个关键类进行分析. MapOutputBuffer顾 ...

  8. MapReduce剖析笔记之七:Child子进程处理Map和Reduce任务的主要流程

    在上一节我们分析了TaskTracker如何对JobTracker分配过来的任务进行初始化,并创建各类JVM启动所需的信息,最终创建JVM的整个过程,本节我们继续来看,JVM启动后,执行的是Child ...

  9. MapReduce剖析笔记之五:Map与Reduce任务分配过程

    在上一节分析了TaskTracker和JobTracker之间通过周期的心跳消息获取任务分配结果的过程.中间留了一个问题,就是任务到底是怎么分配的.任务的分配自然是由JobTracker做出来的,具体 ...

  10. MapReduce剖析笔记之三:Job的Map/Reduce Task初始化

    上一节分析了Job由JobClient提交到JobTracker的流程,利用RPC机制,JobTracker接收到Job ID和Job所在HDFS的目录,够早了JobInProgress对象,丢入队列 ...

随机推荐

  1. 浅谈Android布局

    在前面的博客中,小编介绍了Android的极光推送以及如何实现登录的一个小demo,对于xml布局页面,摆控件这块的内容,小编还不是很熟练,今天小编主要简单总结一下在Android中的布局,学习过An ...

  2. matlab中的sub2ind函数

    在matlab中,矩阵的存储是按列优先,sub2ind函数将矩阵中指定元素的行列下标转换成存储的序号,即线性索引号.下面,我们举例子进行说明. 1 建立一个3*4*2的矩阵 rng(0,'twiste ...

  3. 剑指Offer——贪心算法

    剑指Offer--贪心算法 一.基本概念 所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解.虽然贪心算法不能对 ...

  4. iOS中 Realm的学习与使用 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博! 有问题或技术交流可以咨询!欢迎加入! 这篇直接搬了一份官方文档过来看的 由于之前没用markdown搞的乱七八糟的 ...

  5. SSH深度历险(十一) AOP原理及相关概念学习+xml配置实例(对比注解方式的优缺点)

    接上一篇 SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP,本篇我们主要是来学习使用配置XML实现AOP 本文采用强制的CGLB代理方式 Security ...

  6. 利用并查集+贪心解决 Hdu1232

    畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  7. JSP自定义标签必知必会

    自定义标签技术自sun公司发布以来,便一向很受欢迎!下面我就来谈一谈如何实现自定义标签,以及如何使用自定义标签. 如何实现自定义标签 首先我们应该知道原理,不管是标签还是JSP,本身实际上都会被JSP ...

  8. Python学习笔记 - function调用和定义

    调用函数: #!/usr/bin/env python3 # -*- coding: utf-8 -*- # 函数调用 >>> abs(100) 100 >>> a ...

  9. EBS 信用检查(二)

    Credit checking feature of Oracle OM provides the ability to check that the customer has sufficient ...

  10. SpriteBuilder改变布局后App运行出错代码排查

    原来整个关卡场景放在GameScene.ccb中,后来觉得移到专门的Level.ccb比较好. 移动过后编译运行,只要移动Player的胳膊发射子弹时,Xcode报错: g due to Chipmu ...