Map接口概述

Map:双列集合类的根接口,用于存储具有键(Key)、值(Value)映射关系的元素,每个元素都包含一对键值,在使用Map集合时可以通过指定的Key找到对应的Value,例如根据一个学生的学号就可以找到对应的学生。Map接口的主要实现类有HashMap和TreeMap。

将键映射到值的对象,一个映射不能包含重复的键,每个键最多只能映射到一个值。其实Map集合中存储的就是键值对。map集合中必须保证键的唯一性。

Map接口和Collection接口的不同

  • Map是双列的,Collection是单列的
  • Map的键唯一,Collection的子体系Set是唯一的
  • Map集合的数据结构值针对键有效,跟值无关
  • Collection集合的数据结构是针对元素有效

Map常用的子类:

  • Hashtable:内部结构是哈希表,是同步的。不允许null作为键,null作为值。
  • Properties:用来存储键值对型的配置文件的信息,可以和IO技术相结合。
  • HashMap:内部结构式哈希表,不是同步的。允许null作为键,null作为值。
  • TreeMap:内部结构式二叉树,不是同步的。可以对Map结合中的键进行排序。
  • HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持。

Map接口常用方法

方法声明 功能描述
put(K key, V value) 有添加和替换功能
putAll(Map m) 添加一个Map的元素
clear() 清空集合
remove(Object key) 根据键删除一个元素
containsKey() 判断集合是否包含指定的键
containsValue() 判断集合是否包含指定的值
isEmpty() 判断集合是否为空
get(Object key) 根据键获取值
keySet() 获取所有的键
values() 获取所有的值
entrySet() 获取所有的Entry
size() 获取集合元素的个数

map

HashMap

键是哈希表结构,可以保证键的唯一性

LinkedHashMap

Map 接口的哈希表和链接列表实现,具有可预知的迭代顺序。

TreeMap

键是红黑树结构,可以保证键的排序和唯一性,自然排序,比较器排序。

Map集合遍历

方式1:根据键找值。获取所有键的集合,遍历键的集合,获取到每一个键,根据键找值。

  1. package cn.itcast;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import java.util.Set;
  5. /*
  6. * Map集合的遍历。
  7. * Map -- 夫妻对
  8. * 思路:
  9. * A:把所有的丈夫给集中起来。
  10. * B:遍历丈夫的集合,获取得到每一个丈夫。
  11. * C:让丈夫去找自己的妻子。
  12. *
  13. * 转换:
  14. * A:获取所有的键
  15. * B:遍历键的集合,获取得到每一个键
  16. * C:根据键去找值
  17. */
  18. public class MapDemo {
  19. public static void main(String[] args) {
  20. // 创建集合对象
  21. Map<String, String> map = new HashMap<String, String>();
  22. // 创建元素并添加到集合
  23. map.put("杨过", "小龙女");
  24. map.put("郭靖", "黄蓉");
  25. map.put("杨康", "穆念慈");
  26. map.put("陈玄风", "梅超风");
  27. // 遍历
  28. // 获取所有的键
  29. Set<String> set = map.keySet();
  30. // 遍历键的集合,获取得到每一个键
  31. for (String key : set) {
  32. // 根据键去找值
  33. String value = map.get(key);
  34. System.out.println(key + "---" + value);
  35. }
  36. }
  37. }

