Java 入门第三季

Java 入门第三季

1 异常与异常处理

1.1 Java 异常简介

这里写图片描述
这里写图片描述
运行时异常由 Java 虚拟机自动捕获自动抛出
这里写图片描述]![这里写图片描述
检查时异常需要你手动添加捕获和处理语句

1.2 Java 中使用 try…catch…finally 实现异常处理

这里写图片描述
try 抛出异常会发生什么?
1. 抛出异常的方法会终止执行
2. 程序的控制权讲被移交给 catch 块中的异常处理程序
这里写图片描述

try 会抛出很多种类型的异常该怎么办?
这里写图片描述
这里写图片描述

多重catch语句中,异常类型必须子类在前父类在后
这里写图片描述
这里写图片描述
这里写图片描述

1.3 Java中通过案例学习 try…catch…finally

  1. finally语句块是在try语句块和catch语句块中的return语句执行完之后返回到调用者之前执行的
  2. 如果try…catch…finally语句块之内没有return语句,就会调用这三个语句块之外的return语句
package com.anoscxy;

public class TryCatchTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        TryCatchTest tct = new TryCatchTest();
        int result = tct.test();
        System.out.println("test()方法,执行完毕!返回值为:"+result);
        int result2 = tct.test2();
        System.out.println("test2()方法,执行完毕!返回值为:"+result2);
        int result3 = tct.test3();
        System.out.println("test3()方法,执行完毕!返回值为:"+result3);
    }

    /**
     * divider(除数)
     * result(结果)
     * try...catch 捕获 while 循环
     * 每次循环,divider 减 1,result = result + 100、divider
     * 如果:捕获异常,打印输出"抛出异常!"
     * 否则:返回 result
     * @return
     */
    public int test() {
        int divider = 10;
        int result = 100;
        try {
            while (divider > -1) {
                divider--;
                result = result + 100 / divider;
            }
            return result;
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            System.out.println("循环抛出异常!");
            return -1;
        }
    }

    public int test2() {
        int divider = 10;
        int result = 100;
        try {
            while (divider > -1) {
                divider--;
                result = result + 100 / divider;
            }
            return result;
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            System.out.println("循环抛出异常!");
            return result = 999;
        }finally {
            /**
             * finally 语句块是在 try 语句块和 catch 语句块中的 return 语句执行完之后返回到调用者之前执行的
             */
            System.out.println("这是finally!");
            System.out.println("我是Result!我的值是:"+result);
        }
    }

    public int test3() {
        int divider = 10;
        int result = 100;
        try {
            while (divider > -1) {
                divider--;
                result = result + 100 / divider;
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            System.out.println("循环抛出异常!");
        }finally {
            /**
             * finally 语句块是在 try 语句块和 catch 语句块中的 return 语句执行完之后返回到调用者之前执行的
             */
            System.out.println("这是finally!");
            System.out.println("我是Result!我的值是:"+result);
        }
        System.out.println("test3执行完了!");
        /*
         * 如果try...catch...finally语句块之内没有return语句,就会调用这三个语句块之外的return语句
         */
        return 1111;
    }
}

输出:

java.lang.ArithmeticException: / by zero
    at com.anoscxy.TryCatchTest.test(TryCatchTest.java:31)
    at com.anoscxy.TryCatchTest.main(TryCatchTest.java:8)
循环抛出异常!
test()方法,执行完毕!返回值为:-1
java.lang.ArithmeticException: / by zero
    at com.anoscxy.TryCatchTest.test2(TryCatchTest.java:48)
    at com.anoscxy.TryCatchTest.main(TryCatchTest.java:10)
循环抛出异常!
这是finally!
我是Result!我的值是:999
test2()方法,执行完毕!返回值为:999
java.lang.ArithmeticException: / by zero
    at com.anoscxy.TryCatchTest.test3(TryCatchTest.java:71)
    at com.anoscxy.TryCatchTest.main(TryCatchTest.java:12)
循环抛出异常!
这是finally!
我是Result!我的值是:381
test3执行完了!
test3()方法,执行完毕!返回值为:1111

1.4 练习题

这里写图片描述
(A)
解析:
try 语句块不可以独立存在,必须与 catch 或者 finally 块同存

1.5 Java 中的异常抛出以及自定义异常

这里写图片描述
某方法调用了会抛出异常的方法时的处理方法有两种?
1. 当调用者可以处理异常时,用try…catch语句块尝试捕获并处理异常
2. 当调用者不能处理异常时,添加throws声明将异常抛给更上层的调用者去处理

会抛出异常的方法:声明抛出的异常
这里写图片描述

处理方法一:当调用者可以处理异常时,用try…catch语句块尝试捕获并处理异常
这里写图片描述

处理方法二:当调用者不能处理异常时,添加throws声明将异常抛给更上层的调用者去处理
这里写图片描述
这里写图片描述
这里写图片描述

package com.anoscxy;

public class DrunkException extends Exception {
    public DrunkException() {

    }

    public DrunkException(String message) {
        // TODO Auto-generated constructor stub
        super(message);

    }
}

1.6 练习题

这里写图片描述
(C)
解析:
Exception 是异常类,自定义异常要继承于 Exception 类或者其子类

1.6 Java 中的异常链

新的异常中包含原始异常的所有信息,根据这点可以追溯最初异常发生的位置
异常链的两种写法:
方法一:通过调用新异常的initCause方法去引用原始异常从而实现了异常链的功能

package com.anoscxy;

public class ChainTest {

