一、概述。
1.Map是一种接口,在JAVA集合框架中是以一种非常重要的集合。
2.Map一次添加一对元素,所以又称为“双列集合”(Collection一次添加一个元素,所以又称为“单列集合”)
3.Map集合中存放的是一个一个的键值对,集合中存放的元素必须保证键的唯一性。
二、常用方法。
1.添加

 V put(K key, V value)
          将指定的值与此映射中的指定键关联(可选操作)。

该方法的作用就是向集合中添加一个键值对,并返回一个值;如果键存在,则返回对应的旧值,并以新值取代之;如果键不存在则返回null。所以该方法也是修改的方法。

void putAll(Map<? extends K,? extends V> m)
          从指定映射中将所有映射关系复制到此映射中(可选操作)。

该方法功能略,但注意泛型上限的使用。比较Collection方法:

 boolean addAll(Collection<? extends E> c)
          将指定
collection 中的所有元素都添加到此 collection 中(可选操作)。

2.删除

 V remove(Object key)
          如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。

该方法根据键删除一个键值对,并返回值。如果没有这个键值对,将返回null。

 void clear()
          从此映射中移除所有映射关系(可选操作)。

该方法功能就是清空集合。
3.判断

 boolean containsKey(Object key)
          如果此映射包含指定键的映射关系,则返回 true
 boolean containsValue(Object value)

          如果此映射将一个或多个键映射到指定值,则返回 true

这两个方法,前者判断是否存在指定键,后者判断是否存在指定值。

 boolean isEmpty()
          如果此映射未包含键-值映射关系,则返回 true

该方法用于判断该Map集合是否为空集合。
4.获取。

 V get(Object key)
          返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null
 int size()
          返回此映射中的键-值映射关系数。

这两个方法,前者根据指定的键获取对应的值,如果集合中没有指定的键,则返回null;后者获取键值对的个数。

以上的方法为基本方法,重点方法在下面。

三、重点:Map集合的四种遍历方式。

1.第一种遍历方式:使用keySet方法。

 Set<K> keySet()
          返回此映射中包含的键的 Set 视图。

该方法会返回一个包含所有键的Set集合。

遍历过程:先得到所有键的集合,遍历集合,根据键得到所有的值。

  1. package p01.traverseDemo01.keySetDemo;
  2.  
  3. import java.util.HashMap;
  4. import java.util.Iterator;
  5. import java.util.Map;
  6. import java.util.Set;
  7.  
  8. public class KeySetDemo {
  9.  
  10. public static void main(String[] args) {
  11. Demo01();
  12. }
  13.  
  14. private static void Demo01() {
  15. Map<Integer,String>map=new HashMap<Integer,String>();
  16. map.put(1, "wangcai");
  17. map.put(2, "xiaoqiang");
  18. map.put(3, "xiaoming");
  19.  
  20. Set<Integer>set=map.keySet();
  21. for(Iterator<Integer>it=set.iterator();it.hasNext();)
  22. {
  23. Integer key=it.next();
  24. String value=map.get(key);
  25. System.out.println(key+":"+value);
  26. }
  27.  
  28. }
  29.  
  30. }

应当注意,结果是无序的,这是因为采用了HashMap作为示例,HashMap底层的数据结构是哈希表,存储元素的时候有自己的规则,所以无序。

2.第二种遍历方式:使用entrySet方法。

 Set<Map.Entry<K,V>> entrySet()
          返回此映射中包含的映射关系的 Set 视图。

此方法返回值也是一个Set集合,但是存储的内容是Map.Entry对象。Map.Entry是什么东西?

JDK1.6API的解释如下:

嵌套类摘要
static interface Map.Entry<K,V>
          映射项(键-值对)。

虽然API的解释是“嵌套类”,但是Map是一个接口,Entry也是一个接口,事实上Map.Entry是Map的一个内部静态接口。

该接口封装了几个方法,用于操作一个键值对,注意,是一个,因为它仅仅对一个键值对进行封装(确切的说是对操作每个键值对的方法进行了封装,每个键值对对应着一个Map.Entry对象)。

Map.Entry接口的方法如下:

