美文网首页
3/14day10_选择排序_二分查找_异常

3/14day10_选择排序_二分查找_异常

作者: 蹦蹦跶跶的起床啊 | 来源:发表于2020-03-14 17:35 被阅读0次

    复习

    1.Map的通用方法【重点】
        put(键,值); 添加
        remove(键);
        get(键);
        put(键,值); 修改
        containsKey(键);
        containsValue(值);
    2.Map的遍历方式【重点】
        a.以键找值
            Set<键> keys = map.keySet();//获取所有键的Set集合
            for(K 键 : keys){ //遍历所有的键
                V 值 = map.get(键); //以键找值
                打印
            }
        b.键值对方式
            Set<Map.Entry<键,值>> entries = map.entrySet();//获取所有键值对的Set集合
            for(Map.Entry<键,值> 键值对 : entries){ //遍历所有的键值对
                键值对.getKey(); //获取键
                键值对.getValue();//获取值
                打印
            }
    3.集合的嵌套
        a.ArrayList<ArrayList<String>>
        b.ArrayList<HashMap<String,Integer>>
        c.HashMap<String,HashMap<String,Integer>>
    4.斗地主【重点,3遍历】
    5.冒泡排序【理解】
        核心: 依次比较相邻的两个元素,大的往后走,小的往前走
        代码:
            for(int i = 0;i < arr.length-1;i++){
                for(int j = 0;j < arr.length-1-i;j++){
                    if(arr[j] > arr[j+1]){
                        int temp = arr[j+1];
                        arr[j+1] = arr[j];
                        arr[j] = temp;
                    }
                }   
            }   
    

    今日内容

    • 选择排序
    • 二分查找
    • 异常【异常的继承体系是重点】
    • 异常的处理【try...catch处理方式是重点】
    • 自定义异常

    选择排序

    介绍

    • 另外一种排序的方式,选中数组的某个元素,其后面的元素依次和选中的元素进行两两比较,将较大的数据放在后面,依次从前到后选中每个元素,直至所有数据按要求完成排序
    • 如果有n个数据进行排序,总共需要比较n-1次
    • 每一次比较完毕,下一次的比较就会少一个数据参与

    图解选择排序

    代码实现

    /*
        选择排序:
            另外一种排序的方式,选中数组的某个元素,其后面的元素依次和选中的元素进行两两比较,将较大的数据放
    在后面,依次从前到后选中每个元素,直至所有数据按要求完成排序
     */
    public class ArrayDemo {
        public static void main(String[] args) {
            //定义一个数组
            int[] arr = {7, 6, 5, 4, 3};
            System.out.println("排序前:" + Arrays.toString(arr));
            // 这里减1,是控制比较的轮数
            for (int x = 0; x < arr.length - 1; x++) {
                // 从x+1开始,直到最后一个元素
                for (int i = x+1; i < arr.length; i++) {
                    if (arr[x] > arr[i]) {
                        int temp = arr[x];
                        arr[x] = arr[i];
                        arr[i] = temp;
                    }
                }
            }
            System.out.println("排序后:" + Arrays.toString(arr));
        }
    }
    

    二分查找

    普通查找和二分查找

    • 普通查找: 给定数组,找到对应数组的索引. 只能从前往后依次遍历
    • 二分查找:给定数组, 必须是有自然顺序的(比如,从小到大), 从数组中找到某个元素的索引.
      原理:每一次都去获取数组的中间索引所对应的元素,然后和要查找的元素进行比对,如果相同就返回索引;如果不相同,就比较中间元素和要查找的元素的值;小的话,就去掉后一半.拿前半比较

    二分查找图解

    代码实现

        public static void main(String[] args) {
            int[] arr = {10, 14, 21, 38, 45, 47, 53, 81, 87, 99};
            int index = binarySerach(arr, 38);
            System.out.println(index);
        }
        /**
         * 二分查找方法
         * @param arr 查找的目标数组
         * @param number 查找的目标值
         * @return 找到的索引,如果没有找到返回-1
         */
        public static int binarySerach(int[] arr, int number) {
            int start = 0;
            int end = arr.length - 1;
     
            while (start <= end) {
                int mid = (start + end) / 2;
                if (number == arr[mid]) {
                    return mid ;
                } else if (number < arr[mid]) {
                    end = mid - 1;
                } else if (number > arr[mid]) {
                    start = mid + 1;
                }
            }
            return -1;  //如果数组中有这个元素,则返回
        }
    

    异常

    介绍

    异常:指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止.
    在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象。Java处理异常的方式是中断处理。
    异常指的并不是语法错误,语法错了,编译不通过,不会产生字节码文件,根本不能运行.

    异常的继承体系[重点]

    Throwable 所有异常和错误的根类
    |-- Error 错误类 硬件错误,或者说不可抗抗拒的意外.程序员无法处理
    |-- Exception 异常类 写代码不当造成, 程序员必须处理好的

    • Throwable中的常用方法:
    public void printStackTrace() :打印异常的详细信息。
    包含了异常的类型,异常的原因,还包括异常出现的位置,在开发和调试阶段,都得使用printStackTrace
    public String getMessage() :获取发生异常的原因。
    提示给用户的时候,就提示错误原因。
    public String toString() :获取异常的类型和异常描述信息(不用)。
    

    异常的分类

    我们平常说的异常就是指Exception,因为这类异常一旦出现,我们就要对代码进行更正,修复程序。

    • 编译时异常(必须在类名中声明抛出异常)
      checked异常。在编译时期,就会检查,如果没有处理异常,则编译失败
      编译时异常是Exception 以及Exception的子类(RuntimeException除外)

    • 运行时异常(不用在类名中声明异常)
      runtime异常。在运行时期,检查异常.在编译时期,运行异常不会编译器检测(不报错)。(如数学异常)

    • 图解分类


    • 图解异常产生过程

    异常处理

    java 中异常相关的五个关键字
    throw, throws, try...catch finally

    throw抛出异常(写在方法内)

    • throw是一个关键字

    • 想要先上抛出异常时, 使用throw关键字

    • 格式
      throw 异常对象
      throw new 异常类();

    • 代码演示

     public class TestException02 {
            public static void main(String[] args) {
                int[] arr = {1,2,3};
                //调用方法
                int element = getElement(arr);
                System.out.println(element);
            }
    
            public static int getElement(int[] arr){
                //自己判断,数组是否有3索引
                if (arr.length < 4) {
                   //抛出异常
                    throw new ArrayIndexOutOfBoundsException("哥们越界了!!!");
                }
                //获取数组中索引为3的元素
                int num = arr[3];
                //返回num
                return num;
            }
        }
    

    Objects非空判断

    Objects 是个工具类
    其中有个静态方法 叫做空指针容忍方法

    public static <T> T requireNonNull(T obj) :查看指定引用对象不是null。
    public static <T> T requireNonNull(T obj) {
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }
    

    遇到异常的两种处理方式[重点]

    编译时遇到异常,必须处理, 采用以下两种方式
    运行时异常, 编译时期不需要处理,不需要在类名上进行声明异常, 运行后根据异常信息修改即可

    throws 声明异常(写在方法定义上)

    • 声明异常格式
      throws关键字是给方法使用的, 为该方法做出声明,将问题标识出来,报告给调用者。
      如果方法内通过throw抛出了编译时异常,而没有捕获处理,那么必须通过throws进行声明,让调用者去处理。
      格式:
      修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2…{ }
      代码演示
    public class ThrowsDemo {
        public static void main(String[] args) throws FileNotFoundException {
            read("a.txt");
        }
     
        // 如果定义功能时有问题发生需要报告给调用者。可以通过在方法上使用throws关键字进行声明
        public static void read(String path) throws FileNotFoundException {
            if (!path.equals("a.txt")) {//如果不是 a.txt这个文件 
                // 我假设  如果不是 a.txt 认为 该文件不存在 是一个错误 也就是异常  throw
                throw new FileNotFoundException("文件不存在");
            }
        }
    

    try...catch捕获异常

    自己写的抓住异常的话, 虚拟机就不会拿到异常,不会立刻终止程序,还是会继续运行
    如果异常出现的话,会立刻终止程序,所以我们得处理异常:

    1. 该方法不处理,而是声明抛出,由该方法的调用者来处理(throws)。
    2. 在方法中使用try-catch的语句块来处理异常。
      try-catch的方式就是捕获异常。
      捕获异常:Java中对异常有针对性的语句进行捕获,可以对出现的异常进行指定方式的处理。
      捕获异常语法如下:

    try:该代码块中编写可能产生异常的代码。
    catch:用来进行某种异常的捕获,实现对捕获到的异常进行处理。
    注意:try和catch都不能单独使用,必须连用。

    • 捕获异常的格式
      try{
      可能出现异常的代码
      } catch(XxxExcption e){
      //处理异常
      e.printStackTrace();//直接打印
      save(e);//将异常保存到异常日志(或者数据库)
      }

    • 代码演示

    public class TryCatchDemo {
        public static void main(String[] args) {
            try {// 当产生异常时,必须有处理方式。要么捕获,要么声明。
                read("b.txt");
            } catch (FileNotFoundException e) {// 括号中需要定义什么呢?
                //try中抛出的是什么异常,在括号中就定义什么异常类型
                System.out.println(e);
            }
            System.out.println("over");//抓住异常之后的代码还是会继续运行
        }
        /*
         *
         * 我们 当前的这个方法中 有异常  有编译期异常
         */
        public static void read(String path) throws FileNotFoundException {
            if (!path.equals("a.txt")) {//如果不是 a.txt这个文件 
                // 我假设  如果不是 a.txt 认为 该文件不存在 是一个错误 也就是异常  throw
                throw new FileNotFoundException("文件不存在");
            }
        }
    }
    
    • 捕获到异常之后, 查看异常信息
      1.直接打印出来,调用e.printStachTrace(); 开发阶段
      2.可以先保存出来,比如保存到异常日志,异常系统之类

    finally代码块[IO流时使用]

    • finally代码块格式
      finally一般不单独使用, 配合try...catch使用
      try...catch....finally...:自身需要处理异常,最终还得关闭资源。
      写在finally中的代码,无论是否有异常, 都会执行

    • finally代码块的作用
      一般用于写释放资源,关闭连接等代码
      当只有在try或者catch中调用退出JVM的相关方法,此时finally才不会执行,否则finally永远会执行。

    • 伪代码演示

    public class TryCatchDemo4 {
        public static void main(String[] args) {
            try {
                read("a.txt");
            } catch (FileNotFoundException e) {
                //抓取到的是编译期异常  抛出去的是运行期 
                throw new RuntimeException(e);
            } finally {
                System.out.println("不管程序怎样,这里都将会被执行。");
                xxx.close();
            }
            System.out.println("over");
        }
        /*
         *
         * 我们 当前的这个方法中 有异常  有编译期异常
         */
        public static void read(String path) throws FileNotFoundException {
            if (!path.equals("a.txt")) {//如果不是 a.txt这个文件 
                // 我假设  如果不是 a.txt 认为 该文件不存在 是一个错误 也就是异常  throw
                throw new FileNotFoundException("文件不存在");
            }
        }
    }
    

    异常的注意事项

    • 运行时异常被抛出可以不处理。即不捕获也不声明抛出。
    • 如果父类的方法抛出了多个异常,子类覆盖(重写)父类方法时,只能抛出相同的异常或者是他的子集。
      比如父类抛出100个异常,子类重写该方法时,只能抛出这100个或者这100个中的需要的几个。
    • 父类方法没有抛出异常,子类覆盖父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出
    • 当多异常分别处理时,捕获处理,前边的类不能是后边类的父类
    • 在try/catch后可以追加finally代码块,其中的代码一定会被执行,通常用于资源回收。
    • 多个异常使用捕获又该如何处理呢?
      1.多个异常分别处理。
      2.多个异常一次捕获,多次处理。所有异常一起try,分开catch
      3.多个异常一次捕获一次处理。所有异常一起try,一个catch

    使用一次捕获多次处理方式,格式如下:
    注意事项: 多个catch捕获异常必须是 前面先是捕获子类异常,后面才能是捕获父类异常

    try{
         编写可能会出现异常的代码
    }catch(异常类型A  e){  当try中出现A类型异常,就用该catch来捕获.
         处理异常的代码
         //记录日志/打印异常信息/继续抛出异常
    }catch(异常类型B  e){  当try中出现B类型异常,就用该catch来捕获.
         处理异常的代码
         //记录日志/打印异常信息/继续抛出异常
    }
    

    多个异常一次捕获一次处理。所有异常一起try,一个catch

    try{
         编写可能会出现异常的代码
    }catch(Exception  e){  用异常的父类来捕获
         处理异常的代码
         //记录日志/打印异常信息/继续抛出异常
    }
    

    自定义异常

    自定义异常概念

    • 概念:自定义一个异常类.(每一个异常类就是一种异常情况)
      因为JDK不可能定义所有的异常情况.

    自定义异常步骤

    1.创建一个类, 类名必须叫做XxxException
    2.继承Exception或者RuntimeException
    3.提供两个构造,无参构造+带有String参数的构造

    代码演示

    需求:我们模拟注册操作,如果用户名已存在,则抛出异常并提示:亲,该用户名已经被注册。
    首先定义一个注册异常类RegisterException:

    // 业务逻辑异常
    public class RegisterException extends Exception {
        /**
         * 空参构造
         */
        public RegisterException() {
        }
     
        /**
         *
         * @param message 表示异常提示
         */
        public RegisterException(String message) {
            super(message);//表示调用父类的构造
        }
    }
    

    模拟登陆操作,使用数组模拟数据库中存储的数据,并提供当前注册账号是否存在方法用于判断。

    public class Demo {
        // 模拟数据库中已存在账号
        private static String[] names = {"bill","hill","jill"};
       
        public static void main(String[] args) {     
            //调用方法
            try{
                  // 可能出现异常的代码
                checkUsername("nill");
                System.out.println("注册成功");//如果没有异常就是注册成功
            }catch(LoginException e){
                //处理异常
                e.printStackTrace();
            }
        }
     
        //判断当前注册账号是否存在
        //因为是编译期异常,又想调用者去处理 所以声明该异常
        public static boolean checkUsername(String uname) throws LoginException{
            for (String name : names) {
                if(name.equals(uname)){//如果名字在这里面 就抛出登陆异常
                    throw new LoginException("亲"+name+"已经被注册了!");
                }
            }
            return true;
        }
    }
    

    今日小结

    能够理解选择排序的执行原理
        for(int i = 0;i < arr.length - 1;i++){ //外层控制选中的元素
            for(int j = i+1;j < arr.length;j++){ //内层控制比较的元素
                //比较
                if(arr[i] > arr[j]){
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    能够理解二分查找的执行原理
        public static int binarySearch(int[] arr,int key){
            int left = 0;
            int right = arr.length - 1;
    
            while(left <= right){
                int middle = (left+right)/2;
                if(arr[middle] > key){
                    right = middle - 1;
                }else if(arr[middle] < key){
                    left = middle + 1;
                }else{
                    retrun middle;
                }
            }
            return -1;
        }
        
    能够辨别程序中异常和错误的区别
        Throwable
            Exception 异常一般是程序编写不当造成的,程序有能力处理
            Error 错误一般硬件引起的(系统崩溃,内存溢出),程序员一般无法处理
    说出异常的分类
        Throwable 
            |- Error
            |- Exception
                |- 编译时异常 Exception以及其子类(RuntimeException除外) 需要强制进行 throw try...catch
                |- 运行时异常 RuntimeException以及其子类
    列举出常见的三个运行期异常
        ArrayIndexOutOfBoundsException
        NullPointerException
        ClassCastException 向下转型时出现的类型转换异常
        ConcurrentModificationException 并发修改异常,迭代器使用过程中直接向集合添加/删除元素
    能够使用try...catch关键字处理异常【重点】
        try{
            方法名(实际参数);   
        }catch(XxxException e){
            e.printStackTrace();   
        }
    能够使用throws关键字处理异常【重点】
        throws 给方法使用的,表示声明抛出异常,该调用的调用者要处理异常
        public void 方法名(参数列表) throws Exception{
            %^&*()%^&(
        }
    能够自定义并使用异常类
        完成自定义异常的练习案例(3遍历)    
    

    相关文章

      网友评论

          本文标题:3/14day10_选择排序_二分查找_异常

          本文链接:https://www.haomeiwen.com/subject/eqqmshtx.html