Java基础---集合框架四(Map)

2015-4-19

一、Map集合

1、Map接口概述

     将键映射到值的对象

     一个映射不能包含重复的键

     每个键最多只能映射到一个值

2、Map接口和Collection接口的不同

              Map是双列的,Collection是单列的

              Map的键唯一,Collection的子体系Set是唯一的

              Map集合的数据结构值针对键有效,跟值无关

      Collection集合的数据结构是针对元素有效

     二者的区别:

              Collection集合:

                       单个元素:单身

                       Collection中的Set集合中,元素唯一

              Map:成对元素:夫妻,通常叫做键值对

                       Map集合中的键唯一,值可以重复

3、接口成员方法

添加功能:

     V put(K key,V value) 添加键值与值

删除功能:

     V remove(Object key) 删除一个键值的内容

     void clear() 清除内容

判断功能:

     boolean containsKey(Objectkey) 是否包含此键值

     booleancontainsValue(Object value) 是否包含此值

     boolean isEmpty() 是否为空

     int size() 集合的大小

     V get(Object key) 获取键值

获取功能:

     Set<K> keySet() 获取键值key的Set集合

     Collection<V>values()

     Set<Map.Entry<K,V>>entrySet()获得一个包含多个键值对元素的Set集合

举例:map集合遍历

     遍历方式一:

                     1: 键找值  通过指定的键,获取对应的值

                         a: 获取到Map集合中所有的键的Set集合

                         b: 遍历键的集合,得到每一个键

                         c: 通过当前的键,获取对应的值 

          //创建Map集合
              Map<String,String>map = new HashMap<String,String>();
              //添加元素
              map.put("谢霆锋", "张柏芝");
              map.put("李亚鹏", "王菲");
              map.put("汪峰", "章子怡");
              //遍历
              //a: 获取到Map集合中所有的键的Set集合
              Set<String>keys = map.keySet();
              //b: 遍历键的集合,得到每一个键
              for (String key :keys) {
                       //c: 通过当前的键,获取对应的值
                       Stringvalue = map.get(key);  
                       //显示
                       System.out.println(key +"--" + value );
              }

  遍历方式二:

              通过键值对元素对象,找对应的键,找对应的值    结婚证方式

                       a:获取所有键值对元素的Set集合

                       b:遍历Set集合,得到每一个键值对元素对象

                       c:通过键值对元素对象,获取键,获取值

方法:

   Set<Map.Entry<K,V>> entrySet(): 获得一个包含多个键值对元素的Set集合

    Map.Entry<K,V>  等价    结婚证<男的,女的>

    class 结婚证<男的,女的> {

         private 男的 man;

         private 女的 woman;

         public 男的   getMan(){

                  return man;

         }

         public 女的  getWoman(){

                  return woman;

          }

    }

   Set<Map.Entry<K,V>> entrySet = map.entrySet();

    Set<   结婚证<男的,女的>> entrySet = map.entrySet();

     代码实现:

 <span style="white-space:pre">	</span>//创建Map集合
              Map<String,String>map = new HashMap<String,String>();
              //添加元素
              map.put("谢霆锋", "张柏芝");
              map.put("李亚鹏", "王菲");
              map.put("汪峰", "章子怡");
              //遍历
              //a:获取所有键值对元素的Set集合
              Set<Map.Entry<String,String>>entrySet = map.entrySet();
              //b:遍历Set集合,得到每一个键值对元素对象
              for (Map.Entry<String,String> entry : entrySet) {
                       //c:通过键值对元素对象,获取键,获取值
                       Stringkey = entry.getKey();//获取键
                       Stringvalue = entry.getValue();//获取值
                      
                       System.out.println(key+"--"+ value);
              }

Entry接口的结构:

Map.Entry 接口

interface Map<K,V> {

     interface Entry<K,V>{

              K getKey();

              V getValue();

              V setValue();

     }

}

class HashMap implements Map{

     static classEntry<K,V> implements Map.Entry<K,V>

              K getKey(){

                       ...

              }

              V getValue(){

                       ...

              }

              V setValue(){

                       ...

              }

     }

    

}

二、HashMap集合

1、概述

  底层:哈希表结构

             存储允许使用 null 值和 null 键

             线程不同步-- 效率高-- 不安全

           Map集合中的键要求保证唯一, 那么,HashMap集合中,如何保证 键 的唯一呢?

           重写 hashCode() 与 equals()方法

     注意:这里面的唯一指的是 键唯一, 针对键有效,  与值无关

