A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 庞帅 初级黑马   /  2018-4-14 23:20  /  519 人查看  /  0 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

第07天 集合
集合(HashSet, HashMap,Map集合嵌套)
一:set体系的特点
   *set接口:
      +继承自collection接口
      +特点:
                (1)元素无序(存入和取出的顺序不一致,但存入后每次取出的顺序都一样)
                (2)元素不能重复(元素唯一)
                (3)没有索引
           注意:直接打印和获取元素都属于取出, 所以不要把打印当成是HashSet内部存储的样子
           
二:HashSet存储自定义对象并遍历
  *HashSet类是set接口的实现类
       +成员方法:
          boolean add(E e): 添加成功true, 添加失败(重复了)返回false
     1.HashSet保证元素唯一的原理:
       +判断对象相同的两个方法:(HashSet且去重原理(简单版))
                     (1)hashcode()
                                如果判定哈希值不相同,则认为不重复
                                如果判定哈希值相同,则需要继续用equals()方法判断
                     (2)equals()
                                如果判定不相同, 则认为不重复     
                                如果判定相同, 则认为重复         
      
                 (1) HashSet的add()方法, 首先将新添加的元素和当前集合中的已有元素进行hash值比较, 依靠对象的"hashCode()"
                 (2) 如果hash值不一样, 则认为不重复, 直接添加新元素
                 (3) 如果hash值一样, 则继续与已有元素比较"地址值"或使用"equals()方法"进行比较
                                                 如果比较结果一样, 则认为重复, 不添加
                                       如果和所有的已有元素比较都不一样, 则认为不重复, 添加元素         
                   注意:自定义对象的hashCode()和equals()方法决定了该对象能否被去重   
                    
       *hashCode()方法和equals()方法的优化
                优化hashCode()方法, 即让该方法的返回值和成员属性相关联, 减少equals()的调用, 提高效率
                     (1)让hashCode()方法返回所有成员变量之和.
                         - 基本数据类型直接相加
                         - 引用数据类型获取该成员变量的hashCode方法返回值后再相加(boolean不能参与运算)
                     (2)优化equals方法
                         - 提高效率: this ==obj-->return true
                         - 提高向下转型的安全性:this.getClass() == obj.getClass()-->return false
三.Collections工具类
    *Collection 和Collections 的区别
      - Collection是接口, 是单列集合的顶层, 包含一些共性方法
          - Collections是类, 提供操作Collection的一些工具方法, 类似的还有操作数组的Arrays工具类
       *Collections类常用的静态方法:
               (1) static int binarySearch(List list,T key):使用二分查找来查找元素在指定列表的索引位置  *(前提是集合已经排序,查找原理类似猜数字)
              (2) static voidcopy(List dest, List src): 将源列表中的数据复制到目标列表  *(目标列表的长度至少等于源列表的长度)
              (3) static voidfill(List list, Object obj): 使用指定对象填充指定列表的所有元素
              (4) static voidreverse(List list): 反转集合中的元素
              (5) static voidshuffle(List list): 随机打乱集合中元素的顺序
              (6) static voidsort(List list): 将集合中的元素按照元素的自然顺序排序
              (7) static voidswap(List list, int i, int j): 将指定列表中的两个索引进行位置互换
           
四:Map接口的概述
     *    Map<K, V>接口
                     是双列集合的顶层, 和Collection属于同级
               +特点:
                       (1)存储方式是key-value(键值对)方式, 即一个键对应一个值
             (2) 一个键只能映射一个值
                       (3) 键不能重复, 值可以重复
                       (4) 键是无序的
        +Map和Collection的区别
           - Map是双列集合, 用于处理有一一对应关系的数据,键不能重复且键无序
           - Collection是单列集合, 有不同的子体系,List允许重复且有序, Set不允许重复且无序
五:Map功能概述和测试
     *HashMap
                +多态创建对象: (也可以不使用多态)
                    -Map<K, V> map = new HashMap<>();
                +常用方法:
                    - 增和改:V put(K key, Vvalue): 添加键值对.
                                 注意: 如果key已经存在, 则会使用新的value覆盖原有value,并将原有value返回
                       - 删:
                        void clear(): 清空集合
                        V remove(Object key): 删除指定键的值(key和value都会删除)
                    - 查:
                           -V get(Object key): 通过指定键获取值
                          - int size(): 获取集合长度
                    - 判断:
                           -boolean containsKey(Object key): 是否包含指定的键
                           -boolean containsValue(Object value): 是否包含指定的值
                           -boolean isEmpty(): 是否为空
                       - 遍历:
                           -Set<Map.Entry<K, V>> entrySet(): 获取键值对的Set集合
                          - Set<K> keySet(): 获取所有键的Set集合
                           -Collection<V> values(): 获取所有值得Collection集合
     *Map的遍历方式
         + keySet()方法(Map的第一种遍历方式)
               - 通过get(K key)方法获取key对应的value
         + entrySet()方法, 遍历值的集合(Map的第二种遍历方式)
               - 使用Entry的getKey()获取key, 使用Entry的getValue()获取value
               
         *注意:HashMap存储数据并遍历:String作为key时,相同的字符串内容会导致key重复,字符串通过equals比较返回true
                               自定义类的对象作为key, 是否重复取决于自定义对象的类中如何重写hashCode()和equals()方法