方式2:根据键值对对象找键和值。

  • 获取所有键值对对象的集合
  • 遍历键值对对象的集合,获取到每一个键值对对象
  • 根据键值对对象找键和值
  1. package cn.itcast;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import java.util.Set;
  5. /*
  6. * Map集合的遍历。
  7. * Map -- 夫妻对
  8. *
  9. * 思路:
  10. * A:获取所有结婚证的集合
  11. * B:遍历结婚证的集合,得到每一个结婚证
  12. * C:根据结婚证获取丈夫和妻子
  13. *
  14. * 转换:
  15. * A:获取所有键值对对象的集合
  16. * B:遍历键值对对象的集合,得到每一个键值对对象
  17. * C:根据键值对对象获取键和值
  18. *
  19. * 这里面最麻烦的就是键值对对象如何表示呢?
  20. * 看看我们开始的一个方法:
  21. * Set<Map.Entry<K,V>> entrySet():返回的是键值对对象的集合
  22. */
  23. public class MapDemo {
  24. public static void main(String[] args) {
  25. // 创建集合对象
  26. Map<String, String> map = new HashMap<String, String>();
  27. // 创建元素并添加到集合
  28. map.put("杨过", "小龙女");
  29. map.put("郭靖", "黄蓉");
  30. map.put("杨康", "穆念慈");
  31. map.put("陈玄风", "梅超风");
  32. // 获取所有键值对对象的集合
  33. Set<Map.Entry<String, String>> set = map.entrySet();
  34. // 遍历键值对对象的集合,得到每一个键值对对象
  35. for (Map.Entry<String, String> me : set) {
  36. // 根据键值对对象获取键和值
  37. String key = me.getKey();
  38. String value = me.getValue();
  39. System.out.println(key + "---" + value);
  40. }
  41. }
  42. }

Map集合的应用及扩展

  1. package cn.itcast;
  2. import java.util.Scanner;
  3. import java.util.Set;
  4. import java.util.TreeMap;
  5. /*
  6. * 需求 :"aababcabcdabcde",获取字符串中每一个字母出现的次数要求结果:a(5)b(4)c(3)d(2)e(1)
  7. *
  8. * 分析:
  9. * A:定义一个字符串(可以改进为键盘录入)
  10. * B:定义一个TreeMap集合
  11. * 键:Character
  12. * 值:Integer
  13. * C:把字符串转换为字符数组
  14. * D:遍历字符数组,得到每一个字符
  15. * E:拿刚才得到的字符作为键到集合中去找值,看返回值
  16. * 是null:说明该键不存在,就把该字符作为键,1作为值存储
  17. * 不是null:说明该键存在,就把值加1,然后重写存储该键和值
  18. * F:定义字符串缓冲区变量
  19. * G:遍历集合,得到键和值,进行按照要求拼接
  20. * H:把字符串缓冲区转换为字符串输出
  21. *
  22. * 录入:linqingxia
  23. * 结果:result:a(1)g(1)i(3)l(1)n(2)q(1)x(1)
  24. */
  25. public class TreeMapDemo {
  26. public static void main(String[] args) {
  27. // 定义一个字符串(可以改进为键盘录入)
  28. Scanner sc = new Scanner(System.in);
  29. System.out.println("请输入一个字符串:");
  30. String line = sc.nextLine();
  31. // 定义一个TreeMap集合
  32. TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();
  33. // 把字符串转换为字符数组
  34. char[] chs = line.toCharArray();
  35. // 遍历字符数组,得到每一个字符
  36. for (char ch : chs) {
  37. // 拿刚才得到的字符作为键到集合中去找值,看返回值
  38. Integer i = tm.get(ch);
  39. // 是null:说明该键不存在,就把该字符作为键,1作为值存储
  40. if (i == null) {
  41. tm.put(ch, 1);
  42. } else {
  43. // 不是null:说明该键存在,就把值加1,然后重写存储该键和值
  44. i++;
  45. tm.put(ch, i);
  46. }
  47. }
  48. // 定义字符串缓冲区变量
  49. StringBuilder sb = new StringBuilder();
  50. // 遍历集合,得到键和值,进行按照要求拼接
  51. Set<Character> set = tm.keySet();
  52. for (Character key : set) {
  53. Integer value = tm.get(key);
  54. sb.append(key).append("(").append(value).append(")");
  55. }
  56. // 把字符串缓冲区转换为字符串输出
  57. String result = sb.toString();
  58. System.out.println("result:" + result);
  59. }
  60. }