2、案例

  举例一:使用HashSet集合存储字符串,并遍历

  方式一:

	//创建HashMap集合
              HashMap<String,String>hm = new HashMap<String,String>();
             
              //添加键值对元素到集合
              hm.put("谢霆锋", "张柏芝");
              hm.put("李亚鹏", "王菲");
              hm.put("汪峰", "章子怡");
             
              //遍历方式1  键找值
              //a: 获取到Map集合中所有的键
              Set<String>keys = hm.keySet();
              //b: 获取到每一个键
              for (String key :keys) {
                       //c: 通过键,找对应的值
                       Stringvalue = hm.get(key);
                       System.out.println(key+"---"+value);
              }

     方式二:

         //创建HashMap集合
              HashMap<String,String>hm = new HashMap<String,String>();
             
              //添加键值对元素到集合
              hm.put("谢霆锋", "张柏芝");
              hm.put("李亚鹏", "王菲");
              hm.put("汪峰", "章子怡");
    
              //遍历方式2 键值对  找键 找值
              //a: 获取所有的键值对元素对象
              Set<Entry<String, String>> entrySet =hm.entrySet();
              //b: 获取到每一个键值对元素对象
              for(Entry<String, String> entry: entrySet) {
              //c: 通过当前的键值对元素对象,获取键,获取值
              String key =entry.getKey();// 获取键
              String value =entry.getValue(); //获取值
              System.out.println(key+"---"+value);
              }

  举例二:键为String,值为Student         

	//创建集合对象
              HashMap<String,Student>map = new HashMap<String,Student>();
              //添加元素
              Student s1 = newStudent("周瑜", 28);
              Student s2 = newStudent("小乔", 18);
              Student s3 = newStudent("大乔", 19);
             
              map.put("itcast001",s1);
              map.put("itcast002",s2);
              map.put("itcast003",s3);
              map.put("itcast004",s1);
             
              //遍历
              //方式1 键找值
              Set<String>keys = map.keySet();
              //获取到每一个键
              for (String key :keys) {
                       //通过当前的key, 获取对应的值 Student
                       Students = map.get(key);
                       System.out.println(key+"---" + s.getName() +"---"+ s.getAge());
              }

  举例三:键为Person,值为String

  注意:

  如果HashMap集合中的键是自定义类对象,那么需要重写hashCode()和equals()  

	//创建集合对象
              HashMap<Person,String>map = new HashMap<Person,String>();
              //添加元素
              Person s1 = newPerson("周瑜", 28);
              Person s2 = newPerson("小乔", 18);
              Person s3 = newPerson("大乔", 19);
 
              map.put(s1,"itcast001");
              map.put(s2,"itcast002");
              map.put(s3,"itcast003");
              map.put(s3,"itcast004");// 由于s3 键已存储,  用itcast004 替换 itcast003
             
              //遍历  键值对  找键找值
              Set<Entry<Person,String>> entrySet = map.entrySet();
              //获取到每一个键值对元素对象
              for (Entry<Person,String> entry : entrySet) {
                       Personkey = entry.getKey();
                       Stringvalue = entry.getValue();
                      
                       System.out.println(value+"---"+ key.getName() +"---"+key.getAge() );
              }

三、LinkHashMap集合

1、概述

     底层:哈希表 + 链表

              有序(元素的存与取顺序一致)

              线程不同步 -- 效率高-- 不安全

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

2、案例:创建LinkHashMap集合对象遍历       

   //创建集合对象
              LinkedHashMap<String,String>map = new LinkedHashMap<String,String>();
              //添加元素到集合
              map.put("谢霆锋", "张柏芝");
              map.put("李亚鹏", "王菲");
              map.put("汪峰", "章子怡");
             
              //遍历   键找值
              Set<String>keys = map.keySet();
              for (String key :keys) {
                       //键找 值
                       Stringvalue = map.get(key);
                       System.out.println(key+"---"+value);
              }

四、TreeMap集合

1、概述

      键是红黑树结构,可以保证键的排序和唯一性,实现不是同步的。

   TreeMap<K,V>

              底层:红黑树 (二叉树)

              线程不同步 -- 效率高-- 不安全

              TreeMap集合中如何保证键的唯一和排序的?

                       1:对键实现 自然排序接口 Comparable , 重写 compareTo(obj1)方法

                       2:  对键 实现比较器接口 Comparator, 重写compare(obj1,obj2)方法

