大数据进阶22-Collections工具类异常,以及File文件的主要内容

Posted 啊帅和和。

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了大数据进阶22-Collections工具类异常,以及File文件的主要内容相关的知识,希望对你有一定的参考价值。

这一块的内容主要是有关Collections工具类、异常,以及File文件的主要内容

Collections工具类

Collections工具类的概述:

可以针对ArrayList存储基本包装类的元素进行排序

Collection和Collections的区别

  • Collection是单列集合的顶层接口,有两大子接口List和Set
  • Collections是针对集合操作的工具类,可以针对集合进行排序,以及查找(二分查找)

需要熟知的方法

public static void sort(List list)
public static int binarySearch(List<?> list,T key)
public static T max(Collection<?> coll)
public static void reverse(List<?> list)
public static void shuffle(List<?> list)

代码举例:

public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(100);
        list.add(23);
        list.add(200);
        list.add(10);
        System.out.println(list);
        //排序(升序)
        Collections.sort(list);
        System.out.println(list);
        //使用二分查找寻找列表中数字100的位置
        int i = Collections.binarySearch(list, 100);
        System.out.println(i);
        //返回集合中最大的数字
        Integer max = Collections.max(list);
        System.out.println(max);
        //将集合反转
        Collections.reverse(list);
        System.out.println(list);
        System.out.println("*****随机置换*****");
        //打乱排序
        Collections.shuffle(list);
        System.out.println(list);
    }
}
//[100, 23, 200, 10]
//[10, 23, 100, 200]
//2
//200
//[200, 100, 23, 10]
//*****随机置换*****
//[10, 23, 100, 200]

对ArrayList存储的自定义对象排序

我们可以看到一共有两种排序,第一个是自然排序,第二个是比较器排序

方式一:自然排序
但是在使用自然排序的时候,我们的Studet类要实现Comparable接口

不然会出现这个错误

继承之后的Student类

class Student implements Comparable<Student>{
    private String name;
    private int age;

    public int compareTo(Student student){
        int i = this.getAge() - student.getAge();
        int i1 = i == 0 ? this.getName().compareTo(student.getName()) : i;
        return i1;
    }

    Student(){}

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    Student(String name, int age){
        this.name = name;

        this.age = age;
    }

}
public static void main(String[] args) {
        ArrayList<Student> students = new ArrayList<Student>();

        Student s1 = new Student("zhangsan", 21);
        Student s2 = new Student("lisi", 25);
        Student s3 = new Student("wangwu", 28);
        Student s4 = new Student("zhaoliu", 22);

        students.add(s1);
        students.add(s2);
        students.add(s3);
        students.add(s4);

        //自然排序
        Collections.sort(students);

        for(Student s:students){
            System.out.println(s.getName()+"---"+s.getAge());
        }
    }
}
//zhangsan---21
//zhaoliu---22
//lisi---25
//wangwu---28

方式二:比较器排序

public static void main(String[] args) {
        ArrayList<Student> students = new ArrayList<Student>();

        Student s1 = new Student("zhangsan", 21);
        Student s2 = new Student("lisi", 25);
        Student s3 = new Student("wangwu", 28);
        Student s4 = new Student("zhaoliu", 22);

        students.add(s1);
        students.add(s2);
        students.add(s3);
        students.add(s4);

        //自然排序
        Collections.sort(students);

        Collections.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                int i = o1.getAge() - o2.getAge();
                int i1 = i == 0 ? o1.getName().compareTo(o2.getName()) : i;
                return i1;
            }
        });

        for(Student s:students){
            System.out.println(s.getName()+"---"+s.getAge());
        }
    }
}

异常

什么是异常

程序出现了不正常的情况

程序的异常:Throwable

严重的问题

Error我们不处理,这种问题一般都是比较严重的,比如说内存溢出OOM

问题:异常Exception

运行时异常

RuntimeException 这种问题我们也不进行处理,因为这种问题是你自己的问题,比如说代码不严谨

编译时异常

不是RuntimeException的,就是编译时期异常,必须要进行处理,如果不处理,程序编译不通过,无法运行

如果程序出现了问题,我们没有做任何处理,最终JVM会做出默认的处理,把异常的名称,相关原因,以及出现的问题信息输出在控制台,同时程序会结束,后面的代码不会运行

