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

2020-03-14  本文已影响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;
                }
            }   
        }   

今日内容

选择排序

介绍

图解选择排序

代码实现

/*
    选择排序:
        另外一种排序的方式,选中数组的某个元素,其后面的元素依次和选中的元素进行两两比较,将较大的数据放
在后面,依次从前到后选中每个元素,直至所有数据按要求完成排序
 */
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 异常类 写代码不当造成, 程序员必须处理好的

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

异常的分类

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

异常处理

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

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

 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 声明异常(写在方法定义上)

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都不能单独使用,必须连用。

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("文件不存在");
        }
    }
}

finally代码块[IO流时使用]

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("文件不存在");
        }
    }
}

异常的注意事项

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

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

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

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

自定义异常

自定义异常概念

自定义异常步骤

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遍历)    
上一篇下一篇

猜你喜欢

热点阅读