方法摘要
 boolean equals(Object o)
          比较指定对象与此项的相等性。
 K getKey()

          返回与此项对应的键。
 V getValue()

          返回与此项对应的值。
 int hashCode()

          返回此映射项的哈希码值。
 V setValue(V value)

          用指定的值替换与此项对应的值(可选操作)。

以上方法中,最常用的是getKey方法和getValue方法。

遍历过程:首先拿到每一个键值对对象Map.Entry的集合,再通过遍历集合拿到所有的键值对。

  1. package p01.traverseDemo01.keySetDemo;
  2.  
  3. import java.util.HashMap;
  4. import java.util.Iterator;
  5. import java.util.Map;
  6. import java.util.Set;
  7.  
  8. public class KeySetDemo {
  9.  
  10. public static void main(String[] args) {
  11. Demo01();
  12. }
  13.  
  14. private static void Demo01() {
  15. Map<Integer,String>map=new HashMap<Integer,String>();
  16. map.put(1, "wangcai");
  17. map.put(3, "xiaoming");
  18. map.put(2, "xiaoqiang");
  19.  
  20. Set<Integer>set=map.keySet();
  21. for(Iterator<Integer>it=set.iterator();it.hasNext();)
  22. {
  23. Integer key=it.next();
  24. String value=map.get(key);
  25. System.out.println(key+":"+value);
  26. }
  27.  
  28. }
  29.  
  30. }

3.第三种遍历方式:使用values方法。

 Collection<V> values()
          返回此映射中包含的值的 Collection 视图。

此种方法可以返回值的Collection集合,比较返回值,第一种方式使用keySet方法,返回值类型是Set集合,这里为什么不是Set集合?

解析:Map中键是唯一的,所以使用Set集合存储,而值可以重复,所以使用Collection集合存储。

  1. package p01.traverseDemo03.valuesDemo;
  2.  
  3. import java.util.Collection;
  4. import java.util.HashMap;
  5. import java.util.Iterator;
  6. import java.util.Map;
  7. import java.util.Set;
  8.  
  9. public class ValuesDemo {
  10.  
  11. public static void main(String[] args) {
  12. Demo01();
  13. }
  14.  
  15. private static void Demo01() {
  16. Map<Integer,String>map=new HashMap<Integer,String>();
  17. map.put(1, "wangcai");
  18. map.put(3, "xiaoming");
  19. map.put(2, "xiaoqiang");
  20.  
  21. Collection<String>coll=map.values();
  22. for(Iterator<String>it=coll.iterator();it.hasNext();)
  23. {
  24. String value=it.next();
  25. System.out.println(value);
  26. }
  27.  
  28. }
  29.  
  30. }

4.第四种遍历方式:使用增强型for循环间接遍历。

  1. package p11.ArraysDemo.p01.ExtendForCircle;
  2.  
  3. import java.util.Collection;
  4. import java.util.HashMap;
  5. import java.util.Map;
  6. import java.util.Set;
  7.  
  8. /**
  9. * 使用增强型for循环实现Map的三种遍历方式
  10. * @author kuangdaoyizhimei
  11. *
  12. */
  13. public class ExtendForCircle {
  14.  
  15. public static void main(String[] args) {
  16. Map<Integer,String>map=new HashMap<Integer,String>();
  17. map.put(1, "xiaoqiang");
  18. map.put(2, "zhangsan");
  19. map.put(3, "lisi");
  20. map.put(4, "wangwu");
  21. Function1(map);
  22. Function2(map);
  23. Function3(map);
  24. }
  25.  
  26. private static void Function3(Map<Integer, String> map) {
  27. Set<Map.Entry<Integer, String>>set=map.entrySet();
  28. for(Map.Entry<Integer, String>kv:set)
  29. {
  30. Integer key=kv.getKey();
  31. String value=kv.getValue();
  32. System.out.println("Key:"+key+"\tvalue:"+value);
  33. }
  34. }
  35.  
  36. private static void Function2(Map<Integer, String> map) {
  37. Collection<String>list=map.values();
  38. for(String val:list)
  39. {
  40. System.out.println(val);
  41. }
  42. System.out.println();
  43. System.out.println();
  44. }
  45.  
  46. private static void Function1(Map<Integer, String> map) {
  47. Set<Integer>set=map.keySet();
  48. for(Integer i:set)
  49. {
  50. System.out.println(i+":"+map.get(i));
  51. }
  52. System.out.println();
  53. System.out.println();
  54. }
  55.  
  56. }