六:可变参数
     1.从JDK1.5开始
         2.可变参数: 方法的形参可以传入不定数量个参数
         3.定义格式: 形参数据类型... 形参名
      
       注意事项:
          1.可变参数的数量可以从0个到多个
          2.可变参数只能是同一种数据类型
          3.可变参数的定义位置必须在方法形参列表的最后一个
      
       可变参数的原理:
              底层是一个根据形参数量创建长度的数组, 通过JVM将形参转换为数组
      
       如何使用可变参数?
              1.在方法中使用: 把可变参数的形参名当做一个数组变量名, 遍历并获取元素
           2.向方法中传入参数: 将多个参数值使用逗号分隔传入方法
                        
七:Map嵌套演示: Map嵌套Map
       Map<String, Map<String,String>>
      
            理清key和value
              - 存入: 先处理好内部的Map, 然后再放入外部Map
              - 取出: 遇到Map就使用2种方式遍历即可
      
    Map嵌套演示: Map嵌套Collection
        Map<String,Collection<Student>>
             理清key和value
                - 存入: 先处理好内部的Collection, 然后再放入外部Map
                - 取出: 遇到Map就使用2种方式遍历, 遇到Collection就用3种方式遍历
扩展
      让对象实现排序的2种方式
         - 让对象具有自然顺序: 让JavaBean实现Comparable接口, 重写compareTo()方法
         - 使用比较器: 定义一个类作为比较器, 实现Comparator接口, 重写compare()方法, 排序时传入该比较器实现类的对象
      重写方法的返回值的作用:
         - 返回值为负数: 则认为当前元素比被比较元素小
         - 返回值为0: 则认为当前元素与被比较元素相等
         - 返回值为正数: 则认为当前元素比被比较元素大
         
HashSet去重详细版原理
       * 当调用HashSet的add()方法时,该方法内部调用的是一个HashMap的put()方法,将元素作为HashMap的key,存入HashMap中,
           利用Map的key的唯一性,保证HashSet的元素唯一性
   
    * 那HashMap的key如何保证唯一呢?
              * 首先, HashMap的put方法, 会先计算key的hash值.
              * 然后, 拿该hash值在一个名为table的Entry[]数组中寻找该hash值的索引.
              * 之后, 在for循环的初始化条件中, 拿该索引值获取Entry[]数组中的Entry元素
                     * 如果没有该元素,即元素为null,说明元素不重复,则for循环不满足执行条件,直接略过for循环,并添加元素到Entry[]数组中,并在put()方法最后返回一个null
                     * 如果有该元素, 则进入for循环. 继续判断该元素是否与已有元素相同
                            * 首先,使用当前Entry集合中的每一个元素和新添加的元素进行hash值的比较
                                   * 如果hash值不同, 则直接添加新的元素
                                   * 如果hash值一样, 则比较Entry的key和传入的key是否相同或使用equals方法比较
                                           *如果比较结果相同, 则认为是重复不添加, 且返回已有元素
                                           *如果不重复, 则继续for循环比较下一个
                                           *直到所有比较结果都不相同, 则认为不重复, 添加新的元素
第08天 异常
  
一:异常的体系结构
    Throwable(最顶层)
       Error:不能处理的异常
       Excrption:可以处理的异常,编译异常
         RuntimeExcrption:运行异常,编译正常
         
二:jvm处理异常的方式
    1.将异常的类型,原因还有位置显示在命令行,并且终止程序
三:异常的处理方式
      捕获处理
     try..catch语句
        try{
                      有可能出现问题的代码
       } catch(异常类型   类型名){
                       处理异常;
    }
  try..catch的执行顺序:
               首先执行try语句,如果有异常直接调到catch语句中,整个try..catch语句结束,
               如果没有异常,try..catch语句不执行
         
     抛出去:
           当不想或不能解决异常时,可以使用关键字throws在方法声明处将异常抛出,谁调用方法谁处理
      
四:多异常处理
   1.可以使用多个try.. catch语句
   2.使用一个try和多个catch
     多异常执行顺序:
         1.多个catch之间可以有子父类关系
         2.平级或同级没有子父类关系
         3.如果有子父类,父类必须放到后面   
         
五:Throwable的常用方法:
  (1):1.StringgetMessage():异常原因
     2.String toString():异常类型和原因
     3.void printStackTrace():异常类型,原因和位置
         *该方法只是将异常信息以System.err错误输出流打印到控制台,并不会结束程序
         *System.err.println:输出的是红字
  (2)finally:组合try。。catch使用,用于释放资源等收尾工作,无论try..catch是如何执行,
            finally的代码块中的代码都会执行。
      try{
                      有可能出现问题的代码
        } catch(异常类型   类型名){
                       处理异常;
        }finally{
                      释放资源;
                      清理垃圾;
     }
   
六:异常的分类
   1.运行时期异常:RuntimeExcrption的子类就是运行时期异常,在编译时期可以自由选择处理或不处理。
   2.编译时期异常:是Excrption的子类,非RuntimeExcrption的子类在编译时期必须处理,
七:自定义异常
      1.throws:处理异常的一种方式,把异常抛出,有调用者处理
      2.throw:制造异常的方式,并且结束方法
         *注意:如果是抛出的编译时期异常,必须在方法声明处抛出
    *写一个类去继承Exception或RuntimeException,然后实现多个构造即可
   
   
八:递归
       1.概述:
         (1) 把大问题拆成小问题
                       在方法本身不断调用方法自己
         (2)注意事项:
                      递归一定要有出口,内存溢出
                      递归次数不宜过多,内存溢出         
      
九:斐波那契列数:
             不死神兔 :第一个月和第二个月都是一对兔子,第三个月生下一对兔子,以后每月都生一对兔子,
             即:1--1
                2--1
                3--2
                4--3
                5--5
                6--8
                7--13
                .
                .
                .
                20
   从第三个月开始:每个月都是前两个月兔子之和,即n=(n-1)+(n-2);

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马