    public static void main(String[] args) {
        ChainTest ct = new ChainTest();
        try {
            ct.test2();
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }

    public void test1() throws DrunkException {
        // TODO Auto-generated method stub
        throw new DrunkException("喝车别开酒!");
    }

    public void test2() {
        try {
            // TODO Auto-generated method stub
            test1();
        } catch (Exception e) {
            // TODO: handle exception
            RuntimeException newExc = new RuntimeException("司机一滴酒,亲人两行泪!");
            newExc.initCause(e); // 通过调用新异常的initCause方法去引用原始异常从而实现了异常链的功能
            throw newExc;
        }
    }
}

方法二:老异常传入新异常的构造方法中,从而实现了异常链的功能

public void test2() {
    try {
        // TODO Auto-generated method stub
        test1();
    } catch (Exception e) {
        // TODO: handle exception
        RuntimeException newExc = new RuntimeException(e);
//          newExc.initCause(e); // 通过调用新异常的initCause方法去引用原始异常从而实现了异常链的功能
        throw newExc;
    }
}

1.8 练习题

这里写图片描述
(D)
解析:
捕获到的异常,可以在当前方法的 catch 块中处理,也可抛出给调用者去处理

1.9 经验总结

这里写图片描述

2 认识 Java 中的字符串

2.1 什么是 Java 中的字符串

这里写图片描述

2.2 Java 中字符串的不变性

这里写图片描述
这里写图片描述
这里写图片描述

2.3 Java 中 String 类的常用方法 Ⅰ

这里写图片描述
这里写图片描述
结合代码来熟悉一下方法的使用:

public static void main(String[] args) {
        String str = "学习 JAVA 编程";
        System.out.println("字符串长度:"+str.length());
        char c = '编';
        System.out.println("字符串‘编’的位置:"+str.indexOf(c));
        System.out.println("字符串‘JAVA’的位置:"+str.indexOf("JAVA"));
        System.out.println("字符串'imooc'的位置:"+str.indexOf("imooc"));
        String[] arr = str.split(" ");
        System.out.print("按空格拆分成数组:"+Arrays.toString(arr));
        System.out.println();
        System.out.println("获取位置[3,7]之间的字符串:"+str.substring(3,7));
}

运行结果:

字符串长度:10
字符串‘编’的位置:8
字符串‘JAVA’的位置:3
字符串'imooc'的位置:-1
按空格拆分成数组:[学习, JAVA, 编程]
获取位置[3,7]之间的字符串:JAVA

友情提示:

  1. 字符串 str 中字符的索引从0开始,范围为 0 到 str.length()-1
  2. 使用 indexOf 进行字符或字符串查找时,如果匹配返回位置索引;如果没有匹配结果,返回 -1
  3. 使用 substring(beginIndex , endIndex) 进行字符串截取时,包括 beginIndex 位置的字符,不包括 endIndex 位置的字符
    针对如此繁杂的方法,推荐大家一个学习技巧:好记性不如烂笔头!多看的同时一定要多敲哦~~

任务
亲,让我们赶紧来做个练习吧。

功能:判断 Java 文件名是否正确,判断邮箱格式是否正确。其中:合法的文件名应该以 .java 结尾;合法的邮箱名中至少要包含 “@” , 并要求 “@” 在 “.” 之前
请参考注释,在编辑器中的第 16、19、22、36 行中将代码填写完整

运行结果:
这里写图片描述

public class HelloWorld {
    public static void main(String[] args) {
        // Java文件名
        String fileName = "HelloWorld.java"; 
        // 邮箱
        String email = "[email protected]";

        // 判断.java文件名是否正确:合法的文件名应该以.java结尾
        /*
        参考步骤:
        1、获取文件名中最后一次出现"."号的位置
        2、根据"."号的位置,获取文件的后缀
        3、判断"."号位置及文件后缀名
        */
        //获取文件名中最后一次出现"."号的位置
        int index = fileName.lastIndexOf(".");

        // 获取文件的后缀
        String prefix = fileName.substring(index+1,fileName.length());

        // 判断必须包含"."号,且不能出现在首位,同时后缀名为"java"
        if (index!=-1&&index!=0&&prefix.equals("java")                                 ) {
            System.out.println("Java文件名正确");
        } else {
            System.out.println("Java文件名无效");
        }

        // 判断邮箱格式是否正确:合法的邮箱名中至少要包含"@", 并且"@"是在"."之前
         /*
        参考步骤:
        1、获取文件名中"@"符号的位置
        2、获取邮箱中"."号的位置
        3、判断必须包含"@"符号,且"@"必须在"."之前
        */
        // 获取邮箱中"@"符号的位置
        int index2 = email.indexOf("@");

        // 获取邮箱中"."号的位置
        int index3 = email.indexOf('.');

        // 判断必须包含"@"符号,且"@"必须在"."之前
        if (index2 != -1 && index3 > index2) {
            System.out.println("邮箱格式正确");
        } else {
            System.out.println("邮箱格式无效");
        }
    }
}

2.4 Java 中的 String 类常用方法 Ⅱ

我们继续来看 String 类常用的方法,如下代码所示:

public static void main(String[] args) {
    // TODO Auto-generated method stub
    String str = "学习 JAVA 编程";
    System.out.println("转换为小写:"+str.toLowerCase());
    System.out.println("获取索引为1位置的字符:"+str.charAt(1));
    byte[] b = str.getBytes();
    System.out.println("转换为字节数组:");
    for(int i=0;i<b.length;i++) {
        System.out.print(b[i]+" ");
    }
    System.out.println();
    String str2 = new String("学习 JAVA 编程");
    System.out.println("str 和 str2 的内存地址相同?" + (str == str2));
    System.out.println("str 和 str2 的内容相同?"+str.equals(str2));
}

运行结果:

获取索引为1位置的字符:习
转换为字节数组:
-27 -83 -90 -28 -71 -96 32 74 65 86 65 32 -25 -68 -106 -25 -88 -117 
str 和 str2 的内存地址相同?false
str 和 str2 的内容相同?true

那么,“==” 和 equals() 有什么区别呢?
==: 判断两个字符串在内存中首地址是否相同,即判断是否是同一个字符串对象

equals(): 比较存储在两个字符串对象中的内容是否一致

PS:字节是计算机存储信息的基本单位,1 个字节等于 8 位, gbk 编码中 1 个汉字字符存储需要 2 个字节,1 个英文字符存储需要 1 个字节。所以我们看到上面的程序运行结果中,每个汉字对应两个字节值,如“学”对应 “-47 -89” ,而英文字母 “J” 对应 “74” 。同时,我们还发现汉字对应的字节值为负数,原因在于每个字节是 8 位,最大值不能超过 127,而汉字转换为字节后超过 127,如果超过就会溢出,以负数的形式显示。(关于编码,我们在后面课程中会详细介绍,小小期待哦~~)

任务
亲,让我们赶紧来做个练习巩固一下吧。

功能:统计指定字符串中字符 ‘a’ 出现的次数

分析:可以通过循环遍历字符串中的每一个字符,判断是否是字符 a ,如果是,则累加统计出现的次数

请在编辑器中的第 10、13 行中将代码填写完整

运行结果:字符a出现的次数:8

public static void main(String[] args) {
    // 定义一个字符串
    String s = "aljlkdsflkjsadjfklhasdkjlflkajdflwoiudsafhaasdasd";

       // 出现次数
    int num = 0;

        // 循环遍历每个字符,判断是否是字符 a ,如果是,累加次数
    for (int i=0;i<s.length();i++)
    {
           // 获取每个字符,判断是否是字符a
        if (s.charAt(i) == 'a') {
               // 累加统计次数
            num++; 
        }
    }
    System.out.println("字符a出现的次数:" + num);
}

2.5 认识 Java 中的 StringBuilder 类

在Java中,除了可以使用 String 类来存储字符串,还可以使用 StringBuilder 类或 StringBuffer 类存储字符串,那么它们之间有什么区别呢?

String 类具有是不可变性。如

public static void main(String[] args) {
    // TODO Auto-generated method stub
    String str = "hello";
    System.out.println(str + "world");
    System.out.println(str);
}

运行结果:

helloworld
hello

从运行结果中我们可以看到,程序运行时会额外创建一个对象,保存 “helloworld”。当频繁操作字符串时,就会额外产生很多临时变量。使用 StringBuilder 或 StringBuffer 就可以避免这个问题。至于 StringBuilder 和StringBuffer ,它们基本相似,不同之处,StringBuffer 是线程安全的,而 StringBuilder 则没有实现线程安全功能,所以性能略高。因此一般情况下,如果需要创建一个内容可变的字符串对象,应优先考虑使用 StringBuilder 类。

那么如何定义 StringBuilder 类的对象呢? 我们来看下面的代码:

public static void main(String[] args) {
    StringBuilder str1=new StringBuilder();
    StringBuilder str2=new StringBuilder("imooc");
    System.out.println(str2);
}

运行结果:

imooc

任务

在编辑器中定义了一个 StringBuilder 对象,用来存储字符串。认识一下他吧!!

public static void main(String[] args) {  
     // 创建一个StringBuilder对象,用来存储字符串
    StringBuilder hobby=new StringBuilder("爱慕课");  
    System.out.println(hobby);
}

2.6 Java 中的 StringBuilder 类的常用方法

StringBuilder 类提供了很多方法来操作字符串:
这里写图片描述

public static void main(String[] args) {
    StringBuilder str = new StringBuilder("hello");
    str.append(" imooc");
    str.append(520);
    System.out.println("字符串长度:"+str.length());
    System.out.println("插入前:"+str);

    str.insert(11,"!");
    String str2 = str.toString();
    System.out.println("插入后:"+str2);
}

运行结果:

字符串长度:14
插入前:hello imooc520
插入后:hello imooc!520

任务

功能:将一个由英文字母组成的字符串转换成指定格式—从右边开始每三个字母用逗号分隔的形式。

请在编辑器中的第 4、10 行将代码填写完整

运行效果: j,aew,kjl,dfx,mop,zdm

public static void main(String[] args) {
    // 创建一个空的StringBuilder对象
    StringBuilder str = new StringBuilder();
    // 追加字符串
    str.append("jaewkjldfxmopzdm");
       // 从后往前每隔三位插入逗号
    for(int i=str.length()-3;i>0;i=i-3){
        str.insert(i,',');
    }
       // 将StringBuilder对象转换为String对象并输出
    System.out.print(str.toString());
}

2.7 单选练习题

这里写图片描述
(B)
解析
在需要频繁对字符串进行修改操作时使用 StringBuilder 的效率比 String 要高,所以选项 B 的说法不正确,选择 B

3 Java 中必须了解的常用类

3.1 Java 中的包装类

相信各位小伙伴们对基本数据类型都非常熟悉,例如 int、float、double、boolean、char 等。基本数据类型是不具备对象的特性的,比如基本类型不能调用方法、功能简单。。。,为了让基本数据类型也具备对象的特性, Java 为每个基本数据类型都提供了一个包装类,这样我们就可以像操作对象那样来操作基本数据类型。

基本类型和包装类之间的对应关系:
这里写图片描述

包装类主要提供了两大类方法:
1. 将本类型和其他基本类型进行转换的方法
2. 将字符串和本类型及包装类互相转换的方法
我们将在后面的小节逐步讲解,表着急哦~~

任务
我们以 Integer 包装类为例,来看下包装类的特性。

Integer 包装类的构造方法:
这里写图片描述

如下代码所示:

public static void main(String[] args) {
    Integer m = new Integer(5);
    Integer n = new Integer("8");
    System.out.println("m="+m.intValue());
    System.out.println("n="+n.intValue());
}

Integer包装类的常用方法:
这里写图片描述

编辑器中列举了 Integer 类型和基本数据类型之间的转换,结合运行结果先认识一下吧!

public static void main(String[] args) {
    int score1 = 86;
    Integer score2 = new Integer(score1);
    double score3 = score2.doubleValue();
    float score4 = score2.floatValue();
    int score5 = score2.intValue();
    System.out.println("double 类型:"+score3);
    System.out.println("float 类型:"+score4);
    System.out.println("int 类型:"+score5);
}

运行结果:

double类型:86.0
float类型:86.0
int类型:86

3.3 Java 中基本类型和包装类之间的转换

基本类型和包装类之间经常需要互相转换,以 Integer 为例(其他几个包装类的操作雷同哦):

public static void main(String[] args) {
    Integer a = new Integer(3);
    int b = a +5;
    System.out.println(b);
}

在 JDK1.5 引入自动装箱和拆箱的机制后,包装类和基本类型之间的转换就更加轻松便利了。

那什么是装箱和拆箱呢?我们分别来看下
装箱:把基本类型转换成包装类,使其具有对象的性质,又可分为手动装箱和自动装箱

public static void main(String[] args) {
    int i = 10;
    Integer x = new Integer(i); // 手动装箱
    Integer y = i; // 自动装箱
}

拆箱:和装箱相反,把包装类对象转换成基本类型的值,又可分为手动拆箱和自动拆箱

public static void main(String[] args) {
    Integer j = new Integer(8);
    int m = j.intValue(); // 手动拆箱
    int n = j; // 自动拆箱
}

任务
在编辑器中完成了基本类型和包装类之间的转换,即装箱和拆箱的操作。
请参考注释将 8、11、19、22 代码补充完整
运行结果为:
这里写图片描述

public static void main(String[] args) {

       // 定义double类型变量
    double a = 91.5;

        // 手动装箱
    Double b = new Double(a);        

       // 自动装箱
    Double c =  a;     

       System.out.println("装箱后的结果为:" + b + "和" + c);

       // 定义一个Double包装类对象,值为8
    Double d = new Double(87.0);

       // 手动拆箱
    double e = d.doubleValue();

       // 自动拆箱
    double f = d;

        System.out.println("拆箱后的结果为:" + e + "和" + f);
}

运行结果:

装箱后的结果为:91.5和91.5
拆箱后的结果为:87.0和87.0

3.3 单选练习题

这里写图片描述
解析:
基本类型 int 无法直接转换为包装类 Long 类型,所以选项 C 说法不正确,选择 C

3.4 Java 中基本类型和字符串之间的转换

在程序开发中,我们经常需要在基本数据类型和字符串之间进行转换。

其中,基本类型转换为字符串有三种方法:
1. 使用包装类的 toString() 方法
2. 使用String类的 valueOf() 方法
3. 用一个空字符串加上基本类型,得到的就是基本类型数据对应的字符串

public static void main(String[] args) {
    int c = 10;
    String str1 = Integer.toString(c);
    String str2 = String.valueOf(c);
    String str3 = c + "";
}

再来看,将字符串转换成基本类型有两种方法:
1. 调用包装类的 parseXxx 静态方法
2. 调用包装类的 valueOf() 方法转换为基本类型的包装类,会自动拆箱

public static void main(String[] args) {
    String str = "8";
    int d = Integer.parseInt(str);
    int e = Integer.valueOf(str);
}

PS:其他基本类型与字符串的相互转化这里不再一一列出,方法都类似

任务
在编辑器中完成了基本类型和字符串之间的转换。
运行结果为:
这里写图片描述
请将 6、12 行代码填写完整

public static void main(String[] args) {

    double m = 78.5;
    //将基本类型转换为字符串
    String str1 = Double.toString(m);                             ;

    System.out.println("m 转换为String型后与整数20的求和结果为: "+(str1+20));

    String str = "180.20";
    // 将字符串转换为基本类型
    Double a = Double.parseDouble(str);

    System.out.println("str 转换为double型后与整数20的求和结果为: "+(a+20));
}
m 转换为String型后与整数20的求和结果为: 78.520
str 转换为double型后与整数20的求和结果为: 200.2

3.5 单选练习题

这里写图片描述
解析
基本类型是不能调用方法的,而其包装类具有很多方法,所以选项 B 的说法不正确,选择 B

3.6 使用 Date 和 SimpleDateFormat 类表示时间

在程序开发中,经常需要处理日期和时间的相关数据,此时我们可以使用 java.util 包中的 Date 类。这个类最主要的作用就是获取当前时间,我们来看下 Date 类的使用:

public static void main(String[] args) {
    Date d = new Date();
    System.out.println(d);
}

使用 Date 类的默认无参构造方法创建出的对象就代表当前时间,我们可以直接输出 Date 对象显示当前的时间,显示的结果如下:
这里写图片描述
其中, Wed 代表 Wednesday (星期三), Jun 代表 June (六月), 11 代表 11 号, CST 代表 China Standard Time (中国标准时间,也就是北京时间,东八区)。

从上面的输出结果中,我们发现,默认的时间格式不是很友好,与我们日常看到的日期格式不太一样,如果想要按指定的格式进行显示,如 2014-06-11 09:22:30 ,那该怎么做呢?

此时就到了 java.text 包中的 SimpleDateFormat 类大显身手的时候了!!可以使用 SimpleDateFormat 来对日期时间进行格式化,如可以将日期转换为指定格式的文本,也可将文本转换为日期。