代码举例:
我们可以看到,当我们没有写if判断的时候,控制台打印出来:ArithmeticException
这属于运行时异常,是我们必须要进行处理的,我们加上一个if判断,程序就不走这行代码了

public static void main(String[] args) {
        int a = 10;
        int b = 0;

        if(!(b==0)){
            System.out.println(a/b);
        }

        //ArithmeticException: / by zero
//        System.out.println(a/b);

        System.out.println("over");
    }
}
//over

如何处理异常

  • try…catch…finally
  • thorws 抛出

try…catch…finally处理格式

try{
可能会出现问题的代码
}catch(异常类名 变量名){
针对问题的处理;
}finally{
释放资源;
}

try…catch…finally变形格式

try{
可能会出现问题的代码
}catch(异常类名 变量名){
针对问题的处理;
}

注意

  • try里面的代码越少越好
  • catch里面必须要有内容,哪怕只是一句简单的提示
public static void main(String[] args) {
        int a = 10;
        int b = 0;
        try{
            System.out.println(a/b);
        }catch (ArithmeticException e){
            System.out.println("除数不能为0");
        }
        System.out.println("over");
    }
}
//除数不能为0
//over

处理异常的注意点

1、处理一个异常
2、处理两个异常
1)每一个写一个try…catch
2)写一个try,多个catch
try{
可能会出现问题的代码;
}catch(异常类名 变量名){
针对问题的处理;
}catch(异常类名 变量名){
针对问题的处理;
}catch(异常类名 变量名){
针对问题的处理;
}

注意:
- 能明确异常的类型尽量明确,不要用大的处理(Exception)
- 评级的关系异常谁在谁前谁后无所谓,如果出现了父子继承关系,父必须在后面
- 一旦try里面的代码出错了,就回去匹配catch里面的异常,继续执行后面的代码

代码举例:

public class ExceptionDemo3 {
    //处理一个异常
    private static void fun1(){
        int a = 10;
        int b = 0;
        try{
            System.out.println(a/b);
        }catch (ArithmeticException e){
            System.out.println("除数不能为0");
        }
    }

    //处理两个异常
    private static void fun2(){
        int a = 10;
        int b = 0;
        try{
            System.out.println(a/b);
        }catch(ArithmeticException e){
            System.out.println("除数不能为0");
        }

        int []arr = new int[]{1,2,3};
        try {
            System.out.println(arr[3]);
        }catch (IndexOutOfBoundsException e){
            System.out.println("数组下标越界异常");
        }
    }

    private static void fun3(){
        int a = 10;
        int b = 0;
        int []arr = new int[]{1,2,3};
        try {
            System.out.println(a/b);
            System.out.println(arr[3]);
        } catch (ArithmeticException e){
            System.out.println("除数不能为0");
        }catch (IndexOutOfBoundsException e){
            System.out.println("数组下标越界异常");
        }catch (Exception e){
            System.out.println("异常的父类");
        }
    }

    public static void main(String[] args) {
        //处理一个异常
        fun1();
        System.out.println("*************");
        //处理两个异常
        fun2();
        System.out.println("*************");
        fun3();
    }
}
//除数不能为0
//*************
//除数不能为0
//数组下标越界异常
//*************
//除数不能为0

JDK7的新特性以及注意事项,新的处理异常的方式

try{
可能出现问题的代码
}catch(异常类名1|异常类名2|…变量){

}

注意事项

  • 处理方式是一致的,这个方式虽然简洁,但是也不够好,针对多种类型的问题,只给出了一种解决方案
  • 多个异常之间必须是平级关系
private static void fun(){
        int a = 10;
        int b = 0;
        int []arr = new int[]{1,2,3};

        try {
            System.out.println(a/b);
            System.out.println(arr[3]);
        }catch (ArithmeticException|ArrayIndexOutOfBoundsException e){//这里多个异常之间必须是平级关系,不能出现Exception
            System.out.println("出现了问题");
        }
    }

    public static void main(String[] args) {
        fun();
    }
}
//出现了问题