四、Map集合的常见子类。

  1. public class Hashtable<K,V>extends Dictionary<K,V>implements Map<K,V>, Cloneable, Serializable
  1. public class HashMap<K,V>extends AbstractMap<K,V>implements Map<K,V>, Cloneable, Serializable
  1. public class TreeMap<K,V>extends AbstractMap<K,V>implements NavigableMap<K,V>, Cloneable, Serializable

这三者有些区别:

HashTable:内部结构是哈希表,JDK1.0就出现了(JDK1.0出现的单列集合只有Vector,双列集合只有HashTable),是同步的。不允许null作为键值。
HashMap:内部结构是哈希表,是非同步的。允许null作为键值。
TreeMap:内部结构是一棵红黑树,可以对Map集合中的键进行排序。

需要注意的是Set集合的实现依赖于HashMap集合----HashMap将值统一为一个对象而只关注键的操作即可实现Set集合中元素的唯一性。

HashTable有一个子类应当特别注意:Properties

  1. public class Propertiesextends Hashtable<Object,Object>

这个类用来存储键值对型的文件配置信息,它和Io技术相结合才能发挥出它的优势。

1.HashMap类。

Hash代表着底层的实现使用了哈希表,所以如果使用自定义对象作为键,应当注意重写类的hashCode方法和equals方法。

示例:使用HashMap存储自定义对象Student和其归属地NativePlace,并遍历。

  1. package p02.SubClassDemo01.HashMapDemo;
  2.  
  3. import java.util.HashMap;
  4. import java.util.Iterator;
  5. import java.util.Map;
  6.  
  7. class Student
  8. {
  9. private String name;
  10. private int age;
  11. @Override
  12. public int hashCode() {
  13. final int prime = 31;
  14. int result = 1;
  15. result = prime * result + age;
  16. result = prime * result + ((name == null) ? 0 : name.hashCode());
  17. return result;
  18. }
  19. @Override
  20. public boolean equals(Object obj) {
  21. if (this == obj)
  22. return true;
  23. if (obj == null)
  24. return false;
  25. if (getClass() != obj.getClass())
  26. return false;
  27. Student other = (Student) obj;
  28. if (age != other.age)
  29. return false;
  30. if (name == null) {
  31. if (other.name != null)
  32. return false;
  33. } else if (!name.equals(other.name))
  34. return false;
  35. return true;
  36. }
  37. public Student(String name, int age) {
  38. super();
  39. this.name = name;
  40. this.age = age;
  41. }
  42. public Student() {
  43. super();
  44. }
  45. public String getName() {
  46. return name;
  47. }
  48. public void setName(String name) {
  49. this.name = name;
  50. }
  51. public int getAge() {
  52. return age;
  53. }
  54. public void setAge(int age) {
  55. this.age = age;
  56. }
  57. }
  58.  
  59. class NativePlace
  60. {
  61. private String province;
  62. private String city;
  63. public NativePlace(String province, String city) {
  64. super();
  65. this.province = province;
  66. this.city = city;
  67. }
  68. public NativePlace() {
  69. super();
  70. }
  71. public String getProvince() {
  72. return province;
  73. }
  74. public void setProvince(String province) {
  75. this.province = province;
  76. }
  77. public String getCity() {
  78. return city;
  79. }
  80. public void setCity(String city) {
  81. this.city = city;
  82. }
  83. }
  84. public class HashMapDemo {
  85.  
  86. public static void main(String[] args) {
  87. Demo01();
  88. }
  89.  
  90. private static void Demo01() {
  91. HashMap<Student,NativePlace>hm=new HashMap<Student,NativePlace>();
  92. hm.put(new Student("wangwu",25), new NativePlace("hubei","suizhou"));
  93. hm.put(new Student("zhaoliu",26), new NativePlace("hunan","chagnsha"));
  94. hm.put(new Student("zhangsan",23), new NativePlace("shandong","zibo"));
  95. hm.put(new Student("lisi",24), new NativePlace("shandong","weifang"));
  96.  
  97. //重复添加无效
  98. hm.put(new Student("wangwu",25), new NativePlace("hubei","suizhou"));
  99. hm.put(new Student("zhaoliu",26), new NativePlace("hunan","chagnsha"));
  100. hm.put(new Student("zhangsan",23), new NativePlace("shandong","zibo"));
  101. hm.put(new Student("lisi",24), new NativePlace("shandong","weifang"));
  102.  
  103. for(Iterator<Map.Entry<Student,NativePlace>>it=hm.entrySet().iterator();it.hasNext();)
  104. {
  105. Map.Entry<Student, NativePlace>me=it.next();
  106. Student stu=me.getKey();
  107. NativePlace np=me.getValue();
  108. System.out.println(stu.getName()+":"+np.getProvince()+"."+np.getCity());
  109. }
  110.  
  111. }
  112.  
  113. }