  1. 使用 format() 方法将日期转换为指定格式的文本
public static void main(String[] args) {
    Date d = new Date();
    // 创建SimpleDateFormat对象,指定目标格式
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    // 调用format()方法,格式化时间,转换为指定格式字符串
    String today = sdf.format(d);
    System.out.println(today);
}

代码中的 “yyyy-MM-dd HH:mm:ss” 为预定义字符串, yyyy 表示四位年, MM 表示两位月份, dd 表示两位日期, HH 表示小时(使用24小时制), mm 表示分钟, ss 表示秒,这样就指定了转换的目标格式,最后调用 format() 方法将时间转换为指定的格式的字符串。
运行结果:2017-12-22 14:04:55

  1. 使用 parse() 方法将文本转换为日期
public static void main(String[] args) {
    String day = "2014年02月14日 10:30:25";
    SimpleDateFormat df = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
    try {
        Date date = df.parse(day);
        System.out.println("当前时间:"+date);
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

代码中的 “yyyy年MM月dd日 HH:mm:ss” 指定了字符串的日期格式,调用 parse() 方法将文本转换为日期。
运行结果:当前时间:Fri Feb 14 10:30:25 CST 2014

一定要注意哦:
1. 调用 SimpleDateFormat 对象的 parse() 方法时可能会出现转换异常,即 ParseException ,因此需要进行异常处理
2. 使用 Date 类时需要导入 java.util 包,使用 SimpleDateFormat 时需要导入 java.text 包

任务
亲, Date 类和 SimpleDateFormat 类的使用您掌握了吗?让我们来检验下吧。
功能:实现将日期转换为指定格式的文本,将文本转换为日期请在编辑器中的第 15、18、27 行中将代码填写完整
运行结果:
这里写图片描述

public static void main(String[] args) throws ParseException {  
    // 使用format()方法将日期转换为指定格式的文本
    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
    SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy/MM/dd HH:mm");
    SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    // 创建Date对象,表示当前时间
       Date now = new Date();

       // 调用format()方法,将日期转换为字符串并输出
    System.out.println(sdf1.format(now));
    System.out.println(sdf2.format(now));
    System.out.println(sdf3.format(now));

    // 使用parse()方法将文本转换为日期
    String d = "2014-6-1 21:05:36";
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        // 调用parse()方法,将字符串转换为日期
    Date date = sdf.parse(d);

    System.out.println(date);
}

输出

2017年12月22日 14时32分32秒
2017/12/22 14:32
2017-12-22 14:32:32
Sun Jun 01 21:05:36 CST 2014

3.7 Calendar 类的应用

Date 类最主要的作用就是获得当前时间,同时这个类里面也具有设置时间以及一些其他的功能,但是由于本身设计的问题,这些方法却遭到众多批评,不建议使用,更推荐使用 Calendar 类进行时间和日期的处理。
java.util.Calendar 类是一个抽象类,可以通过调用 getInstance() 静态方法获取一个 Calendar 对象,此对象已由当前日期时间初始化,即默认代表当前时间,如 Calendar c = Calendar.getInstance();

那么如何使用 Calendar 获取年、月、日、时间等信息呢?我们来看下面的代码:

public static void main(String[] args) {
    Calendar c = Calendar.getInstance();
    int year = c.get(Calendar.YEAR);
    int month = c.get(Calendar.MONTH);
    int day = c.get(Calendar.DATE);
    int hour = c.get(Calendar.HOUR);
    int minute = c.get(Calendar.MINUTE);
    int second = c.get(Calendar.SECOND);
    System.out.println("当前时间:"+year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second);
}

其中,调用 Calendar 类的 getInstance() 方法获取一个实例,然后通过调用 get() 方法获取日期时间信息,参数为需要获得的字段的值, Calendar.Year 等为 Calendar 类中定义的静态常量。
运行结果: 当前时间:2017-11-22 2:40:45

Calendar 类提供了 getTime() 方法,用来获取 Date 对象,完成 Calendar 和 Date 的转换,还可通过 getTimeInMillis() 方法,获取此 Calendar 的时间值,以毫秒为单位。如下所示:

public static void main(String[] args) {
    Calendar c = Calendar.getInstance();
    Date date = c.getTime();
    Long time = c.getTimeInMillis();
    System.out.println("当前时间:"+date);
    System.out.println("当前毫秒数:"+time);
}

运行结果:

当前时间:Fri Dec 22 14:44:22 CST 2017
当前毫秒数:1513925062040

任务
亲, Calendar 类的使用您掌握了吗?让我们来检验下吧。
代码编辑器中实现获取 Calendar 对象,并转换为指定格式的时间。请将第 9、12 行代码补充完整
运行结果:
这里写图片描述

public static void main(String[] args) {
    // 创建Calendar对象
    Calendar c = Calendar.getInstance();

    // 将Calendar对象转换为Date对象
    Date date = c.getTime();

    // 创建SimpleDateFormat对象,指定目标格式
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    // 将日期转换为指定格式的字符串
    String now = sdf.format(date);
    System.out.println("当前时间:" + now);
}

输出

当前时间:2017-12-22 14:47:49

3.8 使用 Math 类操作数据

Math 类位于 java.lang 包中,包含用于执行基本数学运算的方法, Math 类的所有方法都是静态方法,所以使用该类中的方法时,可以直接使用类名.方法名,如: Math.round();

常用的方法:
这里写图片描述

通过案例我们来认识一下他们的使用吧!!

public static void main(String[] args) {
    double a = 12.81;
    int b = (int)a;
    System.out.println("强制类型转换:"+b);
    long c = Math.round(a); // 调用round方法,进行四舍五入
    System.out.println("四舍五入:"+c);
    double d = Math.floor(a); // 调用floor方法。返回小于参数的最大整数
    System.out.println("floor:"+d);
    double e = Math.ceil(a); // 调用ceil方法,返回大于参数的最小整数
    System.out.println("ceil:"+e);
    double x = Math.random(); // 调用random方法,返回[0,1)之间的随机数浮点数
    System.out.println("随机数:"+x);
    int y = (int)(Math.random()*99); // 产生[0,99)之间的随机整数
    System.out.println("产生[0,99)之间的随机整数:"+y);
}

运行结果:

强制类型转换:12
四舍五入:13
floor:12.0
ceil:13.0
随机数:0.5453799978883686
产生[0,99)之间的随机整数:22

PS: Math 类还提供了许多其他方法,各位小伙伴们可以注意关注 wiki ,查阅更多信息

任务
功能:定义一个包含 10 个元素的整型数组,通过随机产生 10 以内的随机数,给数组中的每个元素赋值,并输出结果。
运行结果: 0 3 3 2 6 3 2 7 0 9
注:由于数组元素值为随机产生,所以运行结果不固定,此运行结果仅作为示例
请在编辑器中的第 6、11、17 行中将代码填写完整

public static void main(String[] args) {

    // 定义一个整型数组,长度为10
    int[] nums = new int[10];

    //通过循环给数组赋值
    for (int i = 0; i < nums.length; i++) {
        // 产生10以内的随机数
        int x = (int)(Math.random()*10);

        nums[i] = x;// 为元素赋值
    }

    // 使用foreach循环输出数组中的元素
    for (int num : nums) {
        System.out.print(num + " ");
    }
}

输出

9 2 4 0 4 8 4 1 1 8 

4 Java 中的集合框架

4.1 Java 中的集合框架概述

这里写图片描述
这里写图片描述
这里写图片描述

Collection:存储的是单身汪
接口: List:序列、Queue:队列、Set:集、
实现类: ArrayList:数组序列、LinkedList:链表、HashSet:哈希集

接口: Map:存储的是一对一对的夫妇
实现类: HashMap:哈希表

ArrayList、HashSet、HashMap使用频率最高
这里写图片描述

4.2 Collection 接口 & List 接口简介

这里写图片描述
这里写图片描述

4.3 学生选课

这里写图片描述

备选课程类

/**
 * 备选课程类
 * @author BG235144
 *
 */
public class ListTest {
    /**
     * 用于存放备选课程的List
     */
    public List coursesToSelect;
    public ListTest() {
        this.coursesToSelect = new ArrayList();
    }

    /**
     * 用于往coursesToSelect中添加课程的方法,
     * List中的元素是有序可重复的
     */
    public void testAdd() {
        /**
         * 创建一个课程对象,并通过add方法添加到List当中去
         */
        Course cr1 = new Course("1","数据结构");
        coursesToSelect.add(cr1);
        /**
         * 对象存入集合中都会变成Object类型,
         * 取出时需要类型转换
         */
        Course temp = (Course) coursesToSelect.get(0);
        System.out.println(temp);

        Course cr2 = new Course("2","c语言");
        coursesToSelect.add(0, cr2);
        Course temp2 = (Course)coursesToSelect.get(0);
        System.out.println(temp2);

        coursesToSelect.add(cr1);
        /**
         * 对象存入集合中都会变成Object类型,
         * 取出时需要类型转换
         */
        Course temp0 = (Course) coursesToSelect.get(2);
        System.out.println(temp0);

//      Course cr3 = new Course("3","test");
        /**
         * bug:java.lang.IndexOutOfBoundsException: Index: 4, Size: 2,
         * 数组越界
         */
//      coursesToSelect.add(4,cr3);
        Course[] course = {new Course("3","离散数学"), new Course("4","汇编语言")};
        coursesToSelect.addAll(Arrays.asList(course));
        Course cr3 = (Course)coursesToSelect.get(3);
        Course cr4 = (Course)coursesToSelect.get(4);
        System.out.println(cr3 + "\n" + cr4);

        Course[] course2 = {new Course("5","高等数学"), new Course("6","汇编大学英语")};
        coursesToSelect.addAll(2,Arrays.asList(course2));
        Course cr5 = (Course)coursesToSelect.get(2);
        Course cr6 = (Course)coursesToSelect.get(3);
        System.out.println(cr5+"\n"+cr6);
    }

    /**
     * 取得List中的元素的方法,
     */
    public void testGet() {
        int size = coursesToSelect.size();
        System.out.println("有如下课程待选:");
        for(int i=0;i<size;i++) {
            Course cr = (Course)coursesToSelect.get(i);
            System.out.println(cr);
        }
    }

    /**
     * 通过迭代器来遍历List
     */
    public void testIterator() {
        /**
         * 通过集合的iterator方法,取得迭代器的实例
         */
        Iterator it = coursesToSelect.iterator();
        System.out.println("有如下课程待选(通过迭代器访问):");
        while(it.hasNext()) { // 如果还有元素就返回true
            Course cr = (Course)it.next();
            System.out.println(cr);
        }
    }

    /**
     * 通过for each方法访问集合元素
     */
    public void testForEach() {
        System.out.println("有如下课程待选(通过for each访问):");
        for(Object obj:coursesToSelect) {
            Course cr = (Course)obj;
            System.out.println(cr);
        }
    }

    /**
     * 修改List中的元素
     * @param args
     */
    public void testModify() {
        System.out.println("有如下课程待选(通过set修改):");
        coursesToSelect.set(4, new Course("7","毛概"));
        testForEach();
    }

    /**
     * 删除List中的元素
     * @param args
     */
    public void testRemove() {
        /**
         * remove(Object)
         */
//      Course cr = (Course)coursesToSelect.get(4);
//      System.out.println("我是课程:"+cr.id+"我即将被删除");
//      coursesToSelect.remove(cr);
//      System.out.println("成功删除课程:"+cr.id);
        /**
         * remove(id)
         */
//      System.out.println("我是课程:"+4+",我即将被删除");
//      coursesToSelect.remove(4);
//      System.out.println("成功删除课程:"+4);

        /**
         * removeAll(list)
         */
        System.out.println("即将删除4位置和5位置上的课程!");
        Course[] courses = {(Course)coursesToSelect.get(4),(Course)coursesToSelect.get(5)};
        coursesToSelect.removeAll(Arrays.asList(courses));
        System.out.println("成功删除课程4位置和5位置上的课程:");
        testForEach();
    }

    /**
     * 往List中添加一些奇怪的东西
     * @param args
     */
    public void testType() {
        System.out.println("能否往List中添加一些奇怪的东西呢?");
        coursesToSelect.add("我不是课程,我只是一个无辜的字符串!");
        testForEach();
    }

    public static void main(String[] args) {
        ListTest lt = new ListTest();
        lt.testAdd();
        /**
         * bug:Exception in thread "main" java.lang.ClassCastException: 
         * java.lang.String cannot be cast to com.amoscxy.Course
         */
        lt.testType();
        System.out.println();
        lt.testGet();
        System.out.println();
        lt.testIterator();
        System.out.println();
        lt.testForEach();
        System.out.println();
        lt.testModify();
        System.out.println();
        lt.testRemove();
    }
}

学生类

/**
 * 学生类
 * @author BG235144
 *
 */
public class Student {

    public String id;
    public String name;
    public Set course;
    public Student(String id, String name) {
        this.id = id;
        this.name = name;
        this.course = new HashSet();
    }
}

课程类

/**
 * 课程类
 * @author BG235144
 *
 */
public class Course {

    public String id;
    public String name;
    public Course(String id, String name) {
        this.id = id;
        this.name = name;
    }
    public Course() {

    }
    @Override
    public String toString() {
        return "Course [id=" + id + ", name=" + name + "]";
    }
}
public class ChildCourse extends Course{
    public String id;
    public String name;
    public ChildCourse(String id, String name) {
        this.id = id;
        this.name = name;
    }
    public ChildCourse() {

    }
    @Override
    public String toString() {
        return "Course [id=" + id + ", name=" + name + "]";
    }
}

4.4 学生选课—应用泛型管理课程

这里写图片描述

public class TestGeneric {

    /**
     * 带有泛型---Course的List类型属性
     */
    public List<Course> courses; 
    public TestGeneric() {
        this.courses = new ArrayList<Course>();
    }

    /**
     * 测试添加
     */
    public void testAdd() {
        Course cr1 = new Course("1","大学语文");
        courses.add(cr1);
        /**
         * 泛型集合中,
         * 不能添加泛型规定的类型及其子类型以外的对象,
         * 否则会报错
         */
//      courses.add("能否添加一些奇怪的东西呢?");
        Course cr2 = new Course("2","Java基础");
        courses.add(cr2);
        testForEach();
    }

    /**
     * 测试循环遍历
     */
    public void testForEach() {
        for(Course cr:courses) {
            System.out.println(cr);
        }
    }

    /**
     * 泛型集合可以添加泛型的子类型的对象实例
     */
    public void testChild() {
        System.out.println("泛型集合可以添加泛型的子类型的对象实例:");
        ChildCourse ccr = new ChildCourse();
        ccr.id = "3";
        ccr.name = "我是子类型的课程对象实例";
        courses.add(ccr);
        testForEach();
    }

    /**
     * 泛型必须是引用类型,
     * 如果要使用基本类型,可以用它们的包装类
     */
    public void testBasicType() {
        System.out.println("基本类型不能用于泛型,如果要用,就用它们的包装类:");
        /**
         * 基本类型不能用于泛型
         */
//      List<int> list = new List<int>();
        List<Integer> list = new ArrayList<Integer>();
        list.add(1);
        System.out.println("基本类型的包装类作为泛型:"+list.get(0));
    }

    /**
     * 
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        TestGeneric tg = new TestGeneric();
        tg.testAdd();
        System.out.println();
        tg.testChild();
        System.out.println();
        tg.testBasicType();
    }
}

4.5 学生选课—通过 Set 集合管理课程

这里写图片描述
Set中,添加某个对象,无论添加多少次,最终只会保留一个该对象(的引用),并且,保留的是第一次添加的那一个

这里写图片描述
这里写图片描述

// 打印输出学生所选的课程
public void testForEachForSet(Student student) {
    /**
     * 遍历Set中的每一个元素只能用foreach或者iterator方法,
     * 不能用get方法,
     * 因为Set中的元素是无序的,
     * 因此只能用foreach循环或iterator循环将元素一个一个迭代出来,
     * 每一次迭代出来的结果都是不一样的
     * 
     */
    for(Course cr:student.courses) {
        System.out.println(cr);
    }
}

5 Java 中的集合框架(中)

5.1 Map & HashMap 简介

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

5.2 学生选课—使用 Map 添加学生、删除 Map 中的学生、修改 Map 中的学生

public class MapTest {

    /**
     * 用来承装学生类型对象
     * @param args
     */
    public Map<String,Student> students;

    /**
     * 在构造器中初始化students属性
     * @param args
     */
    public MapTest() {
        this.students = new HashMap<String,Student>();
    }

    /**
     * 测试添加:输入学生ID,判断是否被占用,
     * 若未被占用,则输入姓名,创建新学生对象,并且添加到Students中
     * @param args
     */
    public void testPut() {
        // 创建一个Scanner对象,用来获取输入的学生ID和姓名
        Scanner console = new Scanner(System.in);
        int i = 0;
        while(i < 3) {
            System.out.println("请输入学生ID:");
            String ID = console.next();
            // 判断该ID是否被占用
            Student st = students.get(ID);
            if(st == null) {
                // 提示输入学生姓名
                System.out.println("请输入学生姓名:");
                String name = console.next();
                // 创建新的学生对象
                Student newStudent = new Student(ID,name);
                // 通过调用student的put方法,添加ID-学生映射
                students.put(ID, newStudent);
                System.out.println("成功添加学生:"+students.get(ID).name);
                i++;
            }else {
                System.out.println("该学生ID已被占用!");
                continue;
            }
        }
    }

    /**
     * 测试Map的keySet方法
     * @param args
     */
    public void testKeySet() {
        /**
         * Map的keySet方法,返回的是所有key的Set集合
         */
        Set<String> keySet = students.keySet();
        // 取得students的容量
        System.out.println("总共有:"+students.size()+"个学生!");
        // 遍历keySet,取得每一个键,再调用get方法取得每个键对应的value
        for(String stuID:keySet) {
            Student st = students.get(stuID);
            if(st!=null) {
                System.out.println("学生:"+st.name);
            }
        }
    }

    /**
     * 测试删除Map中的映射
     * @param args
     */
    public void testRemove() {
        // 获取从键盘输入的待删除学生ID字符串
        Scanner console = new Scanner(System.in);
        while(true) {
            // 提示输入待删除的学生的ID
            System.out.println("请输入要删除的学生的ID!");
            String ID = console.next();
            // 判断该ID是否有对应的学生对象
            Student st = students.get(ID);
            if(st==null) {
                // 提示输入的ID并不存在
                System.out.println("该ID不存在!");
                continue;
            }
            students.remove(ID);
            System.out.println("成功删除学生:"+st.name);
            break;
        }
    }

    /**
     * 通过entrySet方法来遍历Map
     * @param args
     */
    public void testEntrySet() {
        // 通过entrySet方法,返回Map中的所有键值对
        Set<Entry<String,Student>> entrySet = students.entrySet();
        for(Entry<String,Student> entry:entrySet) {
            System.out.println("取得键:"+entry.getKey());
            System.out.println("对应的值为:"+entry.getValue().name);
        }
    }

    /**
     * 
     * @param args
     */
    public void testModity() {
        // 请输入要修改的学生ID
        System.out.println("请输入要修改的学生ID:");
        Scanner console = new Scanner(System.in);
        while(true){
            String stuID = console.next();
            Student student = students.get(stuID);
            if(student == null) {
                System.out.println("该ID不存在!请重新输入!");
                continue;
            }
            System.out.println("当前该学生ID,所对应的学生为:"+student.name);
            System.out.println("请输入新的学生姓名:");
            String name = console.next();
            Student newStudent = new Student(stuID,name);
            students.put(stuID, newStudent);
            System.out.println("修改成功!");
            break;
        }

    }

    public static void main(String[] args) {
        MapTest mt = new MapTest();
        mt.testPut();
        mt.testKeySet();
        mt.testRemove();
        mt.testEntrySet();
        mt.testModity();
        mt.testEntrySet();
    }
}

6 Java 中的集合框架(下)

6.1 学生选课—判断 List 中课程是否存在

这里写图片描述
这里写图片描述

/**
 * 测试List的contains方法
 * @param args
 */
public void testListContains() {
    Course course = (Course)coursesToSelect.get(0);
    System.out.println("取得课程:"+course.name);
    System.out.println("备选课程中是否包含课程:"+course.name
            +","+coursesToSelect.contains(course)); // true

    // 创建一个新的课程对象,ID和名称,与course对象完全一样
    Course course2 = new Course(course.id,course.name);
    System.out.println("新创建课程:"+course2.name);
    System.out.println("备选课程中是否包含课程:"+course2.name
            +","+coursesToSelect.contains(course2)); // false
}

List的contains(obj)的实现原理
这里写图片描述
Course 类中重写equals方法

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Course other = (Course) obj;
    if (id == null) {
        if (other.id != null)
            return false;
    } else if (!id.equals(other.id))
        return false;
    if (name == null) {
        if (other.name != null)
            return false;
    } else if (!name.equals(other.name))
        return false;
    return true;
}
/**
 * 测试List的contains方法
 * @param args
 */
public void testListContains() {
    Course course = (Course)coursesToSelect.get(0);
    System.out.println("取得课程:"+course.name);
    System.out.println("备选课程中是否包含课程:"+course.name
            +","+coursesToSelect.contains(course)); // true

    // 创建一个新的课程对象,ID和名称,与course对象完全一样
    Course course2 = new Course(course.id,course.name);
    System.out.println("新创建课程:"+course2.name);
    System.out.println("备选课程中是否包含课程:"+course2.name
            +","+coursesToSelect.contains(course2)); // true
}

判断是否包含多个元素
这里写图片描述

6.2 学生选课—判断 Set 中课程是否存在

这里写图片描述

/**
 * 测试Set的contains方法
 * @param args
 */
public void testSetContains() {
    System.out.println("请输入学生已选的课程名称:");
    Scanner console = new Scanner(System.in);
    String name = console.next();
    // 创建一个新的课程对象,ID和名称,与course对象完全一样
    Course course2 = new Course();
    course2.name = name;
    System.out.println("新创建课程:"+course2.name);
    System.out.println("备选课程中是否包含课程:"+course2.name
            +","+student.courses.contain(course2)); // false
}

Set的contains方法实现原理
这里写图片描述

重写Course的hashCode方法

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    return result;
}
/**
 * 测试Set的contains方法
 * @param args
 */
public void testSetContains() {
    System.out.println("请输入学生已选的课程名称:");
    Scanner console = new Scanner(System.in);
    String name = console.next();
    // 创建一个新的课程对象,ID和名称,与course对象完全一样
    Course course2 = new Course();
    course2.name = name;
    System.out.println("新创建课程:"+course2.name);
    System.out.println("备选课程中是否包含课程:"+course2.name
            +","+student.courses.contain(course2)); // true
}

6.3 学生选课—获取 List 中课程的位置

用 indexOf(Object) 方法来获取某元素的索引位置

if(coursesToSelect.contains(course2)) {
    System.out.println("课程:"+course2.name+"的索引位置为:"
            +"coursesToSelect.indexOf(course2)");
}

indexOf(Object)和lastIndexOf(Object)方法的工作原理
这里写图片描述

6.4 学生选课—判断 Map 中是否包含指定的 key 和 value

这里写图片描述

Student 中重写 equals(Object) 方法

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (!(obj instanceof Student))
        return false;
    Student other = (Student) obj;
    if (name == null) {
        if (other.name != null)
            return false;
    } else if (!name.equals(other.name))
        return false;
    return true;
}