编译时异常和运行时异常的区别

  • 编译时期异常:Java程序必须要显示处理,否则程序就会发生错误,无法通过编译
  • 运行时期异常:无须显示处理,但是也可以和编译时期异常一样处理

编译时期异常:
如果不对sdf.parse()进行一个try catch,会编译出错

public static void main(String[] args) {
        String s = "20211-8-14";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try{
            Date date = sdf.parse(s);
        }catch (ParseException e){
            System.out.println("日期解析出错");
        }
    }
}
//日期解析出错

异常中需要掌握的方法

  • getMessage()
    获取异常信息,返回字符串
  • toString()
    获取异常类名和异常信息,返回字符串
    返回此可抛出的简短描述。 结果是:
    这个对象的类的name
    “:”(一个冒号和一个空格)
    调用这个对象的getLocalizedMessage()方法的结果
    默认返回的是getMessage()的内容
    如果getLocalizedMessage返回null ,那么只返回类名
  • printStackTrace()
    获取异常类名和异常信息,以及异常出现在程序中的位置,返回void

代码举例:

public static void main(String[] args) {
        String s = "2021-8-14";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try {
            Date date = sdf.parse(s);
            System.out.println(date);
        }catch (ParseException e){
            //获取异常信息,返回字符串
            System.out.println(e.getMessage());
            //获取异常类名和异常信息,返回字符串
            System.out.println(e.toString());
            e.printStackTrace();
        }

    }
}
//Unparseable date: "2021-8-14"
//java.text.ParseException: Unparseable date: "2021-8-14"
//java.text.ParseException: Unparseable date: "2021-8-14"
//	at java.text.DateFormat.parse(Unknown Source)
//	at com.bigdata.shujia21.ExceptionDemo6.main

抛出异常

抛出异常的引入

有些时候,我们可以对异常进行处理,但是有些时候,我们根本没有权限去处理某个异常,或者说,我们处理不了,就干脆不处理了。为了解决这样的问题,并且程序还能继续运行,Java针对这种情况,提供了另一个处理方案:抛出

格式:
throws 异常类名
注意:这个格式必须跟在方法的括号后面
注意:
尽量不要在main方法上抛出
总结:
- 编译时期异常抛出,将来调用者必须要做处理
- 运行时期异常抛出,将来调用者可以不做处理

fun1中出现了编译时期异常,main函数调用的时候,必须要做处理
fun中出现了运行时期异常,main函数调用的时候,可以不做处理

public static void main(String[] args) {
        fun();
        fun1();//这一行会出错
    }

    private static void fun()throws ArithmeticException{
        int a = 10;
        int b = 0;
        System.out.println(a/b);
    }

    private static void fun1() throws ParseException {
        String s = "2021-8-14";
        SimpleDateFormat asd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = asd.parse(s);
        System.out.println(date);
    }
    
}

throw和throws

throw:如果出现了异常情况,我们就应该把异常抛出
这个时候throw抛出的是异常的对象

public static void main(String[] args) {
        fun();
        
        try {
            fun2();    
        }catch (Exception e){
            e.printStackTrace();
        }
        
    }
    
    private static void fun2()throws Exception{
        int a = 10;
        int b = 0;
        if(b==0){
            throw new Exception();
        }else {
            System.out.println(a/b);
        }
    }
    
    private static void fun(){
        int a = 10;
        int b = 0;
        if(b == 0){
            System.out.println("这里b=0");
            throw new ArithmeticException();
        }else{
            System.out.println(a/b);
        }
    }

finally

finally:被finally控制的语句体一定会执行
特殊情况:在执行到finally之前JVM推出了(比如System.exit(0))

格式:
try…catch…finally…

finally在生活中,在开发过程中有什么作用呢?
一般用于释放资源,在IO流操作和数据操作的时候经常见到

public static void main(String[] args) {

        String s = "2021-8-14";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try{
            date = sdf.parse(s);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            System.out.println("finally一般用于释放资源");
        }
        System.out.println(date);
        
    }
}
//finally一般用于释放资源
//java.text.ParseException: Unparseable date: "2021-8-14"
//null
//	at java.text.DateFormat.parse(Unknown Source)
//	at com.bigdata.shujia21.FinallyDemo1.main(FinallyDemo1.java:13)

面试题:final、finally、finalize的区别