2.TreeMap类。

TreeMap类底层使用了排序树,如果使用自定义对象作为键,就必须实现Comparable接口;如果没有实现这个接口,则必须使用比较器作为HashTree初始化对象的参数。

现在将上面的代码中Student的hashCode方法以及equals方法删掉,同时实现接口Comparable,重写compareTo方法,以达到按照年龄排序的目的。

  1. package p02.SubClassDemo02.TreeMapDemo;
  2.  
  3. import java.util.Iterator;
  4. import java.util.Map;
  5. import java.util.TreeMap;
  6.  
  7. class Student implements Comparable<Student>
  8. {
  9. private String name;
  10. private int age;
  11. public Student(String name, int age) {
  12. super();
  13. this.name = name;
  14. this.age = age;
  15. }
  16. public Student() {
  17. super();
  18. }
  19. public String getName() {
  20. return name;
  21. }
  22. public void setName(String name) {
  23. this.name = name;
  24. }
  25. public int getAge() {
  26. return age;
  27. }
  28. public void setAge(int age) {
  29. this.age = age;
  30. }
  31. @Override
  32. public int compareTo(Student o) {
  33. int temp=this.age-o.getAge();
  34. return temp==0?this.name.compareTo(o.getName()):temp;
  35. }
  36. }
  37.  
  38. class NativePlace
  39. {
  40. private String province;
  41. private String city;
  42. public NativePlace(String province, String city) {
  43. super();
  44. this.province = province;
  45. this.city = city;
  46. }
  47. public NativePlace() {
  48. super();
  49. }
  50. public String getProvince() {
  51. return province;
  52. }
  53. public void setProvince(String province) {
  54. this.province = province;
  55. }
  56. public String getCity() {
  57. return city;
  58. }
  59. public void setCity(String city) {
  60. this.city = city;
  61. }
  62. }
  63.  
  64. public class TreeMapDemo {
  65.  
  66. public static void main(String[] args) {
  67. Demo01();
  68. }
  69.  
  70. private static void Demo01() {
  71. TreeMap<Student,NativePlace>hm=new TreeMap<Student,NativePlace>();
  72. hm.put(new Student("wangwu",25), new NativePlace("hubei","suizhou"));
  73. hm.put(new Student("zhaoliu",26), new NativePlace("hunan","chagnsha"));
  74. hm.put(new Student("zhangsan",23), new NativePlace("shandong","zibo"));
  75. hm.put(new Student("lisi",24), new NativePlace("shandong","weifang"));
  76.  
  77. //重复添加无效
  78. hm.put(new Student("wangwu",25), new NativePlace("hubei","suizhou"));
  79. hm.put(new Student("zhaoliu",26), new NativePlace("hunan","chagnsha"));
  80. hm.put(new Student("zhangsan",23), new NativePlace("shandong","zibo"));
  81. hm.put(new Student("lisi",24), new NativePlace("shandong","weifang"));
  82.  
  83. for(Iterator<Map.Entry<Student,NativePlace>>it=hm.entrySet().iterator();it.hasNext();)
  84. {
  85. Map.Entry<Student, NativePlace>me=it.next();
  86. Student stu=me.getKey();
  87. NativePlace np=me.getValue();
  88. System.out.println(stu.getName()+":"+stu.getAge()+"----"+np.getProvince()+"."+np.getCity());
  89. }
  90.  
  91. }
  92.  
  93. }