举例一:使用TreeMap,遍历       

  <span style="white-space:pre">	</span>// 创建TreeMap集合对象
              TreeMap<String,String>map = new TreeMap<String,String>();
             
              // 添加元素到集合
              map.put("x谢霆锋", "张柏芝");
              map.put("l李亚鹏", "王菲");
              map.put("w汪峰", "章子怡");
             
              //遍历键值对 找键 找值方式
              Set<Entry<String,String>> entrySet = map.entrySet();
              //获取到每一个键值对元素对象
              for(Entry<String, String> entry : entrySet) {
                       //获取键
                       Stringkey = entry.getKey();
                       //获取值
                       Stringvalue = entry.getValue();
                       System.out.println(key+"---"+value);
              }

举例二:<Student, String>   

  //创建TreeMap集合对象,  同时实现比较器
       TreeMap<Student,String>map = new TreeMap<Student,String>(new
                       Comparator<Student>(){
                       @Override
                       publicint compare(Student s1, Student s2) {
                                 //名字
                                 intnum = s1.getName().compareTo(s2.getName());
                                 //年龄
                                 intresult = (num==0) ? (s1.getAge() - s2.getAge()) : num ;
                                 returnresult;
                       }
              });
             
              //添加元素到集合
              Student s1 = newStudent("z周瑜", 28);
              Student s2 = newStudent("x小乔", 18);
              Student s3 = newStudent("d大乔", 19);
              map.put(s1,"itcast001");
              map.put(s2,"itcast002");
              map.put(s3,"itcast003");
              map.put(s1,"itcast110");
              //遍历
              Set<Student>keys = map.keySet();
              //获取到每一个键
              for (Student key: keys) {
                       //键找 值
                       Stringvalue = map.get(key);
                       System.out.println(value+"---"+key.getName()+"---"+key.getAge() );
              }