示例2:在很多项目中,应用比较多的是一对多的映射关系,这就可以通过嵌套的形式将多个映射定义到一个大的集合中,并将大的集合分级处理,形成一个体系。

  1. package cn.itcast;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.Set;
  5. class Student {
  6. private String name;
  7. private int age;
  8. public Student() {
  9. super();
  10. }
  11. public Student(String name, int age) {
  12. super();
  13. this.name = name;
  14. this.age = age;
  15. }
  16. public String getName() {
  17. return name;
  18. }
  19. public void setName(String name) {
  20. this.name = name;
  21. }
  22. public int getAge() {
  23. return age;
  24. }
  25. public void setAge(int age) {
  26. this.age = age;
  27. }
  28. }
  29. /*
  30. * 黑马程序员
  31. * bj 北京校区
  32. * jc 基础班
  33. * 林青霞 27
  34. * 风清扬 30
  35. * jy 就业班
  36. * 赵雅芝 28
  37. * 武鑫 29
  38. * sh 上海校区
  39. * jc 基础班
  40. * 郭美美 20
  41. * 犀利哥 22
  42. * jy 就业班
  43. * 罗玉凤 21
  44. * 马征 23
  45. * gz 广州校区
  46. * jc 基础班
  47. * 王力宏 30
  48. * 李静磊 32
  49. * jy 就业班
  50. * 郎朗 31
  51. * 柳岩 33
  52. * xa 西安校区
  53. * jc 基础班
  54. * 范冰冰 27
  55. * 刘意 30
  56. * jy 就业班
  57. * 李冰冰 28
  58. * 张志豪 29
  59. */
  60. public class HashMapDemo {
  61. public static void main(String[] args) {
  62. // 创建大集合
  63. HashMap<String, HashMap<String, ArrayList<Student>>> czbkMap = new HashMap<String, HashMap<String, ArrayList<Student>>>();
  64. // 北京校区数据
  65. HashMap<String, ArrayList<Student>> bjCzbkMap = new HashMap<String, ArrayList<Student>>();
  66. ArrayList<Student> array1 = new ArrayList<Student>();
  67. Student s1 = new Student("林青霞", 27);
  68. Student s2 = new Student("风清扬", 30);
  69. array1.add(s1);
  70. array1.add(s2);
  71. ArrayList<Student> array2 = new ArrayList<Student>();
  72. Student s3 = new Student("赵雅芝", 28);
  73. Student s4 = new Student("武鑫", 29);
  74. array2.add(s3);
  75. array2.add(s4);
  76. bjCzbkMap.put("基础班", array1);
  77. bjCzbkMap.put("就业班", array2);
  78. czbkMap.put("北京校区", bjCzbkMap);
  79. // 西安校区数据
  80. HashMap<String, ArrayList<Student>> xaCzbkMap = new HashMap<String, ArrayList<Student>>();
  81. ArrayList<Student> array3 = new ArrayList<Student>();
  82. Student s5 = new Student("范冰冰", 27);
  83. Student s6 = new Student("刘意", 30);
  84. array3.add(s5);
  85. array3.add(s6);
  86. ArrayList<Student> array4 = new ArrayList<Student>();
  87. Student s7 = new Student("李冰冰", 28);
  88. Student s8 = new Student("张志豪", 29);
  89. array4.add(s7);
  90. array4.add(s8);
  91. xaCzbkMap.put("基础班", array3);
  92. xaCzbkMap.put("就业班", array4);
  93. czbkMap.put("西安校区", xaCzbkMap);
  94. // 遍历集合
  95. Set<String> czbkMapSet = czbkMap.keySet();
  96. for (String czbkMapKey : czbkMapSet) {
  97. System.out.println(czbkMapKey);
  98. HashMap<String, ArrayList<Student>> czbkMapValue = czbkMap
  99. .get(czbkMapKey);
  100. Set<String> czbkMapValueSet = czbkMapValue.keySet();
  101. for (String czbkMapValueKey : czbkMapValueSet) {
  102. System.out.println("\t" + czbkMapValueKey);
  103. ArrayList<Student> czbkMapValueValue = czbkMapValue
  104. .get(czbkMapValueKey);
  105. for (Student s : czbkMapValueValue) {
  106. System.out.println("\t\t" + s.getName() + "---"
  107. + s.getAge());
  108. }
  109. }
  110. }
  111. }
  112. }

运行结果:

Map接口 - 图2