运行可以看出重复添加的元素仍然没有添加进去,因为TreeSet判断元素是否相同的依据是compareTo方法的返回值而不是hashCode方法以及equals方法。

如果现在有了新的需求,需要按照新的规则对学生进行排序,则创建比较器,按照比较器中的新规则进行排序。

  1. package p02.SubClassDemo02.TreeMapDemo;
  2.  
  3. import java.util.Comparator;
  4. import java.util.Iterator;
  5. import java.util.Map;
  6. import java.util.TreeMap;
  7.  
  8. class Student implements Comparable<Student>
  9. {
  10. private String name;
  11. private int age;
  12. public Student(String name, int age) {
  13. super();
  14. this.name = name;
  15. this.age = age;
  16. }
  17. public Student() {
  18. super();
  19. }
  20. public String getName() {
  21. return name;
  22. }
  23. public void setName(String name) {
  24. this.name = name;
  25. }
  26. public int getAge() {
  27. return age;
  28. }
  29. public void setAge(int age) {
  30. this.age = age;
  31. }
  32. @Override
  33. public int compareTo(Student o) {
  34. int temp=this.age-o.getAge();
  35. return temp==0?this.name.compareTo(o.getName()):temp;
  36. }
  37. }
  38.  
  39. class NativePlace
  40. {
  41. private String province;
  42. private String city;
  43. public NativePlace(String province, String city) {
  44. super();
  45. this.province = province;
  46. this.city = city;
  47. }
  48. public NativePlace() {
  49. super();
  50. }
  51. public String getProvince() {
  52. return province;
  53. }
  54. public void setProvince(String province) {
  55. this.province = province;
  56. }
  57. public String getCity() {
  58. return city;
  59. }
  60. public void setCity(String city) {
  61. this.city = city;
  62. }
  63. }
  64.  
  65. class CompareByName implements Comparator<Student>
  66. {
  67. @Override
  68. public int compare(Student o1, Student o2) {
  69. int temp=o1.getName().compareTo(o2.getName());
  70. return temp==0?o1.getAge()-o2.getAge():temp;
  71. }
  72. }
  73. public class TreeMapDemo {
  74. public static void main(String[] args) {
  75. Demo01();
  76. }
  77.  
  78. private static void Demo01() {
  79. TreeMap<Student,NativePlace>hm=new TreeMap<Student,NativePlace>(new CompareByName());
  80. hm.put(new Student("wangwu",25), new NativePlace("hubei","suizhou"));
  81. hm.put(new Student("zhaoliu",26), new NativePlace("hunan","chagnsha"));
  82. hm.put(new Student("zhangsan",23), new NativePlace("shandong","zibo"));
  83. hm.put(new Student("lisi",24), new NativePlace("shandong","weifang"));
  84.  
  85. //重复添加无效
  86. hm.put(new Student("wangwu",25), new NativePlace("hubei","suizhou"));
  87. hm.put(new Student("zhaoliu",26), new NativePlace("hunan","chagnsha"));
  88. hm.put(new Student("zhangsan",23), new NativePlace("shandong","zibo"));
  89. hm.put(new Student("lisi",24), new NativePlace("shandong","weifang"));
  90.  
  91. for(Iterator<Map.Entry<Student,NativePlace>>it=hm.entrySet().iterator();it.hasNext();)
  92. {
  93. Map.Entry<Student, NativePlace>me=it.next();
  94. Student stu=me.getKey();
  95. NativePlace np=me.getValue();
  96. System.out.println(stu.getName()+":"+stu.getAge()+"----"+np.getProvince()+"."+np.getCity());
  97. }
  98.  
  99. }
  100.  
  101. }

可以看到,通过使用比较器,确实达到了按照名字字典序排序的目的,这也证明了如果使用比较器,则原来的自然比较方式将会无效。

3.LinkedHashMap类。

此类的是HashMap的子类,与HashMap相比,该类实现了“有序”,即插入和取出的顺序一致。该类在很多时候都能发挥出很大的作用。