五、集合的嵌套使用

     1、案例

  举例一:根据给定的字符串得出每个字母出现的次数

              格式:a(3)b(3)c(2)d(5)e(1)

        分析:

                     通过结果可以看出 字母与次数之间有对应关系,我们可以采用Map集合

                     又由于结果是一个有序的结果,我们最终决定采用 TreeMap集合

                     a(5)

                     TreeMap<Character, Integer>

                                                 a                1++ ++

                                                 b       1

 

                     1: 定义一个字符串   "aababcabcdabcde"

                     2:定义一个集合  TreeMap<Character, Integer> 用来存储字母与次数

                     3:遍历字符串,得到每一个字母

                     4:判断当前字母在集合中是否存在

                              存在:

                                       把当前字母 在集合中存储的次数获取出来,次数加1后,再存进去

                              不存在:

                                       把当前字母  与次数1 存进去       

                     5: 组装结果字符串  a(5)b(4)c(3)d(2)e(1)

                              通过遍历Map集合得到每一个键与值 ,然后拼装

  代码实现:           

	//1:定义一个字符串  "aababcabcdabcde"
              String str ="aababcabcdabcde";
             
              //2:定义一个集合  TreeMap<Character,Integer> 用来存储字母与次数
              TreeMap<Character,Integer> map = new TreeMap<Character, Integer>(); // 自然排序
             
              //3:遍历字符串,得到每一个字母
              for (int i =0;i< str.length(); i++) {
                       //得到每一个字母
                       char ch= str.charAt(i);
                       //4:判断当前字母在集合中是否存在
                       if(map.containsKey(ch)) {
                                 //把当前字母在集合中存储的次数获取出来, 次数加1后,再存进去
                                 intcount = map.get(ch);
                                 count++;
                                 map.put(ch,count);
                                
                       } else {
                                 //把当前字母  与次数1 存进去      
                                 map.put(ch,1);
                       }
              }
             
              //System.out.println(map);
              //5: 组装结果字符串  a(5)b(4)c(3)d(2)e(1)
              //通过遍历Map集合得到每一个键与值 ,然后拼装
              StringBuilder sb= new StringBuilder();
             
              //方式2 键值对 找键 找值
              Set<Entry<Character,Integer>> entrySet = map.entrySet();
              //得到每一个键值对元素
              for(Entry<Character, Integer> entry : entrySet) {
                       //找键  --- 字母
                       Characterc = entry.getKey();
                       //找值  --- 次数
                       Integern = entry.getValue();
                       sb.append(c).append("(").append(n).append(")");//a(5)
              }
              //打印结果
              System.out.println(sb.toString());

  案例二:HashMap嵌套HashMap

              czbk

                     (基础班)jc

                              01     张三

                              02     李四

                     (就业班)jy

                              01     王五

                              02     赵六

           分析:

           1: 创建基础班HashMap集合    HashMap<String, String>

                                                                             学号                    姓名

           2: 向基础班集合添加元素

           3: 创建就业班HashMap集合    HashMap<String,String>

                                                                             学号                    姓名

           4: 向就业班集合添加元素

           5: 创建传智播客HashMap集合        HashMap<String, HashMap<String,String> >

                                                                         基础班                     基础班HashMap集合

                                                                             就业班                       就业班HashMap集合

           6: 向传智播客HashMap 添加元素

           7: 遍历

     代码实现:         

         //1: 创建基础班HashMap集合    HashMap<String, String>
              HashMap<String,String> jc = new HashMap<String, String>();
              //2: 向基础班集合添加元素
              jc.put("01","张三");
              jc.put("02","李四");
              //3: 创建就业班HashMap集合    HashMap<String, String>
              HashMap<String,String> jy = new HashMap<String, String>();
              //4: 向就业班集合添加元素
              jy.put("01","王五");
              jy.put("02","赵六");
             
              //5:创建传智播客HashMap集合    HashMap<String,HashMap<String, String> >
              HashMap<String,HashMap<String, String>> czbk = new HashMap<String,HashMap<String, String>>();
              //6:向传智播客HashMap 添加元素
              czbk.put("基础班", jc);
              czbk.put("就业班", jy);
             
              //7: 遍历
              //System.out.println(czbk);
             
              // 键找 值
              //所有的班级名称
              Set<String>classeNames = czbk.keySet();
              for (StringclasseName : classeNames) {
                       //每一个班级名称
                       System.out.println(classeName);
                       //通过班级名称,找到对应班级的所有学生信息
                       HashMap<String,String> students = czbk.get(classeName);
                       //获得当前班级中所有学生的学号
                       Set<String>ids = students.keySet();
                       //得到每一个学生的学号
                       for(String id : ids) {
                                 //通过学号获取对应姓名
                                 Stringname = students.get(id);
                                 System.out.println("\t"+id+ "---"+ name);
                       }
              }

2、面试题  ★★★

(1)HashMap和Hashtable的区别?

     HashMap:

  线程不同步--- 效率高--- 不安全

  存储的元素使用null键null值

  Hashtable

  线程同步—效率低---安全

  不能够使用null键null值作为元素

  代码举例:

 	HashMap<String,String>hashMap = new HashMap<String,String>();
              hashMap.put(null,"王朝");
              hashMap.put("itcast110",null);
              hashMap.put(null,null);
              System.out.println(hashMap);
             
              Hashtable<String,String>hashtable = new Hashtable<String,String>();
              //hashtable.put(null,"马汉");//NullPointerException
              //hashtable.put("itcast365",null);//NullPointerException
              //hashtable.put(null,null);//NullPointerException
             
              System.out.println(hashtable);

(2)List、Set、Map等接口是否都继承子Map接口

  Collection

           |-- List

           |--Set

  Map

       |--HashMap

       |--TreeMap

(3)你常见的集合类有哪些,都有什么方法?

              Collection

                       |- List

                                 |-ArrayList

                                 |-LinkedList

                                 |-Vector

                       |- Set

                                 |-HashSet

                                 |-TreeSet

                      

              Map

                       |-HashMap

                       |-TreeMap

                       |-Hashtable

六、Collection类

 1、概述

   针对集合操作的工具类

 2、成员方法

     public static <T>void sort(List<T> list) 排序

     public static <T>int binarySearch(List<?> list,T key) 二分查找

     public static <T> Tmax(Collection<?> coll) 最大值

     public static voidreverse(List<?> list) 反转

     public static voidshuffle(List<?> list) 随机打乱

     public static <T>boolean replaceAll(List<T> list, T oldVal, T newVal) 替换

  3、集合的结构

   集合

    |-- Collection

         |-- List

         |-- Set

|-- Map 

七、案例:通讯录实现

略。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值