Day18 --集合框架 Map集合 固定下边界

来源:互联网 发布:陕西广电网络是国企嘛 编辑:程序博客网 时间:2024/06/04 17:45
 a.
    Map
        概述
            * util包下,是双列集合的根接口,即方法都是抽象的
            * 表现形式是一个<K,V> 的一种映射关系,即一一对应的关系
                * K -- 此映射所维护键的类型
                * V -- 映射值的类型
            * 将键映射到值的对象
            * 一个映射不能包含重复的键
            * 每个键最多只能映射到一个值
            * 存取无序 --LinkedHashMap除外
            
        Map与Collection接口的不同
            * Map是双列集合的根接口,Collection是单列集合的根接口
            * Map是键唯一,Collection的子体系中Set是唯一   --map集合和Collection的子体系的set集合很像。
                * HashSet底层依赖的是map,二者底层都是哈希算法
            * Map集合的数据结构是值针对键有效,与值无关
            * Collection集合的数据结构是针对元素有效

b.
    Map集合的功能
        概述
            * 添加功能
                * V put(K key, V value); 添加元素
                    * 如果键是第一次存储,那就直接存储元素,返回null
                    * 如果键不是第一次存在,就用值代替原来的值,返回原来的值
            * 删除功能
                * void clear();    移除所有的键值对元素
                * V remove(Object key); 根据键删除值,并将值返回
            * 判断功能
                * boolean containsKey(Object key); 判断集合是否包含指定键
                * boolean containsKey(Object value); 判断集合是否包含指定值
                * boolean isEmpty(); 判断该集合是否为空
            * 获取功能
                * Set<Map.Entry<K,V>> entrySet();
                * V get(Object key); 根据键获取值
                * Set<K> keySet(); 获取集合中所有键的集合
                * Collection<V> values(); 获取集合中所有值的集合
            * 长度功能    
                * int size(); 返回集合中的键值对的个数

        
c.
    Map集合的遍历
        概述
            * 通过查询map集合的API发现没有Iterator的方法,那么双列集合该怎么遍历获取到元素呢?
            * map集合的遍历不能直接使用迭代器来完成。
            * map集合的遍历分为两种
                * --键找值
                    * 思路
                        * 获取所有键的集合     
                        * 使用遍历set集合的迭代器方式遍历键集合     
                        * 遍历键的集合,获取到每一个键  
                        * 根据键找值 
                        * 方式1 --使用迭代器
                              Set<String> keySet = map.keySet();
                             Iterator ir = keySet.iterator(); 
                              while(ir.hasNext){ //判断是否还有下一个键
                                 String key = ir.next(); //获取所有的键
                                 Integer value = map.get(key); //通过键找值
                             }
                        * 方式2 --使用增强for
                            for(String key : map.keySet()){ //获取所有的键的集合
                                Integer value = map.get(key); //通过键获取值
                                System.out.println(key+"..."+value);
                            }
                            
                * --键值对对象找键和值 
                    * 思路
                        * 获取所有键值对对象的集合  --Map.Entry<String, Integer>键值对对象
                        * 遍历键值对对象的集合,获取到每一个键值对对象
                        * 根据键值对对象找键和值
                    * 过程:
                            (将双列集合的键值对变成单列集合的键值对对象,然后遍历这个集合获取到每一个键值对对象,根据键值对对象获取到键和值)
                    * 注意:
                        Set<Map.Entry<String, Integer>> 
                        Map.Entry说明Entry是map的内部接口,将键和值封装成了Entry对象,并且存储到了Set集合中去 
                        这里的Map.Entry<String, Integer>>表示父类引用指向子类对象(子类对象:HashMap)
                        而Entry<String, Integer>>表示父类引用指向子类对象(子类对象:HashMap) 表示直接获取子类对象(子类对象:HashMap)


                        * 方式1  --通过键值对对象集合遍历迭代器的方式获取到键和值
                                //Set<Map.Entry<String,Integer>> entrySet = map.entrySet(); //父类引用指向子类对象(HashMap)
                                Set<Entry<String,Integer>> entrySet = map.entrySet(); //直接获取子类对象 获取所有键值对对象的集合  
                                Iterator<Entry<String, Integer>> ir = entrySet.iterator(); //通过迭代器来遍历所有键值对对象
                                while(ir.hasNext()){    //判断是否还有下一个键值对对象
                                    Entry<String, Integer> en = ir.next(); //获取到键值对对象
                                    String key = en.getKey(); //通过键值对对象获取到键
                                    Integer value = en.getValue(); //通过键值对对象获取到值
                                    System.out.println(key+"..."+value);
                                }
                        * 方式2  --通过增强for的方式获取到所有键值对对象的键和值
                            for (Entry<String, Integer> en : map.entrySet()) {
                                String key = en.getKey();
                                Integer value = en.getValue();
                                System.out.println(key+"..."+value);
                            }