在 Map 中,用 containsKey() 方法,来判断是否包含某个 Key 值,用 ContainsValue() 方法,来判断是否包含某个 Value 值

/**
 * 测试Map中,是否包含某个Key值或者某个Value值
 * @param args
 */
public void testContainsKeyOrValue() {
    /**
     * 在 Map 中,用 containsKey() 方法,来判断是否包含某个 Key 值,
     * 用 ContainsValue() 方法,来判断是否包含某个 Value 值
     */
    System.out.println("请输入学生id:");
    Scanner sid = new Scanner(System.in);
    System.out.println("请输入学生姓名:");
    Scanner sname = new Scanner(System.in);
    String id = sid.next();
    String name = sname.next();
    System.out.println("您输入的学生ID为:"+id+",在学生映射表中是否存在:"
            +students.containsKey(id));
    if(students.containsKey(id)) {
        System.out.println("对应的学生为:"+students.get(id).name);
    }
    System.out.println("您输入的学生Value为:"+name+",在学生映射表中是否存在:"
            +students.containsValue(name));
    if(students.containsValue(new Student(null,name))) {
        System.out.println("包含学生:"+name);
    }else {
        System.out.println("不包含学生:"+name);
    }

}

6.5 应用 Collections.sort() 实现 List 排序

这里写图片描述
这里写图片描述

6.6 学生选课—尝试对学生序列排序

这里写图片描述

6.7 Comparable & Comparator 简介

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

6.8 学生选课— 实现学生序列排序

实现 Comparable 接口 和 compareTo 方法

/**
 * 学生类
 * @author BG235144
 *
 */
public class Student implements Comparable<Student>{

    public String id;
    public String name;
    public Set<Course> courses;
    public Student(String id, String name) {
        this.id = id;
        this.name = name;
        this.courses = new HashSet<Course>();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof Student))
            return false;
        Student other = (Student) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    @Override
    public int compareTo(Student o) {
        // TODO Auto-generated method stub
        return this.id.compareTo(o.id);
    }
}

就可以对其它类型泛型的 List 进行排序,以 Student 为例

Collections.sort(studentList);

排序规则
这里写图片描述

实现 Comparator 接口
这里写图片描述
这里写图片描述

就可以对其它类型泛型的 List 进行排序,以 Student 为例

Collection.sort(studentList, new studentComparator());

这里写图片描述
以及它们的增删改查方法

这里写图片描述

猜你喜欢

转载自blog.csdn.net/amoscxy/article/details/78822908
今日推荐