【JAVA集合框架之Map】的更多相关文章

  1. Java集合框架之map

    Java集合框架之map. Map的主要实现类有HashMap,LinkedHashMap,TreeMap,等等.具体可参阅API文档. 其中HashMap是无序排序. LinkedHashMap是自 ...

  2. Java集合框架之Map接口浅析

    Java集合框架之Map接口浅析 一.Map接口综述: 1.1java.util.Map<k, v>简介 位于java.util包下的Map接口,是Java集合框架的重要成员,它是和Col ...

  3. Java集合框架中Map接口的使用

    在我们常用的Java集合框架接口中,除了前面说过的Collection接口以及他的根接口List接口和Set接口的使用,Map接口也是一个经常使用的接口,和Collection接口不同,Map接口并不 ...

  4. java集合框架07——Map架构与源代码分析

    前几节我们对Collection以及Collection中的List部分进行了分析,Collection中还有个Set,因为Set是基于Map实现的,所以这里我们先分析Map,后面章节再继续学习Set ...

  5. Java 集合框架之 Map

    Hashtable Hashtable 的实例有两个参数影响其性能:初始容量 和加载因子.容量 是哈希表中桶 的数量,初始容量就是哈希表创建时的容量.注意,哈希表的状态为 open:在发生“哈希冲突” ...

  6. 【转】Java集合框架List,Map,Set等全面介绍

    原文网址:http://android.blog.51cto.com/268543/400557 Java Collections Framework是Java提供的对集合进行定义,操作,和管理的包含 ...

  7. 34、Java集合框架List,Map,Set等全面介绍(转载)

      Java Collections Framework是Java提供的对集合进行定义,操作,和管理的包含一组接口,类的体系结构.   Java集合框架的基本接口/类层次结构: java.util.C ...

  8. Java集合框架List,Map,Set等全面介绍

    Java集合框架的基本接口/类层次结构: java.util.Collection [I]+--java.util.List [I]   +--java.util.ArrayList [C]   +- ...

  9. 我所理解Java集合框架的部分的使用(Collection和Map)

    所谓集合,就是和数组类似——一组数据.java中提供了一些处理集合数据的类和接口,以供我们使用. 由于数组的长度固定,处理不定数量的数据比较麻烦,于是就有了集合. 以下是java集合框架(短虚线表示接 ...

随机推荐

  1. android之inflater用法

    在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById().不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例 ...

  2. POJ 2631 DFS+带权无向图最长路径

    http://poj.org/problem?id=2631 2333水题, 有一个小技巧是说随便找一个点作为起点, 找到这个点的最远点, 以这个最远点为起点, 再次找到的最远点就是这个图的最远点 证 ...

  3. HDU 2860 并查集

    http://acm.hdu.edu.cn/showproblem.php?pid=2860 n个旅,k个兵,m条指令 AP 让战斗力为x的加入y旅 MG x旅y旅合并为x旅 GT 报告x旅的战斗力 ...

  4. 浏览器js自动查表脚本

    javascript: void((function() {$.get("", {wen: "880350384879600241",action: " ...

  5. FWT

    Fast Walsh-Hadamard Transform .pre 今天本来想看FFT的应用的...翻翻picks的博客发现了好东西Fast Walsh-Hadamard Transform,感觉挺 ...

  6. WinForm多线程编程简单Demo

    需要搭建一个可以监控报告生成的CS(WinForm)工具,即CS不断Run,执行获取数据生成报告,经过研究和实践,选择了使用"WinForm多线程编程"的解决方案.当然参考了园中相 ...

  7. JSON代码格式化 进行查询筛选

    JSON是前端编程经常用到的格式,对于PHP或者Python,解析JSON都不是什么大事,尤其是PHP的json_encode和json_decode,干的相当的漂亮.Linux下也有处理处理JSON ...

  8. 一个iOS 框架介绍:MKNetworkKit

    http://blog.csdn.net/kmyhy/article/details/12276287 http://blog.csdn.net/mobailwang/article/details/ ...

  9. [转]Java连接各种数据库的方法

    //MySQL:       String Driver="com.mysql.jdbc.Driver";   //驱动程序     String URL="jdbc:m ...

  10. POJ 2367 (裸拓扑排序)

    http://poj.org/problem?id=2367 题意:给你n个数,从第一个数到第n个数,每一行的数字代表排在这个行数的后面的数字,直到0. 这是一个特别裸的拓扑排序的一个题目,拓扑排序我 ...