d.
    HashMap集合键是Student值是String的案例
    * 案例演示
        * HashMap集合键是Student值是String的案例
    *  分析
        * 键是学生基类对象
        * 值是学生的归属地    
        * 前提:基类必须重写hashCode和equals方法,和HashSet的理论一致。

e.
    LinkedHashMap
        概述
            * util包下,是个类对象
            * 底层链表结构实现,所以保证了怎么存怎么取。又因为是HashMap的子类对象,所以同样保证了键的唯一性
        使用
            * 代码实现

f.    
    TreeMap
        概述
            * util包下,是一个类对象
            * 基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序Comparable进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。 
        使用
            * 案例演示
                * TreeMap集合键是Student值是String的案例
            * 代码
                * demo01_TreeSet使用自然排序的方式对进行进行_升序_排序();
                * demo02_TreeSet使用比较器排序的方式对元素进行_降序_排序();
【自然排序的compare方法 和 比较器的compareTo方法 类似于hashcode和equals的比较顺序,都是先比较第一个方法,如果第一个方法条件不成立,就比较第二个方法,如果第一个方法条件成立,就无需比较第二个方法。提高了代码的运行效率】
【当自然排序和比较器排序都存在时,系统会优先以 比较器排序为准。】


g.
    统计字符串中每个字符出现的次数
    * 案例演示
        * 需求:键盘录入字符串,统计字符串中每个字符出现的次数

    集合嵌套之HashMap嵌套HashMap


h.
【面试题--在企业面试过程中JavaEE要占整个面试的60%~70%】
    HashMap和Hashtable的区别
        概述
            * Hashtable是jdk1.0时出现,当集合体系在jdk1.2版本出现后,让Hashtable也实现了Map接口。成为了Map集合体系中的一部分,但是该Hashable是线程安全的,同步(加
            * 
            * 
            * 
            * 
            * 
            * 
            * ),执行效率低,所以被jdk1.2后map集合体系中的HashMap给替代掉了。因为HashMap是线程不安全的,执行效率高。 --整个过程类似List集合系统中的Vector一样的命运。    
        区别
            * 共同点:
                * 底层都是 哈希算法,都是双列集合。
            * 异同点:
                1. * HashMap是线程不安全的,执行效率高,jdk1.2版本时候出现。
                   * Hashtable是线程安全的,执行效率低,jdk1.0版本时候出现。
                2. * HashMap可以存储Null键,Null值。
                   * Hashable不可以存储Null键,Null值。 

i.
    Collections工具类的概述和常见方法
        Collections工具类的概述和常见方法
        概述
            * Collections是针对集合操作的 工具类。
            * 查看API可知,所有方法都是静态的,所以要做一步操作:
                * 当一个类中所有方法都是静态的,要私有构造方法,目的是不让其他类去创建本类对象,而是直接 类名.方法名 调用即可。
        成员方法
            * public static <T> void sort(List<T> list);  根据元素的自然顺序 对指定列表按升序进行排序。
            * public static <T> int binarySearch(List<T> list, T key); 使用二分搜索法搜索指定列表,以获得指定对象。
                 * 如果该元素不存在,就返回 该元素在集合的正序排序的负的插入点-1即:
            * public static <T> T max(Collection<?> coll); 根据元素的自然顺序,返回给定 collection 的最大元素。
            * public static void reverse(List<T> list); 反转指定列表中元素的顺序。
            * public static void  shuffle(List<T> list); 使用默认随机源对指定列表进行置换。所有置换发生的可能性都是大致相等的。
                 * 如:对扑克牌随机洗牌,即元素排序的顺序每次不同

g.
    模拟斗地主洗牌和发牌
案例演示
    * 模拟斗地主洗牌和发牌,牌没有排序
案例演示
    * 模拟斗地主洗牌和发牌并对牌进行排序的代码实现



k.
    泛型固定下边界
   ? super E --固定下边界    
    向上限定,此时的? 只能够是E或E的父类 --只能够是BaseStudent或BaseStudent的父类
      * 比如:TreeSet(Comparator<?  super E> comparator)  比较器排序
      
   ? extends E --这种写法叫:固定上边界。 
    向下限定,此时的? 只能够是E或E的子类  --只能够是Student或Student的子类
      * 比如:ArrayList 的  addAll(Collection<?  extends E> c)      添加集合的方法


【集合继承体系图】
Collection 单列集合顶层接口
    * List 存取有序,有索引,元素可重复。
        * ArrayList 
            * 底层:数组结构实现。线程不安全,不同步,所以执行效率高。查询快,修改快,增删慢。
        * Vector
            * 底层:数组结构实现。线程安全,同步,所以执行效率低。增删改查都慢。jdk1.0时出现,在jdk1.2时候并入集合体系。已被ArrayList替代。
        * LinkedList
            * 底层:链表结构实现。线程不安全,不同步,所以执行效率高。查询慢,修改慢。增删快。
查询多,修改多,用ArrayList
增加多,删除多,用LinkedList
都多,用ArrayList        

    * Set 存取无序,无索引,元素不可重复。
        * HashSet
            * 底层:哈希算法实现。线程不安全,不同步。所以执行效率高。
                * 存储自定义Bean对象,保证元素的唯一性,必须依赖hashcode和equals方法。
        * LinkedHashSet
            * 底层:链表结构实现。是Set集合中唯一一个存取有序的集合,又因为是HashSet的子类,所以保证了元素的唯一性。
        * TreeSet
            * 底层:二叉树实现。线程不安全,不同步。所以执行效率高。
                * TreeSet是用做排序的。依赖的是 自然排序 和 比较器排序。
开发过程中,不需要对存储元素排序,大多时候用HashSet,因为HashSet效率高。
TreeSet在面试时候比较多:问有几种排序方式 和 几种排序方式的区别
    * 方式:自然排序 和 比较器排序
    * 区别:
        * 自然排序:Bean类实现comparable接口,重写compareTo方法,new TreeSet集合对象是什么都不传入。
        * 比较器排序:在new TreeSet集合对象时,传入使用匿名内部类的方式,传入比较器接口,重写compare()方法。        


Map 双列集合顶层接口 表现形式是一种 <K,V>的映射关系
    * HashMap
        * 底层:哈希算法实现。线程不安全,不同步。针对键。
    * linkedHashMap
        * 底层:链表结构实现。线程不安全,不同步。是HashMap的子类。针对键。
    * TreeMap
        * 底层:二叉树实现。线程不安全,不同步。 对元素进行排序的。 该映射根据 自然排序 和 比较器排序。
    * Hashtable
        * 底层:哈希算法。是jdk1.0时候出现,在jdk1.2时候并入集合体系。已被HashMap替代。
        
Map是键唯一,Collection的子体系中Set是唯一   --map集合和Collection的子体系的set集合很像。    
单列集合存储重复元素,优先考虑ArrayList, 如果不存储重复元素,优先考虑HashSet
双列集合自己考虑用HashMap,如果要对 键 进行排序,使用TreeSet。


【集合的遍历方式】
Collection
    1. 普通for,配合size()和get(int index)使用。
    2. toArray集合转数组后,配合普通for或增强for。
    3. 迭代器Iterator 不能边遍历元素,边修改(增加)元素,但必须使用自己迭代器remove()的方法。
    4. List特有迭代器ListIterator。可以边遍历元素,边修改(增加,删除)元素,但必须使用自己迭代器add()的方法。
    5. 增强for。
    6. Vector自己特有的遍历方式:Vector vec = new Vector(); Enumeration ele = vec.elements(); 获取枚举的方式。

Map
    1. keySet()
    2. entrySet()