Java学习总结

一、Java基础学习

1、变量与数据类型

1.1、变量的含义

变量就是内存中一块临时存放数据的区域。

1.2、变量的命名规则

  • 变量名由字母、数字、下划线、$这四种字符组成。
  • 变量名的首字符不能是数字
  • 变量名是区分大小写字母
  • 变量名不能是java关键字或保留字

1.3、变量的命名规范

  • 使用驼峰式命名
  • 望文生义
  • 写详细注释

1.4、java的八种基本数据类型

整型:byte、short、int、long
数据类型 占字节数 大小/位 数据范围
byte(字节型) 1 8 -128~127
short(短整型) 2 16 -32768~32767
int(整型) 4 32 -2147483648~2147483647
long(长整型) 8 64 -9223372036854775808~9223372036854775807
/**
 *八种基本数据类型:byte、short、int、long、float、double、char、boolean
 * 1、整型:
 * byte:字节型、占1个字节、8位
 * short:短整型、占2个字节、16位
 * int:整型、占4个字节、32位
 * long:长整型、占8个字节、64位
 */
public static void main(String[] args) {
    //byte:-128~127
    byte b = 10;
    byte byteMaxValue = Byte.MAX_VALUE;
    byte byteMinValue = Byte.MIN_VALUE;
    System.out.println("byteMaxValue = " + byteMaxValue);
    System.out.println("byteMinValue = " + byteMinValue);
    System.out.println("------------------------------");
    //short:-32768~32767
    short s = 121;
    short shortMaxValue = Short.MAX_VALUE;
    short shortMinValue = Short.MIN_VALUE;
    System.out.println("shortMaxValue = " + shortMaxValue);
    System.out.println("shortMinValue = " + shortMinValue);
    System.out.println("------------------------------");
    //int:-2147483648~2147483647
    int i =10;
    int intMaxValue = Integer.MAX_VALUE;
    int intMinValue = Integer.MIN_VALUE;
    System.out.println("intMaxValue = " + intMaxValue);
    System.out.println("intMinValue = " + intMinValue);
    System.out.println("------------------------------");
    //long:-9223372036854775808~9223372036854775807
    long l = 123L;
    long longMaxValue = Long.MAX_VALUE;
    long longMinValue = Long.MIN_VALUE;
    System.out.println("longMaxValue = " + longMaxValue);
    System.out.println("longMinValue = " + longMinValue);
}
浮点型:float、double
数据类型 占字节数 大小/位 精确度
float(单精度) 4 32 7位有效数字
double(双精度) 8 64 15位有效数字
/**
 * float 单精度浮点类型 占4个字节 精确度为7位
 */
@Test
public void test02(){
    //1.java中的小数类型都是double类型,如果直接写float f = 3.14会报错。
    float f1 = 3.14f;//第一种解决办法:在数字后面加上f
    float f2 = (float) 3.14;//第二种解决办法:将double类型转换为float类型
    //2.float精确度(精确度为7位)
    float f3 = 5.332326231115325325155215f;
    System.out.println("f3 = " + f3);
    //3.进行运算
    int a = 2;
    float b = 3.14f;
    float c = a+b;
    System.out.println("c = " + c);
}
/**
 * double 双精度浮点类型 占8个字节 精确度为15位
 */
@Test
public void test03(){
    //1、声明一个变量,输出的值精确到15位
    double d = 5.332326231115325325155215;
    System.out.println("d = " + d);
    //2.进行运算
    long l = 10L;
    double d1 = 3.14;
    double d2 = l + d1;
}
字符型:char
数据类型 占字节数 大小/位
char(字符型) 2 16
编码 范围
大写字母(A-Z) 65~90
小写字母(a-z) 97~122
数字(0-9) 48~57
/**
 * char 占两个字节 :键盘上的每一种字符都对应一个数字
 * a-z:97-122
 * A-Z:65-90
 * 0-9:48-57
 */
@Test
public void test05(){
    //1.声明一个字符型变量
    char ch = '中';//一个中文占两个字符
    System.out.println("ch = " + ch);
    //2.声明一个字母型变量
    char c1 = 'A';
    System.out.println("c1 = " + (int)c1);
}
布尔型:boolean
/**
 * boolean:true,false
 */
@Test
public void test04(){
    //1.声明一个boolean型变量
    boolean b = true;
    System.out.println("b = " + b);
    //2.取反
    b = !b;
    System.out.println("b = " + b);
}

2、运算符与表达式

2.1、算术运算符

双目运算符(+ – * / %)
/**
 * 双目运算符
 */
@Test
public void test01() {
    int a = 10, b = 4;
    int e = a + b;
    int f = a - b;
    int g = a * b;
    int h = a / b;
    int i = a % b;
    System.out.println("e = " + e);
    System.out.println("f = " + f);
    System.out.println("g = " + g);
    System.out.println("h = " + h);
    System.out.println("i = " + i);
}
单目运算符(++ –)
/**
 * 单目运算符
 * a++:先取值后自增
 * ++a:先自增后取值
 */
@Test
public void test02() {
    //1.1、定义两个变量
    int a = 1;
    int b;
    //1.2、++运算符用法
    //1.2.1、前加
    //1.2.1.1、单独使用
    ++a;
    System.out.println("a = " + a);
    //1.2.1.2、与表达式一起使用
    b = ++a;
    System.out.println("a = " + a + ",b = " + b);
    //1.2.2、后加
    //1.2.2.1、单独使用
    a++;
    System.out.println("a = " + a);
    //1.2.2.2、与表达式一起使用
    b = a++;
    System.out.println("a = " + a + ",b = " + b);
    //1.3、--运算符
    //1.3.1、前减
    //1.3.1.1、单独使用
    --a;
    System.out.println("a = " + a);
    //1.3.1.2、与表达式一起使用
    b = --a;
    System.out.println("a = " + a + ",b = " + b);
    //1.3.2、后减
    //1.3.2.1、单独使用
    a--;
    System.out.println("a = " + a);
    //1.3.2.2、与表达式一起使用
    b = a--;
    System.out.println("a = " + a + ",b = " + b);
}
自增和自减
  • ++变量、–变量:先进行变量的自增或自减,再使用该变量参与运算。
  • 变量++、变量–:先用该变量参与运算,再进行自增或自减

2.2、关系运算符(> >= < <= == !=)

@Test
public void test01() {
    //1、定义几个变量
    int a = 10, b = 5, c = 6, d = 5;
    //2、判断
    boolean b1 = a > b;
    boolean b2 = c < d;
    boolean b3 = b == d;
    System.out.println("b1 = " + b1);
    System.out.println("b2 = " + b2);
    System.out.println("b3 = " + b3);
}

2.3、逻辑运算符(!& && | ||)

/**
 * 逻辑与(&&):代表参与运算的表达式需要同时为true,整个表达式才成立
 */
@Test
public void test01() {
    //1.1定义几个变量
    int a = 10, b = 5, c = 4, d = 3;
    //1.2逻辑与的一般用法:参与运算的多个表达式都成立,整个表达式才成立。
    if (a++ > --b && c-- > d++) {   //a=10,b=4,c=4,d=3;true&&true
        System.out.println("a = " + a + ",b = " + b + ",c = " + c + ",d = " + d); //a=11,b=4,c=3,d=4
    }
    //1.3逻辑与的短路用法:参与运算的表达式只要有一个为false,其后面的表达式就不需要执行了
    if (a++ < --b && c-- > d++) {   //a=12,b=3,c=2,d=5;
    }
    System.out.println("a = " + a + ",b = " + b + ",c = " + c + ",d = " + d);
}

/**
 * 逻辑或(||):代表参与运算的表达式需要同时为false,整个表达式才成立
 */
@Test
public void test02() {
    //1.1定义几个变量
    int a = 10, b = 5, c = 4, d = 3;
    //1.2逻辑或的一般用法:参与运算的多个表达式都成立,整个表达式才成立。
    if (a++ < b-- || c++ > d--) {
        System.out.println("a = " + a + ",b = " + b + ",c = " + c + ",d = " + d);   //a=11,b=4,c=5,d=2
    }
    //1.3逻辑或的短路用法:参与运算的表达式只要有一个为true,其后面的表达式就不需要执行了
    if (a++ > b-- || c++ < d--) {
    }
    System.out.println("a = " + a + ",b = " + b + ",c = " + c + ",d = " + d);   //a=12,b=3,c=5,d=2
}

/**
 * 逻辑非(!)
 */
@Test
public void test03() {
    boolean b = true;
    System.out.println("b = " + b);
    b = !b;
    System.out.println("b = " + b);
}

2.4、赋值运算符(= += -= *= /= %=)

@Test
public void test01(){
    int a = 10;
    a += 3;
    System.out.println("a = " + a); //a=a+3
    a -= 5;
    System.out.println("a = " + a); //a=a-5
    a *= 4;
    System.out.println("a = " + a); //a=a*4
    a /= 3;
    System.out.println("a = " + a); //a=a/3
    a %= 2;
    System.out.println("a = " + a); //a=a%2
}

2.5、运算符的优先级

运算符的优先级:

① ( )

② ++ — !

算术运算符

③ * / %

④ 

关系运算符

⑤ > >= < <== !=

逻辑运算符

⑥ &&

⑦ ||

赋值运算符

⑧ += -= */= %=

3、if条件结构

3.1、简单if语句

/**
 * 功能:简单if条件结构
 * 时间:2021/12/8 14:35
 */
@Test
public void test01() {
    //1、定义两个变量
    int a = 10, b = 4;
    //2、判断
    if (a > b) {
        System.out.println("a > b");
    }
}

3.2、if…else条件结构

/**
 * 功能:if...else条件结构
 * 时间:2021/12/8 14:37
 */
@Test
public void test02() {
    //1、得到当前时间的小时数
    int hour = LocalDateTime.now().getHour();
    //2、判断
    if (hour > 10) {
        System.out.println("上午好");
    } else {
        System.out.println("早上好");
    }
    //3、使用三元表达式
    System.out.println(hour > 10 ? "上午好" : "早上好");
}

3.3、if…else if…else if…else多重if结构

/**
 * 功能:if...else if...else结构
 * 案例:根据学生成绩打印评分
 * 时间:2021/12/8 14:42
 */
@Test
public void test03() {
    //1、定义学生成绩
    int score = 56;
    //2、根据成绩的范围进行评分的判断
    if (score >= 90) {
        System.out.println("优秀");
    } else if (score >= 80) {
        System.out.println("良好");
    } else if (score >= 70) {
        System.out.println("一般");
    } else if (score >= 60) {
        System.out.println("及格");
    } else {
        System.out.println("不及格");
    }
}

4、Switch…case多分支选择结构

4.1、案例一:输入一个字母判断是不是元音字母

private static void test01(Scanner scanner) {
    //1、输入提示信息并获取输入的信息
    System.out.println("请输入一个字母:");
    String next = scanner.next();
    //2、对输入的值进行判断
    switch (next) {
        case "a":
            System.out.println("a是一个元音字母");
            break;
        case "e":
            System.out.println("e是一个元音字母");
            break;
        case "i":
            System.out.println("i是一个元音字母");
            break;
        case "o":
            System.out.println("o是一个元音字母");
            break;
        case "u":
            System.out.println("u是一个元音字母");
            break;
        default:
            System.out.println(next + "不是一个元音字母");
    }
}

4.2、案例二:根据输入的月份数,打印对应的天数!

private static void test03(Scanner scanner) {
    //1、输入提示信息并获取对应的值
    System.out.println("请输入一个月份数:");
    int month = scanner.nextInt();
    int days = 0;
    //2、根据输入的月份进行判断
    switch (month) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            days = 31;
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            days = 30;
            break;
        case 2:
            days = 28;
            break;
        default:
            System.out.println("月份只能在1~12月份之间");
            break;
    }
    System.out.println(month + "月有" + days + "天");
}

4.3、案例三:根据输入的学生成绩打印评语

private static void test04(Scanner scanner) {
    //1、输入提示信息并获取对应的值
    System.out.println("请输入学生的成绩:");
    int score = scanner.nextInt();
    //2、对获取的值分区间判断
    switch (score / 10) {
        case 9:
            System.out.println("优秀");
            break;
        case 8:
            System.out.println("良好");
            break;
        case 7:
            System.out.println("一般");
            break;
        case 6:
            System.out.println("及格");
            break;
        default:
            System.out.println("不及格");
            break;
    }
}

5、while、do…while与for循环

5.1、while循环:先判断后执行

案例一:打印10遍 “hello,world”
/**
 * 功能:案例一:打印10遍 "hello,world"
 * 时间:2021/12/8 15:31
 */
@Test
public void test01() {
    int i = 1;
    while (i <= 10) {
        System.out.println("hello,world");
        i++;
    }
}
案例二:求 1-100 之间所有数字之和
/**
 * 功能:案例二:求 1-100 之间所有数字之和
 * 时间:2021/12/8 15:34
 */
@Test
public void test02() {
    //1、定义一个循环初始变量
    int i = 1;
    //2、求和变量初始化
    int sum = 0;
    //3、求和
    while (i <= 100) {
        sum += i;
        i++;
    }
    //4、输出
    System.out.println("sum = " + sum);
}
案例三:输出1-100之间所有奇数并且每5个一换行?
/**
 * 功能:案例三:输出1-100之间所有奇数并且每5个一换行?
 * 分析:
 * (1)先筛选出1~100之间的所有奇数:i%2==1
 * (2)对筛选出的所有奇数进行统计
 * (3)每5个一换行:count%5==0
 * 时间:2021/12/8 15:38
 */
@Test
public void test03() {
    //1、初始化循环变量
    int i = 1;
    //2、初始化计数变量
    int count = 0;
    //3、循环判断
    while (i <= 100) {
        if (i % 2 == 1) {
            System.out.print(i + "\t");
            count++;
            if (count % 5 == 0) {
                System.out.println();
            }
        }
        i++;
    }
}
案例四:输出1-1000之间所有个位数为3且能被7整除的数字之和,每3个一换行?
/**
 * 功能:案例四:输出1-1000之间所有个位数为3且能被7整除的数字之和,每3个一换行?
 * 分析:
 * (1)先筛选出1~1000之间所有个位数为3且能被7整除的数字之和:i%10==3 && i%7==0
 * (2)每3个一换行:count%3==0
 * 时间:2021/12/8 15:41
 */
@Test
public void test04() {
    //1、初始化循环变量
    int i = 1;
    //2、初始化计数变量、求和变量
    int count = 0, sum = 0;
    //3、循环判断
    while (i <= 1000) {
        if (i % 10 == 3 && i % 7 == 0) {
            System.out.print(i + "\t");
            sum += i;
            count++;
            if (count % 3 == 0) {
                System.out.println();
            }
        }
        i++;
    }
    System.out.println("\nsum = " + sum);
}

5.2、do…while循环:先执行后判断

案例一:找到10个整数中的最大值并输出?
/**
 * 功能: 案例二:找到10个整数中的最大值并输出?
 * 分析:
 * (1)初始化最大值
 * (2)循环输入10个数
 * (3)最大值和每一个整数进行比较
 * (4)输出最大值
 * 时间:2021/12/9 11:19
 */
private static void test02(Scanner scanner) {
    //1、初始化最大值
    int maxNum = 0;
    //2、循环输入10个数
    int i = 1;
    do {
        System.out.print("请输入第" + i + "个数:");
        int num = scanner.nextInt();
        //3、使用if语句对输入的每一个值跟最大值进行比较
        if (num > maxNum) {
            maxNum = num;
        }
        i++;
    } while (i <= 10);
    //4、输出最大值
    System.out.println("最大值:" + maxNum);
}
案例二:输出超市管理系统的菜单项?
/**
 * 功能:案例三:输出超市管理系统的菜单项?
 * 时间:2021/12/9 11:35
 */
private static void test03(Scanner scanner) {
    //打印主菜单
    showMenu();
    //用户选择操作菜单
    userSelect(scanner);
}

//主菜单
private static void showMenu() {
    System.out.println("===============南山超市管理系统===============");
    System.out.println("[1]添加商品");
    System.out.println("[2]修改商品");
    System.out.println("[3]删除商品");
    System.out.println("[4]查看商品");
    System.out.println("[5]退出系统");
    System.out.println("===========================================");
}

//用户选择
private static void userSelect(Scanner scanner) {
    //定义是否选择的变量
    String inCon = "y";
    //循环
    do {
        System.out.print("请选择菜单:");
        int choice = scanner.nextInt();
        //对输入的选择进行判断
        switch (choice) {
            case 1:
                System.out.println("添 加 商 品");
                break;
            case 2:
                System.out.println("修 改 商 品");
                break;
            case 3:
                System.out.println("删 除 商 品");
                break;
            case 4:
                System.out.println("查 看 商 品");
                break;
            case 5:
                System.exit(0);
                break;
        }
        System.out.print("\n是否继续(y/n):");
        inCon = scanner.next();
    } while (inCon.equalsIgnoreCase("y"));
    System.out.println("\n程序结束!");
}

5.3、while循环与do…while循环的区别

(1)while循环:先判断后循环,如果循环的条件不成立一次也不会执行
(2)do...while循环:先循环后判断,如果循环的条件不成立也会执行一次

5.4、for循环

案例一:打印1-100之间所有整数之和
/**
 * 功能:案例一:打印1-100之间所有整数之和
 * 时间:2021/12/9 11:58
 */
@Test
public void test01() {
    //定义求和变量并初始化
    int sum = 0;
    //循环
    for (int i = 1; i <= 100; i++) {
        sum += i;
    }
    System.out.println("1-100之间所有整数之和为:" + sum);
}
案例二:输出1-1000之间即能被3又能被7整除的整数,每五个一换行。
/**
 * 功能:案例二:输出1-1000之间即能被3又能被7整除的整数,每五个一换行。
 * 分析:
 * (1)先筛选出1~1000之间即能被3又能被7整除的整数:i%3==0 && i%7==0
 * (2)每5个一换行:count%5==0
 * 时间:2021/12/9 11:59
 */
@Test
public void test02() {
    //定义一个计数变量
    int count = 0;
    //循环
    for (int i = 1; i <= 1000; i++) {
        if (i % 3 == 0 && i % 7 == 0) {
            System.out.print(i + "\t");
            count++;
            if (count % 5 == 0) {
                System.out.println();
            }
        }
    }
}
案例三:输入10个字符,判断其中数字和字母的个数?
/**
 * 功能:案例三:输入10个字符,判断其中数字和字母的个数?
 * 方法一:每次输入一个字符,以空格或回车作为结束符号!
 * 时间:2021/12/9 12:00
 */
private static void test03(Scanner scanner) {
    //1、定义计数器
    int m = 0, n = 0;
    //2、输入10个字符
    System.out.println("请输入10个字符:");
    for (int i = 0; i < 10; i++) {
        char ch = scanner.next().charAt(0);
        if (ch >= '0' && ch <= '9') { //数字
            m++;
        }
        if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) { //字母
            n++;
        }
    }
    System.out.println("10个字符中数字的个数:" + m);
    System.out.println("10个字符中字母的个数:" + n);
}
/**
 * 功能:案例三:输入10个字符,判断其中数字和字母的个数?
 * 方法二:一次性输入一个字符串!
 * 时间:2021/12/9 12:00
 */
private static void test04(Scanner scanner) {
    //定义计数器
    int m = 0, n = 0;
    //输入信息
    System.out.println("请输入10个字符:");
    String str = scanner.next();
    //循环输出
    for (int i = 0; i < 10; i++) {
        char ch = str.charAt(i);
        //统计出现数字的个数
        if (ch >= '0' && ch <= '9') {
            m++;
        }
        //统计出现字母的个数
        if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
            n++;
        }
    }
    System.out.println("10个字符中数字的个数:" + m);
    System.out.println("10个字符中字母的个数:" + n);
}
案例四:求给定数字的阶乘?
/**
 * 功能:案例四:求给定数字的阶乘?
 * 分析:例如:5!=5x4x3x2x1
 * 时间:2021/12/9 12:00
 */
private static void test05(Scanner scanner) {
    //定义一个阶乘结果变量
    long fax = 1;
    //输入提示信息
    System.out.println("请输入一个整数:");
    int num = scanner.nextInt();
    for (int i = 1; i <= num; i++) {
        fax *= i;
    }
    //输出信息
    System.out.println(num + "的阶乘为:" + fax);
}

5.5、嵌套for循环

案例一:打印直角三角形
/**
 * 功能:案例一:打印直角三角形
 * 时间:2021/12/9 14:30
 */
@Test
public void test01() {
    //打印行数
    for (int i = 1; i <= 5; i++) {
        //打印*数
        for (int j = 1; j <= i; j++) {
            System.out.print("* ");
        }
        //换行
        System.out.println();
    }
}
案例二:打印九九乘法表
/**
 * 功能:案例二:打印九九乘法表
 * 时间:2021/12/9 14:34
 */
@Test
public void test02() {
    //打印行数
    for (int i = 1; i <= 9; i++) {
        //打印列数
        for (int j = 1; j <= i; j++) {
            //输出并计算
            System.out.print(j + "x" + i + "=" + (j * i) + "\t");
        }
        //换行
        System.out.println();
    }
}
案例三:打印等腰三角形
/**
 * 功能:案例三:打印等腰三角形
 * 分析:
 * (1)  行数:1、2、3、4、5
 * (2)空格数:4、3、2、1、0(5-行数)
 * (3)*个数:1、3、5、7、9(2*行数-1)
 * 时间:2021/12/9 14:38
 */
@Test
public void test03() {
    //打印行数
    for (int i = 1; i <= 5; i++) {
        for (int j = 1; j <= 5 - i; j++) { //打印空格数
            System.out.print(" ");
        }
        for (int k = 1; k <= 2 * i - 1; k++) { //打印*数
            System.out.print("*");
        }
        System.out.println();//换行
    }
}
案例四:打印实心菱形和空心菱形
public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    showMenu();
    userSelect(scanner);
}

//主菜单
private static void showMenu() {
    System.out.println("===============打印菱形===============");
    System.out.println("[1]打印实心菱形");
    System.out.println("[2]打印空心菱形");
    System.out.println("[3]退出系统");
    System.out.println("===========================================");
}

//用户选择
private static void userSelect(Scanner scanner) {
    //定义是否选择的变量
    String inCon = "y";
    //循环
    do {
        System.out.print("请选择菜单:");
        int choice = scanner.nextInt();
        //对输入的选择进行判断
        switch (choice) {
            case 1:
                test01(scanner); //调用打印实心菱形的方法
                break;
            case 2:
                test02(scanner); //调用打印空心菱形的方法
                break;
            default:
                System.exit(0);
                break;
        }
        System.out.print("\n是否继续(y/n):");
        inCon = scanner.next();
    } while (inCon.equalsIgnoreCase("y"));
    System.out.println("\n程序结束!");
}

/**
 * 功能:案例四:打印菱形
 * 分析:
 * (1)先打印出正等腰三角形
 * (1.1)  行数:1、2、3、4、5
 * (1.2)空格数:4、3、2、1、0(5-行数)
 * (1.3)*个数:1、3、5、7、9(2*行数-1)
 * <p>
 * (2)打印出倒等腰三角形
 * (2.1)  行数:1、2、3、4
 * (2.2)空格数:1、2、3、4(行数)
 * (2.3)*个数:7、5、3、1(9-2*行数)
 * 时间:2021/12/9 14:43
 */
private static void test01(Scanner scanner) {
    System.out.print("请输入要打印的行数:");
    int num = scanner.nextInt();
    for (int i = 1; i <= num; i++) {
        for (int j = 1; j <= num - i; j++) {
            System.out.print(" ");
        }
        for (int k = 1; k <= 2 * i - 1; k++) {
            System.out.print("*");
        }
        System.out.println();
    }
    for (int m = 1; m <= num - 1; m++) {
        for (int n = 1; n <= m; n++) {
            System.out.print(" ");
        }
        for (int p = 1; p <= (2 * num - 1) - 2 * m; p++) {
            System.out.print("*");
        }
        System.out.println();
    }
}

/**
 * 功能:案例五:打印空心菱形(每行只打印第一个*号和最后一个*号,除了第一行和最后一行只打印一个*)
 * 分析:
 * (1)打印正等腰三角形的空心
 * (2)打印倒等腰三角形的空心
 * 时间:2021/12/9 15:18
 */
private static void test02(Scanner scanner) {
    System.out.print("请输入要打印的行数:");
    int num = scanner.nextInt();
    for (int i = 1; i <= num; i++) {
        for (int j = 1; j <= num - i; j++) {
            System.out.print(" ");
        }
        for (int k = 1; k <= 2 * i - 1; k++) {
            if (k == 1 || k == 2 * i - 1) {
                System.out.print("*");
            } else {
                System.out.print(" ");
            }
        }
        System.out.println();
    }
    for (int m = 1; m <= num - 1; m++) {
        for (int n = 1; n <= m; n++) {
            System.out.print(" ");
        }
        for (int p = 1; p <= (2 * num - 1) - 2 * m; p++) {
            if (p == 1 || p == (2 * num - 1) - 2 * m) {
                System.out.print("*");
            } else {
                System.out.print(" ");
            }
        }
        System.out.println();
    }
}

6、流程控制语句

6.1、break语句:退出当前循环

/**
 * break语句的使用:退出当前循环
 * 功能:案例一:打印1-1000之间个位数是3的数字,只打印前三个?
 * 分析:
 * ①定义一个计数器
 * ②在循环中筛选中个位数为3的数字
 * ③在筛选出的数字中打印前三个数字
 */
@Test
public void test01() {
    //定义一个计数器
    int count = 0;
    //在循环中筛选中个位数为3的数字
    for (int i = 1; i <= 1000; i++) {
        int ge = i % 10;
        //在筛选出的数字中打印前三个数字
        if (ge == 3) {
            System.out.print(i + "\t");
            count++;
            if (count == 3) {
                break;
            }
        }
    }
}

6.2、continue语句:退出当前循环,进行下一次循环

/**
 * continue语句的使用:退出当前循环,接着执行下一次循环
 * 功能:案例二:打印1-100之间所有奇数之和?
 * 分析:
 * ①定义求和变量
 * ②在循环中找出所有的奇数
 * ③对所有的奇数累加求和
 */
@Test
public void test02() {
    //定义求和变量
    int sum = 0;
    //循环找出所有奇数的数字
    for (int i = 1; i <= 100; i++) {
        if (i % 2 == 0) {
            continue;
        }
        //累加求和
        sum += i;
    }
    //打印结果
    System.out.println("sum = " + sum);
}

6.3、return语句

  • 代表退出整个结构,如果在方法中就退出方法,如果在循环中就退出整个循环结构
  • 如果有多重循环则退出所有的循环
/**
 * return语句的使用
 * 代表退出整个结构,如果在方法中就退出方法,如果在循环中就退出整个循环结构。
 * 如果有多重循环则退出所有的循环
 * 功能:案例一:1-1000之间个位数是3的数字,只对前三个求和?
 * 分析:
 * ①获取个位数为3的数字:i % 10 == 3
 * ②计数:count == 3
 * ③求和
 */
@Test
public void test03() {
    //定义求和变量和计数器
    int sum = 0;
    int count = 0;
    //循环
    for (int i = 1; i <= 1000; i++) {
        //个位数为3
        if (i % 10 == 3) {
            count++;
            //累加求和
            sum += i;
            System.out.print(i + "\t");
            if (count == 3) {
                System.out.println("\nsum = " + sum);
                return;
            }
        }
    }
    System.out.println("return后的语句都不会执行");
}

7、数组

7.1、一维数组的定义与声明

/**
 * 功能:一维数组的定义与声明
 */
@Test
public void test01() {
    //1、定义一维数组
    int[] scores = new int[5];
    int a[] = new int[3];
    //2、为数组赋值
    //2.1、静态赋值
    a[0] = 1;
    int[] b = {1, 2, 3, 4};
    int[] c = new int[]{3, 4, 5, 6};
}

7.2、一维数组的动态赋值

public static void main(String[] args) {
    //定义一个扫描器对象
    Scanner scanner = new Scanner(System.in);
    test02(scanner);
}

/**
 * 功能:实现一维数组的动态赋值
 */
private static void test02(Scanner scanner) {
    //定义一个代表学生成绩的数组
    int[] scores = new int[5];
    //为数组动态赋值
    System.out.println("请输入5个学生的成绩:");
    for (int i = 0; i < scores.length; i++) {
        //将得到的学生分数赋值给数组
        scores[i] = scanner.nextInt();
    }
    //使用foreach循环打印数组的元素
    for (int score : scores) {
        System.out.print(score + "\n");
    }
}

7.3、二维数组的定义与声明

/**
 * 功能:二维数组的定义与声明
 */
@Test
public void test01() {
    //定义二维数组
    int[][] a = new int[3][4];
    int[][] b = new int[3][];
    b[0] = new int[5];
    b[1] = new int[4];
    b[2] = new int[3];
    //为二维数组赋值
    b[0][0] = 11;
    b[0][1] = 12;
    b[0][2] = 13;
    b[0][3] = 14;
    b[0][4] = 15;
    b[1][0] = 16;
    b[1][1] = 17;
    b[1][2] = 18;
    b[1][3] = 19;
    b[2][0] = 20;
    b[2][1] = 21;
    b[2][2] = 22;
    //遍历二维数组
    for (int i = 0; i < b.length; i++) {
        for (int j = 0; j < b[i].length; j++) {
            System.out.print(b[i][j] + "\t");
        }
        System.out.println();
    }
}

7.4、二维数组的动态赋值

public static void main(String[] args) {
    //定义一个扫描器对象
    Scanner scanner = new Scanner(System.in);
    test02(scanner);
}

/**
 * 功能:实现二维数组的动态赋值
 * 时间:2021/12/13 16:24
 */
private static void test02(Scanner scanner) {
    //定义一个二维数组存储2名学生的三门成绩
    int[][] scores = new int[2][3];
    //为二维数组动态赋值
    for (int i = 0; i < scores.length; i++) {
        System.out.print("请输入" + (i + 1) + "名学生的3门成绩:");
        for (int j = 0; j < scores[i].length; j++) {
            scores[i][j] = scanner.nextInt();
        }
    }
    //遍历二维数组
    for (int[] score : scores) {
        for (int i : score) {
            System.out.print(i + "\t");
        }
        System.out.println();
    }
}

7.5、数组的常用算法

案例一:在数组中查找最大值与最小值
/**
 * 功能:案例一:在数组中查找最大值与最小值
 * 分析:【方法一】
 * 1、定义一维数组
 * 2、初始化最大值与最小值,默认为数组的第一个值
 * 3、遍历判断最大值与最小值
 * 4、打印输出
 */
@Test
public void test01() {
    //定义一维数组
    int[] a = {3, 1, 9, 10, 2, 11, 8, 7, 4, 3};
    //初始化最大值与最小值
    int max = a[0];
    int min = a[0];
    //遍历数组
    for (int i = 0; i < a.length; i++) {
        //最大值
        if (a[i] > max) {
            max = a[i];
        }
        //最小值
        if (a[i] < min) {
            min = a[i];
        }
    }
    //输出最大值与最小值
    System.out.println("max = " + max);
    System.out.println("min = " + min);
}

/**
 * 功能:案例一:在数组中查找最大值与最小值
 * 分析:【方法二】使用Arrays.sort()
 */
@Test
public void test02() {
    //定义一维数组
    int[] a = {3, 1, 9, 10, 2, 11, 8, 7, 4, 3};
    //使用Arrays.sort()方法:升序排列
    Arrays.sort(a);
    //输出最大值与最小值
    System.out.println("max = " + a[a.length - 1]);
    System.out.println("min = " + a[0]);
}

/**
 * 功能:案例一:在数组中查找最大值与最小值
 * 分析:【方法三】使用冒泡排序算法:升序
 */
@Test
public void test03() {
    //定义一维数组
    int[] a = {3, 1, 9, 10, 2, 11, 8, 7, 4, 3};
    //循环遍历数组
    for (int i = 0; i < a.length; i++) {
        for (int j = 0; j < a.length - i - 1; j++) {
            if (a[j] > a[j + 1]) {
                int temp = a[j];
                a[j] = a[j + 1];
                a[j + 1] = temp;
            }
        }
    }
    //输出数组的最大值与最小值
    System.out.println("max = " + a[a.length - 1]);
    System.out.println("min = " + a[0]);
}
案例二:在数组中查找元素及其下标?【元素在数组中只出现一次】
/**
 * 功能: 案例二:在数组中查找元素及其下标?【元素在数组中只出现一次】
 * 分析:【方法一】
 * 1、可以定义一个代表找到的元素的下标,如:int index = -1;
 * 2、遍历开始查找元素,如果找到就赋值给index,并退出。
 */
@Test
public void test04() {
    //定义一个数组
    int[] a = {3, 1, 9, 10, 2, 11, 8, 7, 4, 3};
    //定义要查找的元素
    int e = 3;
    //定义查找到的元素在数组中的下标
    int index = -1;
    //开始遍历查找
    for (int i = 0; i < a.length; i++) {
        //根据查找的元素是否与当前正在遍历的元素相等,就可以确定是否找到了元素
        if (a[i] == e) {
            index = i;
            break;
        }
    }
    //如果index不等于-1,代表找到了元素
    if (index != -1) {
        System.out.println("在" + index + "位置找到了元素" + e + "!");
    } else {
        System.out.println("没有找到元素" + e + "!");
    }
}

/**
 * 功能:案例二:在数组中查找元素及其下标?【元素在数组中只出现一次】
 * 分析:【方法二】
 * 1、在遍历循环完成后,如果循环变量i的值小于数组的长度,则说明这个循环中途退出了并且找到了这个元素。
 */
@Test
public void test05() {
    //定义一个数组
    int[] a = {3, 1, 9, 10, 2, 11, 8, 7, 4, 3};
    //定义要查找的元素
    int e = 4;
    //定义循环变量i
    int i = 0;
    //开始循环
    for (; i < a.length; i++) {
        if (a[i] == e) {
            break;
        }
    }
    //判断循环变量i的值是否小于数组的长度
    if (i < a.length) {
        System.out.println("在" + i + "位置找到了元素" + e + "!");
    } else {
        System.out.println("没有找到元素" + e + "!");
    }
}

/**
 * 功能:案例二:在数组中查找元素及其下标?【元素在数组中只出现一次】
 * 分析:【方法三】
 * 1、使用return语句,如果找到了直接打印输出
 */
@Test
public void test06() {
    //定义一个数组
    int[] a = {3, 1, 9, 10, 2, 11, 8, 7, 4, 3};
    //定义要查找的元素
    int e = 4;
    //循环
    for (int i = 0; i < a.length; i++) {
        if (a[i] == e) {
            System.out.println("在" + i + "位置找到了元素" + e + "!");
            return;
        }
    }
    System.out.println("没有找到元素" + e + "!");
}
案例三:在数组中查找元素及其下标?【元素在数组中出现多次】
/**
 * 功能:案例三:在数组中查找元素及其下标?【元素在数组中出现多次】
 * 分析:【方法一】
 * 1、使用continue语句,如果找到了就继续
 */
@Test
public void test07() {
    //定义要查找的数组
    int[] a = {3, 1, 9, 1, 2, 1, 2, 1, 2, 2};
    //定义要查找的元素
    int e = 2;
    //遍历
    System.out.println("在如下位置找到了元素" + e + ":");
    System.out.println("-------------------------");
    for (int i = 0; i < a.length; i++) {
        if (a[i] == e) {
            System.out.print(i + "\t");
            continue;
        }
    }
    System.out.println("\n-------------------------");
}

/**
 * 功能:案例三:在数组中查找元素及其下标?【元素在数组中出现多次】
 * 分析:【方法二】
 * 1、可以将找到的元素在数组中的下标放到一个新的数组中。
 * 2、新的数组的长度可以定义为与源数组长度一致。
 * 3、新的数组的下标可以定义一个计数器来实现。此时的计数器充当下标及代表找到的元素的个数的计数器。
 */
@Test
public void test08() {
    //定义要查找的数组
    int[] a = {3, 1, 9, 1, 2, 1, 2, 1, 2, 2};
    //定义要查找的元素
    int e = 2;
    //定义存放找到的元素在数组中下标的数组
    int[] b = new int[a.length];
    //定义计数器同时充当b数组的下标
    int count = 0;
    //开始查找并将找到的下标放到b数组中
    for (int i = 0; i < a.length; i++) {
        if (a[i] == e) {
            b[count++] = i;
        }
    }
    //打印找到的元素下标
    if (count > 0) {
        System.out.println("在如下位置找到元素" + e + ":");
        System.out.println("-----------------------------------");
        for (int i = 0; i < count; i++) {
            System.out.print(b[i] + "\t");
        }
        System.out.println("\n-----------------------------------");
    } else {
        System.out.println("没有找到元素" + e + "!");
    }
}

/**
 * 功能:案例三:在数组中查找元素及其下标?【元素在数组中出现多次】
 * 分析:【方法三】
 * 1、将找到的下标用一个字符串连接起来
 */
@Test
public void test09() {
    //定义要查找的数组
    int[] a = {3, 1, 9, 1, 2, 1, 2, 1, 2, 2};
    //定义要查找的元素
    int e = 1;
    //定义查找到的元素的下标存放的字符串
    String str = "";
    //开始查找
    for (int i = 0; i < a.length; i++) {
        if (a[i] == e) {
            str += i + " ";
        }
    }
    //根据str的长度是否为0,判断是否找到元素
    if (str.trim().length() == 0) {
        System.out.println("没有找到元素" + e + "!");
    } else {
        System.out.println("在如下位置找到元素" + e + ":");
        System.out.print(str);
    }
}

7.6、数组的排序

/**
 * 功能:冒泡排序
 */
@Test
public void test01() {
    //定义一个数组
    int[] a = {11, 1, 19, 2, 5, 3, 7, 6};
    //开始循环
    for (int i = 0; i < a.length; i++) {
        for (int j = 0; j < a.length - i - 1; j++) {
            if (a[j] > a[j + 1]) {
                int temp = a[j];
                a[j] = a[j + 1];
                a[j + 1] = temp;
            }
        }
    }
    //打印排序后的数组
    for (int i : a) {
        System.out.print(i + "\t");
    }
}

/**
 * 功能:Arrays类的用法
 */
@Test
public void test02() {
    //定义一个数组
    int[] a = {11, 1, 19, 2, 5, 3, 7, 6};
    //对数组进行排序
    Arrays.sort(a);
    //打印排序后的数组
    for (int i : a) {
        System.out.print(i + "\t");
    }
    //在数组中查找元素
    int e = 5;
    int index = Arrays.binarySearch(a, e);
    System.out.println("\nindex = " + index);
}

8、Math类的使用

@Test
public void test01(){
    //1、绝对值
    int abs = Math.abs(-10);
    System.out.println("abs = " + abs);
    //2、随机数[0,10)
    double random = Math.random();
    System.out.println("random = " + random);
    //3、返回小于等于给定参数的最大整数
    double floor = Math.floor(3.14);
    System.out.println("floor = " + floor);
    //4、返回大于等于给定参数的最小整数
    double ceil = Math.ceil(3.14);
    System.out.println("ceil = " + ceil);
    //5、返回两个参数的最大值与最小值
    int max = Math.max(4, 5);
    System.out.println("max = " + max);
    int min = Math.min(6, 4);
    System.out.println("min = " + min);
    //6、返回一个参数的n次幂
    double pow = Math.pow(2, 3);
    System.out.println("pow = " + pow);
    //6、返回一个四舍五入的数(将给定的数+0.5后再向下取整)
    long round = Math.round(3.456);
    System.out.println("round = " + round);
    //7、返回圆周率
    double pi = Math.PI;
    System.out.println("pi = " + pi);
    //8、求给定参数的正弦值
    double sin = Math.sin(Math.PI / 3);
    System.out.println("sin = " + sin);
    //9、求给定参数的算术平方根
    double sqrt = Math.sqrt(2);
    System.out.println("sqrt = " + sqrt);
}

9、String类的使用

/**
 * 功能:String类的使用
 */
@Test
public void test01() {
    //定义一个字符串类
    String str = "hello,world";
    //得到指定位置的字符
    char c = str.charAt(1);
    System.out.println("c = " + c);
    //得到指定字符第一次出现的位置
    int indexOf = str.indexOf("o");
    System.out.println("indexOf = " + indexOf);
    //得到指定字符最后一次出现的位置
    int lastIndexOf = str.lastIndexOf("o");
    System.out.println("lastIndexOf = " + lastIndexOf);
    //将当前字符串转换成大写
    String toUpperCase = str.toUpperCase();
    System.out.println("toUpperCase = " + toUpperCase);
    //将当前字符串转换成小写
    String toLowerCase = str.toLowerCase();
    System.out.println("toLowerCase = " + toLowerCase);
    //字符串的拆分
    String[] split = str.split(",");
    for (String s : split) {
        System.out.println(s);
    }
    //从指定字符串的当前位置开始截取到结束
    String substring = str.substring(1);
    System.out.println("substring = " + substring);
    //在字符串中间截取
    String substring1 = str.substring(2, 4);
    System.out.println("substring1 = " + substring1);
    //替换字符串
    String replace = str.replace("o","O");
    System.out.println("replace = " + replace);
    //以指定字符开头的字符串
    boolean startsWith = str.startsWith("he");
    System.out.println("startsWith = " + startsWith);
    //以指定字符结尾的字符串
    boolean endsWith = str.endsWith("ld");
    System.out.println("endsWith = " + endsWith);
    //字符串是否包含指定字符
    boolean contains = str.contains("e");
    System.out.println("contains = " + contains);
    //字符串的长度
    int length = str.length();
    System.out.println("length = " + length);
}

10、StringBuffer类的使用

/**
 *功能:StringBuffer类的使用
 */
@Test
public void test02(){
    //定义字符串
    StringBuffer buffer = new StringBuffer("hello");
    //追加字符串
    buffer.append(1);
    //打印字符串
    System.out.println("buffer = " + buffer);
    //插入一个字符串
    buffer.insert(5,"中国人");
    System.out.println("buffer = " + buffer);
    //删除一个指定字符
    buffer.deleteCharAt(8);
    System.out.println("buffer = " + buffer);
    //删除指定范围内的字符
    buffer.delete(5,8);
    System.out.println("buffer = " + buffer);
    //反转字符转
    buffer.reverse();
    System.out.println("buffer = " + buffer);
}

11、第一阶段综合实战案例

面试题一:将一个给定字符串逆序输出

/**
 * 功能:面试题一:将一个给定字符串逆序输出。
 * 分析:【方法一】通过循环
 */
@Test
public void test01() {
    //定义一个字符串
    String str = "hello,world";
    //将字符串倒叙输出
    for (int i = str.length() - 1; i >= 0; i--) {
        //得到字符串的字符
        char c = str.charAt(i);
        //打印输出
        System.out.print(c);
    }
}

/**
 * 功能:面试题一:将一个给定字符串逆序输出。
 * 分析:【方法二】使用StringBuffer类
 */
@Test
public void test02() {
    //定义一个字符串
    String str = "hello,world";
    //声明一个StringBuffer
    StringBuffer buffer = new StringBuffer(str);
    //将字符串逆序
    buffer.reverse();
    //打印结果
    System.out.println(buffer);
}

面试题二:写一个字符串转换成驼峰的方法

/**
 * 功能:面试题二:写一个字符串转换成驼峰的方法
 * 分析:【方法一】
 */
@Test
public void test03() {
    //给定一个字符串
    String str = "border-bottom-color-hello-world-welcome";
    //遍历字符串,将-号的下一个位置的字符转换成大写
    for (int i = 0; i < str.length(); i++) {
        //找到第一个-号的位置
        int indexOf = str.indexOf("-");
        //得到下一个位置的字符
        char c = str.charAt(indexOf + 1);
        //将下一个位置的字符转换成大写
        str = str.replace("-" + c, (char) (c - 32) + "");
    }
    System.out.println(str);
}

/**
 * 功能:面试题二:写一个字符串转换成驼峰的方法
 * 分析:【方法二】将当前字符串拆分成字符串数组
 */
@Test
public void test04() {
    //给定一个字符串
    String str = "border-bottom-color-hello-world-welcome";
    //拆分
    String[] split = str.split("-");
    //定义结果字符串
    String result = split[0];
    //循环拆分后的数组
    for (int i = 0; i < split.length; i++) {
        //得到当前字符串
        String s = split[i];
        //将第一个字符转换为大写并连接到result中
        result += (char) (s.charAt(0) - 32);
        //截取字符串
        result += s.substring(1);
    }
    //打印结果字符串
    System.out.println(result);
}

/**
 * 功能:面试题二:写一个字符串转换成驼峰的方法
 * 分析:【方法三】使用CaseUtils对Java字符串进行转换为驼峰格式
 */
@Test
public void test05(){
    //给定一个字符串
    String str = "border-bottom-color-hello-world-welcome";
    //使用CaseUtils
    String s = CaseUtils.toCamelCase(str, false, '-');
    System.out.println(s);
}

面试题三:返回一个只包含数字类型的一个数组

/**
 * 功能:面试题三:返回一个只包含数字类型的一个数组
 */
@Test
public void test01() {
    //定义一个字符串
    String str = "f-[}f242fsdf2432agst5k232sfsa";
    //利用正则表达式将非数字的字符替换成空字符
    String s = str.replaceAll("[^0-9]", "");
    //将新字符串转换成字符数组
    char[] chars = s.toCharArray();
    //将字符数组打印输出
    for (char c : chars) {
        System.out.print(c);
    }
}

面试题四:如何判断一个字符串是否是一个回文字符串?

/**
 * 功能:面试题四:如何判断一个字符串是否是一个回文字符串?
 * 分析:【方法一】
 */
@Test
public void test02() {
    //定义一个字符串
    String str = "abcba";
    //遍历字符串
    for (int i = 0, len = str.length(); i < len / 2; i++) {
        //取出左边字符
        char left = str.charAt(i);
        //取出右边字符
        char right = str.charAt(len - 1 - i);
        //判断左右两边字符是否相等
        if (left != right) {
            System.out.println(str + "不是一个回文字符串");
            return;
        }
    }
    System.out.println(str + "是一个回文字符串");
}

/**
 * 功能:面试题四:如何判断一个字符串是否是一个回文字符串?
 * 分析:【方法二】
 */
@Test
public void test03() {
    //定义一个字符串
    String str = "abcba";
    //将字符串逆序输出
    StringBuffer buffer = new StringBuffer(str);
    buffer.reverse();
    //将新字符串与原字符串进行比较,如果相等则是回文字符串
    if (buffer.toString().equals(str)) {
        System.out.println(str + "是一个回文字符串");
    } else {
        System.out.println(str + "不是一个回文字符串");
    }
}

面试题五:将一个给定字符串如:”abcde”转换为”bcdef”

/**
 * 功能:面试题五:将一个给定字符串如:”abcde”转换为”bcdef”
 */
@Test
public void test04() {
    //定义一个字符串
    String str = "abcde";
    //遍历当前字符串
    for (int i = 0; i < str.length(); i++) {
        //得到每一个字符
        char c = str.charAt(i);
        //将得到的每一个字符加1
        System.out.print((char) (c + 1));
    }
}

面试题六:如何判断一个字符串中是否存在重复元素

/**
 * 功能:面试题六:如何判断一个字符串中是否存在重复元素?(面试题)
 */
@Test
public void test05() {
    //定义一个字符串
    String str = "abcdefagt";
    //遍历字符串
    for (int i = 0; i < str.length(); i++) {
        //得到每一个字符
        char c = str.charAt(i);
        //得到字符第一次出现的位置
        int indexOf = str.indexOf(c);
        //得到字符最后一次出现的位置
        int lastIndexOf = str.lastIndexOf(c);
        //比较两次出现的位置是否相等
        if (indexOf != lastIndexOf) {
            System.out.println(str + "中存在重复字符");
            return;
        }
    }
    System.out.println(str + "中不存在重复字符");
}

二、JavaOOP学习

1、类和对象

类和对象的关系:

1.对象是具体的,是看得见也摸得着的现实世界实实在在的个体。

2.类是抽象的,是现实世界中很多个同类事物的抽象

2、构造方法和this关键字

2.1、构造方法

1.构造方法一般定义为public的。[备注:在单例时会用到private.]

2.构造方法没有返回值,包括也没有void这种类型的返回值。

3.构造方法名与类名必须一致。

4.一个类如果没有提供构造方法,则JVM会为我们提供一个默认无参的构造方法。但是,

一旦我们定义了自己的构造方法,则系统不会再为我们提供任何形式的构造方法了。

5.构造方法的作用:就是实现局部变量为全局赋值(简化了对对象的赋值操作)。

2.2、this关键字

1.如果在构造方法中使用this,代表通过局部变量为全局变量进行赋值。如果没有this根据软件开发中的就近原则,就会自己赋值给己。

2.this在构造方法中就代表当前构造出来的哪个对象

3.this([参数列表])代表调用本类的其它构造方法,它只能放在调用的构造方法的第一行上,所以在一个构造方法中只能调用一次this([参数列表])

/**
* 功能:汽车类
*/
public class Car {

public String brand;    //汽车品牌
public String color;    //汽车颜色
public double price;    //汽车价格
public Integer wheels;  //汽车轮子数

//创建无参构造方法
public Car() {
    System.out.println("这是一个无参构造方法");
}

//创建带一个参数的有参构造方法
public Car(String brand) {
    this(); //调用无参构造方法
    this.brand = brand;
    System.out.println("这是一个带一个参数的有参构造方法");
}

//创建带两个参数的有参构造方法
public Car(String brand, String color) {
    this(brand);    //调用带一个参数的有参构造方法
    this.color = color;
    System.out.println("这是一个带两个参数的有参构造方法");
}

//创建带三个参数的有参构造方法
public Car(String brand, String color, double price) {
    this(brand, color); //调用带两个参数的有参构造方法
    this.price = price;
    System.out.println("这是一个带三个参数的有参构造方法");
}

//创建带四个参数的有参构造方法
public Car(String brand, String color, double price, Integer wheels) {
    this(brand, color, price);  //调用带三个参数的有参构造方法
    this.wheels = wheels;
    System.out.println("这是一个带四个参数的有参构造方法");
}

public void start() {
    System.out.println("一辆颜色为" + color + "的" + brand + "汽车正在启动....");
}

public void run() {
    System.out.println("一辆颜色为" + color + "的" + brand + "汽车正在奔跑....");
}

public void stop(){
    System.out.println("一辆颜色为" + color + "的" + brand + "汽车正在停止....");
}

}

2.3、利用构造方法创建对象

public static void main(String[] args) {
    //test01();
    test02();
}

/**
 * 功能:利用无参构造方法创建对象
 * 分析:默认为执行一遍无参构造方法
 */
private static void test01() {
    //创建一个汽车对象
    Car car = new Car();
    //通过对象.属性的方法为对象赋值
    car.brand = "宝马";
    car.color = "白色";
    car.price = 300000;
    car.wheels = 4;
    //调用方法
    car.start();
    car.run();
    car.stop();
}

/**
 *功能:利用有参构造方法创建对象
 * 分析:多个有参构造方法的调用会出现层级调用
 */
private static void test02() {
    //创建一个带四个参数的有参构造方法
    Car car = new Car("奔驰","黑色",400000,4);
    //调用方法
    car.start();
    car.run();
    car.stop();
}

3、toString方法与equals方法

toString方法的作用:简化对对象属性的打印输出

equals方法的作用:定义我们自己对对象的比较规则。此时,我们需要重写父类Object的equals方法

//重写父类的toString方法
public String toString() {
    return "品牌:" + this.brand + "\n颜色:" + this.color + "\n价格:" + this.price + "\n轮子数:" + this.wheels;
}

//重写equals方法
public boolean equals(Object obj) {
    Car car = (Car) obj;
    return this.brand.equals(car.brand) && this.price == price;
}

4、Java访问修饰符

private: 修饰符代表只在当前类的内部访问
protected: 只在父子类中可以访问,无论是否是父子类都可以在同一个包下访问
public:可以在任意位置访问
default:只要在包的内部都可以访问
public>protected>default>private
修饰符 当前类 同一包类 父子类 其他包(父子类) 使用范围
private ok no no no 变量、方法、不能修饰外部类
protected ok ok ok ok 变量、方法、不能修饰外部类
default ok ok no no 类、接口、变量、方法
public ok ok ok ok 类、接口、变量、方法

5、面向对象三大特征—-封装

public class Manager {

    public String username; //登录名
    public String password; //密码

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

6、面向对象三大特征—-继承

父类:

public class Person {
    private int pid;
    private String pname;
    protected String sex;
    private int age;
    public String addr;

    public Person() {
    }

    public Person(String pname, String sex) {
        this.pname = pname;
        this.sex = sex;
    }

    public Person(String pname, String sex, int age, String addr) {
        this(pname, sex);
        this.age = age;
        this.addr = addr;
    }

    public Person(int pid, String pname, String sex, int age, String addr) {
        this.pid = pid;
        this.pname = pname;
        this.sex = sex;
        this.age = age;
        this.addr = addr;
    }

    //定义读取年龄的方法
    public int getAge() {
        return this.age;
    }

    //定义设置年龄的方法
    public void setAge(int age) {
        if (age > 0 && age <= 150) {
            this.age = age;
        } else {
            System.out.println("年龄不合法!");
        }
    }

    //定义读取pname的方法
    public String getPname() {
        return this.pname;
    }

    //定义设置pname的方法
    public void setPname(String pname) {
        if (pname.length() >= 2) {
            this.pname = pname;
        } else {
            System.out.println("人名不合法!");
        }
    }

    //自定义方法
    public void welcome() {
        this.pid = 1001;
        this.pname = "小明";
        System.out.println("Person ---> welcome()");
    }

    @Override
    public String toString() {
        return pid + "\t" + pname + "\t" + sex + "\t" + age + "\t" + addr;
    }

}

子类(super关键字):

public class Student extends Person {

    private int score;//成绩

    public Student() {

    }

    public Student(int score) {
        this();
        this.score = score;
    }

    public Student(int pid, String pname, String sex, int age, String addr, int score) {
        super(pid, pname, sex, age, addr); //调用父类的有参构造方法
        this.score = score;
    }

    public void sayHello() {
        this.sex = "男";
    }

    //重写父类的welcome()方法:
    public void welcome() {
        super.welcome();
        System.out.println("Student--->welcome().");
    }

    @Override
    public String toString() {
        return super.toString() + "\t" + this.score;
    }

}

继承小结:

1、所有类的父类是Object类。

2、父类有的子类都有,父类没有的子类可以添加,父类有的子类可以改变

3、构造方法不能被继承,方法和属性可以被继承

4、子类的构造方法隐式调用父类不带参数的构造方法,子类显示调用父类构造方法使用super关键字

7、面向对象三大特征—-多态

多态:同一种事物的多种形态,如水果类就有苹果、香蕉、桔子等。继承的表现形式就是多态的体现

8、方法的重载和重写

重载和重写的区别:

重载(overload):可以发生于一个类,也可以发生于子类和父类之间(子类继承父类方法,同时完成方法重载)

  • 方法名相同,参数类型、顺序、个数不同
  • 访问修饰符、返回值类型不能成为构成重载的条件
  • 例如:无参构造方法和有参构造方法

重写(override):子类重写父类的方法

  • 方法名、返回值类型、参数列表相同
  • 子类的访问修饰符权限不得低于父类的访问修饰符权限

重载:

public class Calcuator {

    public int add(int a, int b) {
        return a + b;
    }

    public int add(int a, int b,int c) {
        return a + b+c;
    }

    public double add(int a, double b) {
        return a + b;
    }

    public float add(int a, float b) {
        return a + b;
    }

    public float add(float a, int b) {
        return a + b;
    }

}

重写:

/**
 * 类名:Parent父类
 */
public class Parent {

    public void sayHello(){
        System.out.println("Parent--->sayHello()");
    }

}
/**
 * 类名:Child子类继承Parent父类并重写父类的sayHello方法
 */
public class Child extends Parent{

    @Override
    public void sayHello() {
        System.out.println("Child--->sayHello()");
    }

}

测试重载和重写:

/**
 * 测试方法的重载
 */
@Test
public void test01(){
    Calcuator calcuator = new Calcuator();
    int s1 = calcuator.add(1, 2);
    System.out.println("s1 = " + s1);
    int s2 = calcuator.add(1, 2, 3);
    System.out.println("s2 = " + s2);
    float s3 = calcuator.add(3.14f, 1);
    System.out.println("s3 = " + s3);
    float s4 = calcuator.add(2, 3.14f);
    System.out.println("s4 = " + s4);
    double s5 = calcuator.add(3, 3.14);
    System.out.println("s5 = " + s5);
}

/**
 * 测试方法的重写
 */
@Test
public void test02(){
    Parent parent = new Child();
    parent.sayHello();
}

9、final关键字

1、被final修饰的类不能被继承

2、被final修饰的变量一般为常量,不能被修改,常量字段必须赋初始值

3、被final修饰的方法不能被重写

10、Java单例设计模式

懒汉式:

public class User{
    //1、懒汉式
    private static User user = null;
    private User(){}
    public static User getUser(){
        if(user==null){
            user=new User();
        }
        return user;
    }
}

饿汉式:

public class User{
    //2、饿汉式
    private static User user = new User();
    private User(){}
    public static User getUser(){
        return user;
    }
}

测试单例模式:

@Test
public void test01() {
    User user1 = User.getUser();
    System.out.println("user1 = " + user1);
    User user2 = User.getUser();
    System.out.println("user2 = " + user2);
}

两者的区别

(1)在饿汉式中可以在本类中创建本类对象时加上final关键字,但在懒汉式中不可以。

(2)饿汉式在类加载时就创建了对象实例,懒汉式则是在使用时才创建对象实例。 –最主要的区别

(3)饿汉式不存在线程安全问题,而懒汉式存在线程安全问题。

(4)饿汉式存在浪费资源的问题,而懒汉式不存在浪费资源的问题。

  饿汉式 懒汉式
创建对象的时机 类加载时 使用时
线程安全方面 不存在 存在
资源浪费方面 存在 不存在

11、Java的向上转型和向下转型

向上转型:父类的引用指向了子类

优点:增强了程序的扩展性

缺点:不能调用子类有父类没有的方法

/**
 *功能:向上转型:父类的引用指定子类(开发中常用):如果父子类都有相同的方法,使用的是子类的对象
 */
@Test
public void test01(){
    Fruit fruit = new Apple(3);
    fruit.sayHello();
}

向下转型:把父类引用强制转换为子类对象

优点:可以调用子类有父类没有的方法

缺点:不能增强程序的扩展性

/**
 *功能:向下转型:子类有方法而父类没有方法
 */
@Test
public void test02(){
    Fruit fruit = new Apple(5);
    ((Apple)fruit).welcome();
}

12、抽象类和接口

12.1、抽象类

1、必须使用abstract修饰

2、抽象类中可以有抽象方法,也可以有实现的方法

3、一个抽象方法必须存在于抽象类中

4、一个抽象类的子类必须完全实现这个抽象类中的所有抽象方法,否则,它也是一个抽象子类

5、抽象类中可以有构造方法,但不能被实例化

6、抽象类的作用:提供一种对子类行为的约束机制

public abstract class Animal {

    //1. 抽象方法必须存在于抽象类中
    public abstract void breathe();
    public Animal(){
        System.out.println("Animal构造方法.");
    }
    public void sayHello(){
        System.out.println("Animal-->sayHello()");
    }
    public abstract void welcome();

}

12.2、接口

1、必须使用interface修饰

2、接口中的方法是由:public abstract来修饰

3、接口中的变量都是常量,是由:public static final来修饰的。必须要赋初始值

4、接口中不能有构造方法,也不能被实例化

5、接口中可以有默认方法和静态方法,前者可以由接口的实现类来调用,后者由接口直接调用

6、子类实现接口,必须要实现其中的所有抽象方法,否则,它也是一个抽象子类

7、接口主要是定义规范的,而抽象类主要是一种对子类的一种约束机制

8、因为接口中有了默认方法,所以,我们可以在默认中定义好默认功能实现,到时,就可以根据需要 重写我们需要的方法,完成自己的功能就可以了,而这一操作,原来需要使用适配器模式才能实现。

public interface USB {
    //1. 接口中的变量是由: public static  final 修饰的,是常量,必须要赋初始值
    int width = 1;

    //2. 接口中的方法是由public abstract 修饰的
    void read();
    void write();

    //3. 接口中不能定义构造方法
    // public USB(){
    //
    // }

    //4. 【JDK1.7之后才出现】接口中的定义的默认方法,它是由接口的实现类来调用的
    default void print(){
        System.out.println("这是接口的默认方法.");
    }
    //5. 【JDK1.7之后才出现】接口中的定义的静态方法,它是由接口直接来调用的
    static void welcome(){
        System.out.println("这是接口中的静态方法.");
    }

}

12.3、抽象类和接口的区别

区别 抽象类 接口
关键字 abstract interface
组成 构造方法、普通方法、抽象方法、static方法、常量、变量 抽象方法、全局变量
子类使用 class 子类 extends 抽象类 class 子类 implements 接口,接口
关系 抽象类可以实现多个接口 接口不能继承抽象类,却可以继承多个父接口
权限 可以使用各种权限 只能使用public权限
限制 单继承局限 没有单继承局限
子类 抽象类和接口都必须由子类,子类必须要覆写全部的抽象方法
实例化对象 依靠子类对象的向上转型进行对象的实例化

12.4、接口的使用方法

jdk1.7之前的使用方法:(适配器设计模式)
public interface A{
     void t1();
     void t2();
     void t3();
     void t4();
     void t5();
     void t6();
}
public class Test01 implements A{
     public void t1(){
		xxxx
     }
     public void t2(){
     }
     public void t3(){
     }
     public void t4(){
     }
     public void t5(){
     }
     public void t6(){
     }
}
public class Aadapter implements A{
     public void t1(){
     }
     public void t2(){
     }
     public void t3(){
     }
     public void t4(){
     }
     public void t5(){
     }
     public void t6(){
     }
}
public class Test02 extends Aadapter {
    public void t1(){
		xxxx
    }
}

public class Test03 extends Aadapter {
    public void t2(){
		yyyy
    }
}
jdk1.7之后的使用方法:(默认方法)
public interface AA{
     default void t1(){
     }
     default void t2(){
     }
     default void t3(){
     }
     default void t4(){
     }
     default void t5(){
     }
     default void t6(){
     }
}
public class Test04 implements AA{
    void t1(){
		xxxxxsx
   	}
}

12.5、面向接口编程思想

USB接口
public interface USB {
    void read(); //读
    void write(); //写
}
Mp3实现类
public class Mp3 implements USB{

    @Override
    public void read() {
        System.out.println("Mp3正在读取数据...");
    }

    @Override
    public void write() {
        System.out.println("Mp3正在写入数据...");
    }
}
FlashDisk实现类
public class FlashDisk implements USB{
    @Override
    public void read() {
        System.out.println("FlashDisk正在读取数据...");
    }

    @Override
    public void write() {
        System.out.println("FlashDisk正在写入数据...");
    }
}
Computer类(面向接口编程)
public class Computer {

    public void run(USB usb){
        usb.read();
        usb.write();
    }

}
测试类:
/**
 * 测试面向接口编程
 */
@Test
public void test02() {
    Computer computer = new Computer();
    USB usb = new Mp3();
    computer.run(usb);
    usb = new FlashDisk();
    computer.run(usb);
}

12.6、接口中实现与继承问题

1、接口可以继承自多个接口

2、一个类可以实现多个接口,多个接口之间用逗号隔开

3、一个类可以继承自另一个类,并且同时可以实现多个接口

/**
 * 接口可以继承自多个接口
 * extends关键字:必须发生在同种事物之间,如类与类之间、接口与接口之间
 */
public interface A extends B,C{
    void a();
}
interface B{
    void b();
}
interface C{
    void c();
}

/**
 * 一个类可以实现多个接口,多个接口之间用,隔开
 */
class TC implements B,C{

    @Override
    public void b() {

    }

    @Override
    public void c() {

    }
}

class TB{
    void b(){}
}

/**
 * 一个类继承自另一个类,同时可以实现多个接口
 */
class TD extends TB implements B,C{

    @Override
    public void b() {

    }

    @Override
    public void c() {

    }
}

12.7、案例:宠物超市

宠物IPet接口:
public interface IPet {
    String getName();//获取名称
    String getColor();//获取颜色
    int getAge();//获取年龄
}
Cat类实现IPet接口:
public class Cat implements IPet{

    String name;
    String color;
    int age;

    public Cat(){

    }

    public Cat(String name,String color,int age){
         this.name=name;
         this.color=color;
         this.age=age;
    }


    public void setColor(String color) {
        this.color = color;
    }


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


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

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getColor() {
        return color;
    }

    @Override
    public int getAge() {
        return age;
    }
}
Dog类实现IPet接口:
public class Dog implements IPet{

    String name;
    String color;
    int age;

    public Dog() {
    }

    public Dog(String name, String color, int age) {
        this.name = name;
        this.color = color;
        this.age = age;
    }

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

    public void setColor(String color) {
        this.color = color;
    }

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

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getColor() {
        return color;
    }

    @Override
    public int getAge() {
        return age;
    }
}
PetUI界面类:
public class PetUI {

    private PetManager manager = new PetManager();

    //1、展示菜单
    public void showMenu() {
        System.out.println("========== 宠物商店 ==========");
        System.out.println("[1] 添加宠物");
        System.out.println("[2] 查看宠物");
        System.out.println("[3] 查找宠物");
        System.out.println("[4] 修改宠物");
        System.out.println("[5] 退出系统");
        System.out.println("=============================");
        Scanner scanner = new Scanner(System.in);
        //用户选择
        userSelect(scanner);
    }

    //2、用户选择
    private void userSelect(Scanner scanner) {
        System.out.println("请选择:");
        int choice = scanner.nextInt();
        switch (choice){
            case 1:
                addPet(scanner);
                break;
            case 2:
                manager.printPetInfo();
                break;
            case 3:
                searchPet(scanner);
                break;
            case 4:
                System.out.println("修改宠物");
                break;
            case 5:
                System.exit(0);
                break;
        }
        //判断用户是否继续选择
        System.out.println("是否继续(y/n):");
        String inCon = scanner.next();
        if (inCon.equalsIgnoreCase("y")){
            userSelect(scanner);
        }
    }

    //3、添加宠物界面
    private void addPet(Scanner scanner) {
        System.out.println("请输入宠物类型(1:猫,2:狗):");
        int type = scanner.nextInt();
        System.out.println("请输入宠物名称:");
        String name = scanner.next();
        System.out.println("请输入宠物颜色:");
        String color = scanner.next();
        System.out.println("请输入宠物年龄:");
        int age = scanner.nextInt();
        //构造一个宠物对象
        IPet pet = null;
        switch (type){
            case 1:
                pet = new Cat(name,color,age);
                break;
            case 2:
                pet = new Dog(name,color,age);
                break;
            default:
                System.out.println("输入的类型不合法!");
                break;
        }
        //添加宠物
        manager.addPet(pet);
    }

    //4、查找宠物
    private void searchPet(Scanner scanner) {
        System.out.println("请输入要查找宠物的关键字:");
        String keywords = scanner.next();
        //查找宠物
        manager.searchPet(keywords);
    }

}
PetManager宠物管理类:
public class PetManager {

    //定义一个宠物类型数组
    private IPet[] pets = new IPet[5];
    //定义数组的下标
    private int count=0;

    //添加宠物功能
    public void addPet(IPet pet) {
        if (count<pets.length){
            pets[count++]=pet;
        }else {
            System.out.println("宠物已满!");
        }
    }

    //查找宠物功能
    public void searchPet(String keywords) {
        //定义查找到的宠物数组
        IPet[] petList = new IPet[pets.length];
        //定义查找到的数组的下标
        int n = 0;
        //循环查询
        for (int i = 0; i < count; i++) {
            //得到当前的宠物
            IPet pet = pets[i];
            //根据宠物的名字或颜色查找
            if (pet.getName().contains(keywords) || pet.getColor().contains(keywords)){
                petList[n++]=pet;
            }
        }
        //打印查找到的数组
        if (n==0){
            System.out.println("没有找到宠物");
        }else {
            printPetInfo(petList);
        }
    }

    //打印数组
    public void printPetInfo(IPet... petList) { //表示petList的长度是可变的
        System.out.println("宠物信息如下:");
        System.out.println("------------------------------");
        //长度为0就打印全部信息
        if (petList.length==0){
            petList=pets;
        }
        for (int i = 0; i < petList.length; i++) {
            //得到当前宠物
            IPet pet = petList[i];
            if (pet!=null){
                //打印宠物信息
                System.out.println("宠物的名称:"+pet.getName());
                System.out.println("宠物的颜色:"+pet.getColor());
                System.out.println("宠物的年龄:"+pet.getAge());
                System.out.println("==============================");
            }
        }
        System.out.println("---------------------------------");
    }
}
测试类:
public class TestPet {
    public static void main(String[] args) {
        //构建页面
        PetUI petUI = new PetUI();
        petUI.showMenu();
    }
}

13、Java异常类

13.1、编译期异常

1、文件未找到异常:FileNotFoundException

2、类不存在异常:ClassNotFoundException

/**
 * 编译期异常
 * 处理异常的方法一:使用throws关键字抛出对应的异常
 */
private static void test02() throws FileNotFoundException, ClassNotFoundException {
    //文件不存在异常:FileNotFoundException
    FileInputStream fileInputStream = new FileInputStream("c:/aa.txt");
    //类不存在异常:ClassNotFoundException
    Class.forName("xxx");
}

13.2、运行时异常

1、空指针异常:NullPointerException

2、数组下标越界异常:ArrayIndexOutOfBoundsException

3、算术异常:ArithmeticException

4、数字格式转换异常:NumberFormatException

5、输入不匹配异常:InputMismatchException

/**
 *运行时异常RuntimeException
 */
private static void test01(Scanner scanner) {
    //1、空指针异常:java.lang.NullPointerException
    /*String str =null;
    str.length();*/

    //2、数组下标越界异常:ArrayIndexOutOfBoundsException
    /*int[] a = new int[3];
    a[3]=1;*/

    //3、算术异常:ArithmeticException
    //int i = 10 / 0;

    //4、数字格式转换异常:NumberFormatException
    //int a = new Integer("abc");

    //5、输入不匹配异常:InputMismatchException
    System.out.println("输入一个整数:");
    int a = scanner.nextInt();
}

13.3、处理异常的方法

1、使用try…catch语句捕捉异常

2、使用throws抛出异常

3、使用自定义异常

13.4、try…finally的使用

/**
 * 在try语句块中有return语句,此时,finally语句块是否执行,如果执行,是在return之前还是之后执行?(面试题)
 * finally在return之前执行
 */
private static int test05(int i){
    try {
        System.out.println("(try)i = " + i);
        return i++;
    }finally {
        System.out.println("(finally)i = " + i);
    }
}

14、Java集合类

14.1、List接口

14.1.1、ArrayList子类

编号 方法名称 方法描述 | :–: | :——————————————————–: | :——————————–: add(Object o)、add(int index,Object element) 向集合中添加元素 addAll(Collection c)、addAll(int index,Collection c) 将新集合中的元素添加到原来的集合中 remove(Object o)、remove(int index) 从集合中移除元素 removeAll(Collection c) 删除存在原来集合中的集合元素 set(int index,Object o) 根据下标修改集合中对应的元素 get(int index) 根据下标获取集合中的元素 contains() 判断元素是否在集合中 |

/**
 * ArrayList集合的基本使用
 */
@Test
public void test01(){
    //创建一个List集合
    List list = new ArrayList();
    //添加集合元素
    list.add("hello");
    list.add(123);
    list.add(3.4);
    list.add('中');
    list.add(true);
    System.out.println("修改前的集合:"+list);
    //修改集合元素
    list.set(1,"world");
    System.out.println("修改后的集合:"+list);
    //添加多个元素
    List smallList = new ArrayList();
    smallList.add("aa");
    smallList.add("bb");
    smallList.add("cc");
    list.addAll(smallList);
    System.out.println("添加后的集合:"+list);
    //遍历集合
    //方法一:使用普通for循环
    System.out.println("===== 使用普通for循环遍历 =====");
    for (int i = 0; i < list.size(); i++) {
        Object o = list.get(i);
        System.out.print(o+" ");
    }
    //方法二:使用增强for循环
    System.out.println("\n===== 使用增强for循环遍历 =====");
    for (Object o : list) {
        System.out.print(o+" ");
    }
    //方法三:使用迭代器Iterator
    System.out.println("\n===== 使用迭代器Iterator遍历 =====");
    Iterator iterator = list.iterator();
    while (iterator.hasNext()){
        Object next = iterator.next();
        System.out.print(next+" ");
    }
    //方法四:使用forEach循环遍历
    System.out.println("\n===== 使用forEach循环遍历 =====");
    list.forEach(f->{
        System.out.print(f+" ");
    });
    //方法五:使用简化的forEach循环遍历
    System.out.println("\n===== 使用简化的forEach循环遍历 =====");
    list.forEach(System.out::println);
    //方法六:使用stream流遍历
    System.out.println("\n===== 使用stream流遍历 =====");
    list.stream().forEach(System.out::println);
    //根据下标移除集合元素
    list.remove(3);
    System.out.println("根据下标移除后的集合:"+list);
    //根据指定内容移除集合元素
    list.remove(true);
    System.out.println("根据指定内容移除后的集合:"+list);
    //移除多个元素
    list.removeAll(smallList);
    System.out.println("移除小集合后的集合:"+list);
}
14.1.2、Vector子类
/**
 * Vector集合的基本使用
 */
@Test
public void test02(){
    //创建一个List集合
    List list = new Vector();
    //添加集合元素
    list.add("hello");
    list.add(123);
    list.add(3.4);
    list.add('中');
    list.add(true);
    System.out.println("修改前的集合:"+list);
    //修改集合元素
    list.set(1,"world");
    System.out.println("修改后的集合:"+list);
    //添加多个元素
    List smallList = new ArrayList();
    smallList.add("aa");
    smallList.add("bb");
    smallList.add("cc");
    list.addAll(smallList);
    System.out.println("添加后的集合:"+list);
    //遍历集合
    //方法一:使用普通for循环
    System.out.println("===== 使用普通for循环遍历 =====");
    for (int i = 0; i < list.size(); i++) {
        Object o = list.get(i);
        System.out.print(o+" ");
    }
    //方法二:使用增强for循环
    System.out.println("\n===== 使用增强for循环遍历 =====");
    for (Object o : list) {
        System.out.print(o+" ");
    }
    //方法三:使用迭代器Iterator
    System.out.println("\n===== 使用迭代器Iterator遍历 =====");
    Iterator iterator = list.iterator();
    while (iterator.hasNext()){
        Object next = iterator.next();
        System.out.print(next+" ");
    }
    //方法四:使用forEach循环遍历
    System.out.println("\n===== 使用forEach循环遍历 =====");
    list.forEach(f->{
        System.out.print(f+" ");
    });
    //方法五:使用简化的forEach循环遍历
    System.out.println("\n===== 使用简化的forEach循环遍历 =====");
    list.forEach(System.out::println);
    //方法六:使用stream流遍历
    System.out.println("\n===== 使用stream流遍历 =====");
    list.stream().forEach(System.out::println);
    //根据下标移除集合元素
    list.remove(3);
    System.out.println("根据下标移除后的集合:"+list);
    //根据指定内容移除集合元素
    list.remove(true);
    System.out.println("根据指定内容移除后的集合:"+list);
    //移除多个元素
    list.removeAll(smallList);
    System.out.println("移除小集合后的集合:"+list);
}
14.1.3、Vector类与ArrayList类的区别

1、Vector集合开始出现在jdk1.0版本,ArrayList集合开始出现在jdk1.2版本

2、Vector集合是线程同步、安全性高、性能低;ArrayList集合是线程异步、性能更高

3、当集合容量不足时,Vector集合的长度会增加为原来的1倍,ArrayList集合的长度会增加为原来的1/2

14.1.4、ArrayList的应用:宠物超市
IPet接口:
/**
 * 宠物类
 */
public interface IPet {
    String getName();
    String getColor();
    int getAge();
}
Cat类:
/**
 * 猫类
 */
public class Cat implements IPet{

    private String name;
    private String color;
    private int age;

    public Cat() {
    }

    public Cat(String name, String color, int age) {
        this.name = name;
        this.color = color;
        this.age = age;
    }

    @Override
    public String getName() {
        return name;
    }

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

    @Override
    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
Dog类:
/**
 * 狗类
 */
public class Dog implements IPet{

    private String name;
    private String color;
    private int age;

    public Dog() {
    }

    public Dog(String name, String color, int age) {
        this.name = name;
        this.color = color;
        this.age = age;
    }

    @Override
    public String getName() {
        return name;
    }

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

    @Override
    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
petUI界面类:
public class PetUI {

    //创建宠物管理类对象
    private PetManager manager = new PetManager();

    /**
     * 1、展示菜单
     */
    public void showMenu() {
        //1.1、展示菜单
        System.out.println("========== 宠物商店 ==========");
        System.out.println("[1] 添加宠物");
        System.out.println("[2] 查看宠物");
        System.out.println("[3] 查找宠物");
        System.out.println("[4] 修改宠物");
        System.out.println("[5] 退出系统");
        System.out.println("=============================");
        //1.2、用户选择
        Scanner scanner = new Scanner(System.in);
        userSelect(scanner);
    }

    /**
     * 2、用户选择
     */
    private void userSelect(Scanner scanner) {
        //2.1、输入提示信息
        System.out.println("请选择:");
        int choice = scanner.nextInt();
        //2.2、根据用户选择进入对应的菜单
        switch (choice) {
            case 1:
                addPetMenu(scanner);
                break;
            case 2:
                manager.printPetInfo(null);
                break;
            case 3:
                searchPetMenu(scanner);
                break;
            case 4:
                System.out.println("修改宠物");
                break;
            case 5:
                System.exit(0);
                break;
            default:
                System.out.println("请重新选择!");
                break;
        }
        //2.3、是否继续选择菜单
        System.out.println("是否继续选择(y/n):");
        String isCon = scanner.next();
        if ("y".equalsIgnoreCase(isCon)) {
            userSelect(scanner);
        }
    }

    /**
     * 3、添加宠物菜单界面
     */
    private void addPetMenu(Scanner scanner) {
        //3.1、输入提示信息
        System.out.println("请输入要添加宠物的类型(1:猫,2:狗):");
        int type = scanner.nextInt();
        System.out.println("请输入宠物的名称:");
        String name = scanner.next();
        System.out.println("请输入宠物的颜色:");
        String color = scanner.next();
        System.out.println("请输入宠物的年龄:");
        int age = scanner.nextInt();
        //3.2、构建宠物对象
        IPet pet = null;
        //3.3、根据类型构建对象
        switch (type) {
            case 1:
                pet = new Cat(name, color, age);
                break;
            case 2:
                pet = new Dog(name, color, age);
                break;
            default:
                System.out.println("请重新输入!");
                break;
        }
        //3.4、实现添加宠物
        manager.addPet(pet);
    }

    /**
     * 4、查找宠物界面
     */
    private void searchPetMenu(Scanner scanner) {
        //4.1、输入提示信息
        System.out.println("请输入要查找宠物的关键字(名字或颜色):");
        String keywords = scanner.next();
        //4.2、打印查找的信息
        manager.searchPet(keywords);
    }
}
PetManager宠物管理类:
/**
 * 宠物管理类
 */
public class PetManager {

    //创建集合用来存储宠物对象
    private List<IPet> pets = new ArrayList<IPet>();

    /**
     * 1、添加宠物
     */
    public void addPet(IPet pet) {
        pets.add(pet);
    }

    /**
     * 2、打印宠物信息
     */
    public void printPetInfo(List<IPet> petList) {
        if (petList == null) {
            petList = pets;
        }
        //打印宠物信息
        System.out.println("宠物信息如下:");
        for (IPet pet : petList) {
            System.out.println("宠物的名称:" + pet.getName());
            System.out.println("宠物的颜色:" + pet.getColor());
            System.out.println("宠物的年龄:" + pet.getAge());
            System.out.println("---------------------------");
        }
    }

    /**
     * 3、查找宠物
     */
    public void searchPet(String keywords) {
        //定义一个新集合用来存储查找的信息
        List<IPet> list = new ArrayList<>();
        for (IPet pet : list) {
            if (pet.getName().contains(keywords) || pet.getColor().contains(keywords)){
                list.add(pet);
            }
        }
        //判断集合里面是否有内容
        if (list.size()>0){
            printPetInfo(list);
        }else {
            System.out.println("没有找到宠物!");
        }
    }
}
测试类:
public class TestPet {
    public static void main(String[] args) {
        PetUI petUI = new PetUI();
        petUI.showMenu();
    }
}
14.1.5、ArrayList泛型的使用
/**
 * ArrayList泛型的使用
 */
@Test
public void test01(){
    //1、定义一个ArrayList集合
    List<Student> studentList = new ArrayList<>();
    //2、为学生对象赋值
    Student student1 = new Student(1001,"张三","男",20,"上海");
    Student student2 = new Student(1002,"李四","男",21,"武汉");
    Student student3 = new Student(1003,"王五","男",22,"成都");
    //3、将学生对象添加到集合中去
    studentList.add(student1);
    studentList.add(student2);
    studentList.add(student3);
    //4、打印学生信息
    //4.1、方法一:增强for循环
    for (Student student : studentList) {
        System.out.println(student);
    }
    System.out.println("-------------------------------------------------------------");
    //4.2、方法二:使用流式编程
    studentList.stream().forEach(System.out::println);
    //5、修改学生
    //5.1、定义修改后的学生对象
    Student student4 = new Student(1004,"赵六","女",19,"杭州");
    //5.2、开始修改
    studentList.set(1,student4);
    System.out.println("-------------------------------------------------------------");
    studentList.forEach(System.out::println);
    //6、删除学生
    //6.1、根据下标删除
    studentList.remove(1);
    System.out.println("-------------------------------------------------------------");
    studentList.forEach(System.out::println);
    //6.2、根据内容删除
    studentList.remove(student3);
    System.out.println("-------------------------------------------------------------");
    studentList.forEach(System.out::println);
}
14.1.6、LinkedList集合
/**
 * LinkedList集合
 */
@Test
public void test02(){
    //1、定义一个LinkedList集合
    LinkedList<String> linkedList = new LinkedList<>();
    //2、向集合中添加元素
    linkedList.add("《三国演义》");
    linkedList.addFirst("《西游记》");//将元素放到集合的头部
    linkedList.addLast("《水浒传》");//将元素放到集合的尾部
    linkedList.push("《红楼梦》");//入栈
    //3、遍历集合
    for (String s : linkedList) {
        System.out.println(s);
    }
    System.out.println("------------");
    //4、出栈元素(从栈顶取出一个元素)
    String pop = linkedList.pop();
    System.out.println("pop = " + pop);
    System.out.println("------------");
    for (String s : linkedList) {
        System.out.println(s);
    }
    //5、查看栈顶元素(对栈元素没有影响)
    String peek = linkedList.peek();
    System.out.println("peek = " + peek);
    System.out.println("------------");
    for (String s : linkedList) {
        System.out.println(s);
    }
    //6、判断集合是否为空
    boolean empty = linkedList.isEmpty();
    System.out.println("empty = " + empty);
    //7、集合元素通过循环出栈演示
    System.out.println("集合元素通过循环出栈演示:");
    while (!linkedList.isEmpty()){
        String pop1 = linkedList.pop();
        System.out.println(pop1);
    }
    //8、获取集合的长度
    int size = linkedList.size();
    System.out.println("size = " + size);
}

14.2、Set接口

14.2.1、HashSet集合
/**
 * 1、HashSet的用法
 */
@Test
public void test01(){
    //1.1、定义一个Set集合
    Set<String> set = new HashSet<>();
    //1.2、向Set集合中添加元素
    set.add("周4");
    set.add("周1");
    set.add("周3");
    set.add("周2");
    set.add("周6");
    set.add("周5");
    //1.3、遍历集合
    //1.3.1、方法一:使用增强for循环
    for (String s : set) {
        System.out.print(s+" ");
    }
    System.out.println("\n---------------------");
    //1.3.2、方法二:使用迭代器
    Iterator<String> iterator = set.iterator();
    while (iterator.hasNext()){
        String next = iterator.next();
        System.out.print(next+" ");
    }
    System.out.println("\n---------------------");
    //1.3.3、使用foreach
    set.forEach(s -> System.out.print(s+" "));
    System.out.println("\n---------------------");
    //1.4、删除元素
    set.remove("周3");
    set.forEach(s -> System.out.print(s+" "));
}
14.2.2、TreeSet集合
/**
 * 2、TreeSet集合
 */
@Test
public void test02(){
    //2.1、定义一个Set集合
    Set<String> set = new TreeSet<>();
    //2.2、向Set集合中添加元素
    set.add("周4");
    set.add("周1");
    set.add("周3");
    set.add("周2");
    set.add("周6");
    set.add("周5");
    //2.3、遍历集合
    for (String s : set) {
        System.out.print(s+" ");
    }
}

14.3、Map接口

14.3.1、HashMap集合
/**
 * 1、HashMap的用法
 */
@Test
public void test01(){
    //1.1、定义一个HashMap集合
    Map<Integer, Student> map = new HashMap<>();
    //1.2、定义几个学生数据
    Student student1 = new Student(1001,"张三","男",20,"上海");
    Student student2 = new Student(1002,"李四","男",21,"武汉");
    Student student3 = new Student(1003,"王五","男",22,"成都");
    Student student4 = new Student(1004,"赵六","女",19,"杭州");
    //1.3、将数据添加到集合中
    map.put(student1.getId(),student1);
    map.put(student2.getId(),student2);
    map.put(student3.getId(),student3);
    //1.4、遍历集合
    //1.4.1、方法一:遍历所有的key的集合,通过key取得值
    Set<Integer> keySet = map.keySet();
    for (Integer key : keySet) {
        Student student = map.get(key);
        System.out.println(student);
    }
    //1.4.2、方法二:直接获取到值
    Collection<Student> values = map.values();
    for (Student value : values) {
        System.out.println(value);
    }
    //1.4.3、方法三:将key和value看作一个整体进行遍历
    Set<Map.Entry<Integer, Student>> entries = map.entrySet();
    for (Map.Entry<Integer, Student> entry : entries) {
        Integer key = entry.getKey();
        Student value = entry.getValue();
        System.out.println(key+"---->"+value);
    }
    //1.4.4、使用forEach遍历
    map.forEach((k,v)->System.out.println(k+"---->"+v));

    //1.5、修改集合元素
    //1.5.1、如果不存在指定的key,就将元素添加到集合中去
    map.putIfAbsent(student2.getId(),student4);
    //1.5.2、如果在集合中已存在某个元素,可以使用put(),此时存在相同的key,那么新值会覆盖旧值
    map.put(student2.getId(),student4);
    map.forEach((k,v)->System.out.println(k+"---->"+v));

    //1.6、根据key来删除集合元素
    map.remove(1002);
    map.forEach((k,v)->System.out.println(k+"---->"+v));

    //1.7、替换元素
    map.replace(1002,student2);
    map.forEach((k,v)->System.out.println(k+"---->"+v));

    //1.8、集合中是否包含指定的key
    boolean b = map.containsKey(1002);
    if (b){
        Student student = map.get(1002);
        System.out.println(student);
    }
}
14.3.2、Hashtable集合
/**
 * 2、Hashtable集合的用法
 */
@Test
public void test02(){
    //2.1、定义一个HashMap集合
    Hashtable<Integer, Student> map = new Hashtable<>();
    //2.2、定义几个学生数据
    Student stud1 = new Student(1001,"张三","男",20,"上海");
    Student stud2 = new Student(1002,"李四","男",21,"武汉");
    Student stud3 = new Student(1003,"王五","男",22,"成都");
    Student stud4 = new Student(1004,"赵六","女",19,"杭州");
    //2.3、将数据添加到集合中
    map.put(stud1.getId(),stud1);
    map.put(stud2.getId(),stud2);
    map.put(stud3.getId(),stud3);
    //2.4、遍历集合
    //2.4.1、方法一:使用forEach遍历
    map.forEach((k,v)->System.out.println(k+"---->"+v));
    //2.4.2、方法二:使用枚举迭代器
    Enumeration<Student> elements = map.elements();
    while (elements.hasMoreElements()){
        Student student = elements.nextElement();
        System.out.println(student);
    }
}
14.3.3、HashMap和Hashtable的区别

1、HashMap是JDK1.2后出现的新的集合类;Hashtable是JDK1.0后出现的旧的集合类。

2、HashMap是线程异步的,效率较高;Hashtable是线程同步的,效率较低,安全性较高

3、HashMap可以存放null键和null值;Hashtable放的话会出现空指针异常

4、二者都是key/value集合,都会出现在相同key的情况下出现新值覆盖旧值的情况

14.4、集合类的练习

案例一:从控制台接收10个整数进行排序,按降序在控制台输出
方法一:
/**
 * 案例一:从控制台接收10个整数进行排序,按降序在控制台输出
 * 方法一:使用Collections.sort()进行排序
 */
private static void test01(Scanner scanner) {
    //定义一个整型集合
    List<Integer> list = new ArrayList<>();
    //通过循环录入10个数
    System.out.println("请输入10个数字:");
    for (int i = 0; i < 10; i++) {
        //输入10个数
        int num = scanner.nextInt();
        //将这些数添加到集合中去
        list.add(num);
    }
    //对集合进行升序排序
    Collections.sort(list);
    System.out.println("升序排列的集合:" + list);
    //对集合进行降序排序
    Comparator<Object> comparator = Collections.reverseOrder();
    Collections.sort(list, comparator);
    //打印集合
    System.out.println("降序排列的集合:" + list);
}
方法二:
/**
 * 案例一:从控制台接收10个整数进行排序,按降序在控制台输出
 * 方法二:使用List集合
 */
private static void test02(Scanner scanner) {
    //定义一个整型集合
    List<Integer> list = new ArrayList<>();
    //通过循环录入10个数
    System.out.println("请输入10个数字:");
    for (int i = 0; i < 10; i++) {
        //输入10个数
        int num = scanner.nextInt();
        //将这些数添加到集合中去
        list.add(num);
    }
    //对集合进行排序
    //方法一:使用匿名内部类实现比较规则(降序)
    list.sort(new Comparator<Integer>() {
        @Override
        public int compare(Integer a, Integer b) {
            return b - a;
        }
    });
    //方法二:自定义内部静态类实现比较规则
    list.sort(null);
    list.sort(new MyListComparator());
    //方法三:使用lambda表达式
    list.sort((a, b) -> b - a);
    //方法四:使用stream排序
    list.stream().sorted((a, b) -> b - a).forEach(r -> System.out.print(r + "\t"));
}

/**
 * 自定义比较规则
 */
private static class MyListComparator implements Comparator<Integer> {
    //b-a:降序
    //a-b:升序
    @Override
    public int compare(Integer a, Integer b) {
        return b - a;
    }
}
案例二:写一个程序通过集合类Vector类,实现有学生添加、修改、查询、删除功能
/**
 * 案例二:写一个程序通过集合类Vector类,实现有学生添加、修改、查询、删除功能。
 */
@Test
public void test04(){
    //定义两个学生对象
    Student student1 = new Student(1001,"张三","男",20,"上海");
    Student student2 = new Student(1002,"李四","男",21,"武汉");
    //定义一个学生管理类
    StudentManager manager = new StudentManager();
    //添加学生功能
    manager.add(student1);
    //修改学生功能
    student1.setName("张小三");
    student1.setAddress("杭州");
    boolean b = manager.update(student1);
    if (b){
        System.out.println("修改成功!");
    }
    //查看学生
    manager.findAll();
    //删除学生
    manager.delete(student1.getId());
}
/**
 * 学生管理类
 */
public class StudentManager {

    //定义存储学生对象的集合
    private Map<Integer,Student> studentMap = new HashMap<>();

    /**
     *添加学生
     */
    public void add(Student st1) {
        studentMap.put(st1.getId(),st1);
    }

    /**
     *修改学生
     */
    public boolean update(Student st) {
        //判断集合中是否包含key
        if (studentMap.containsKey(st.getId())){
            studentMap.put(st.getId(),st);
            return true;
        }
        return false;
    }

    /**
     * 查看学生
     */
    public void findAll() {
        System.out.println("学生信息如下:");
        System.out.println("----------------------------------");
        if (studentMap.size()>0){
            studentMap.values().forEach(stud -> {
                System.out.println("编号:"+stud.getId());
                System.out.println("姓名:"+stud.getName());
                System.out.println("性别:"+stud.getSex());
                System.out.println("年龄:"+stud.getAge());
                System.out.println("地址:"+stud.getAddress());
            });
        }else {
            System.out.println("没有学生");
        }
    }

    /**
     * 删除学生
     */
    public void delete(int id) {
        if (studentMap.containsKey(id)){
            studentMap.remove(id);
        }else {
            System.out.println("没有您要删除的学生信息");
        }
    }
}
案例三:写一个程序向List集合类添加”a”,”abc”,”ab”,”ac”,”ab”,”b”,”b”等字符串,找出集合中存在重复的字符串在控制台输出,不重复的不输出。
/**
 * 功能: 案例三:写一个程序向List集合类添加”a”,”abc”,”ab”,”ac”,”ab”,”b”,”b”等字符串,
 * 找出集合中存在重复的字符串在控制台输出,不重复的不输出。30分
 */
@Test
public void test01() {
    //定义两个list集合和一个set集合
    List<String> list1 = new ArrayList<>();//原始数据集合
    List<String> list2 = new ArrayList<>();//元素不重复数据集合
    Set<String> set = new HashSet<>();//元素重复数据集合
    //向List1中添加元素
    list1.add("a");
    list1.add("abc");
    list1.add("ab");
    list1.add("ac");
    list1.add("ab");
    list1.add("b");
    list1.add("b");
    //遍历list1集合,看list2集合中是否有此元素
    for (String s : list1) {
        if (list2.contains(s)) {
            set.add(s);
        } else {
            list2.add(s);
        }
    }
    //打印set集合
    System.out.println("set = " + set);
}
案例四:写一个方法排除掉List集合中的重复对象后输出
/**
 * 案例四、写一个方法排除掉List集合中的重复对象后输出
 */
@Test
public void test02() {
    //定义两个list集合和一个set集合
    List<String> list1 = new ArrayList<>();//原始数据集合
    List<String> list2 = new ArrayList<>();//元素不重复数据集合
    Set<String> set = new HashSet<>();//元素重复数据集合
    //向List1中添加元素
    list1.add("a");
    list1.add("abc");
    list1.add("ab");
    list1.add("ac");
    list1.add("ab");
    list1.add("b");
    list1.add("b");
    //遍历list1集合,看list2集合中是否有此元素
    for (String s : list1) {
        if (list2.contains(s)) {
            set.add(s);
            list2.remove(s);//在集合list2中移除在list1中出现的重复元素
        } else {
            list2.add(s);
        }
    }
    //打印list1集合中元素不重复的数据
    System.out.println("list2 = " + list2);
}
案例五:自已编写一个程序,将list集合中所有重复的字符串去掉,只保留非重复的。
/**
 * 案例五:自已编写一个程序,将list集合中所有重复的字符串去掉,只保留非重复的。
 */
@Test
public void test03() {
    //定义两个list集合和一个set集合
    List<String> list1 = new ArrayList<>();//原始数据集合
    List<String> list2 = new ArrayList<>();//元素不重复数据集合
    Set<String> set = new HashSet<>();//元素重复数据集合
    //向List1中添加元素
    list1.add("a");
    list1.add("abc");
    list1.add("ab");
    list1.add("ac");
    list1.add("ab");
    list1.add("b");
    list1.add("b");
    //遍历list1集合,看list2集合中是否有此元素
    for (String s : list1) {
        if (list2.contains(s)) {
            set.add(s);
        } else {
            list2.add(s);
        }
    }
    //在list1集合中移除重复的元素
    list1.removeAll(set);
    //打印list1集合中元素不重复的数据
    System.out.println("list1 = " + list1);
}
案例六:有以下字符串String str=“56.89.5.3.75.98.98.26.15.44”,请定义一个类,写个方法,实现对该字符串按照.号进行分隔,并将结果按照从大到小的顺序进行排列。
/**
 * 功能: 案例六:有以下字符串String str=“56.89.5.3.75.98.98.26.15.44”,请定义一个类,
 * 写个方法,实现对该字符串按照.号进行分隔,并将结果按照从大到小的顺序进行排列。
 */
@Test
public void test04() {
    //定义一个字符串
    String str = "56.89.5.3.75.98.98.26.15.44";
    //定义一个整型的list集合用来存储分割后的数据
    List<Integer> list = new ArrayList<>();
    //定义字符串的分割
    String[] split = str.split("\\.");
    //遍历数组
    for (String s : split) {
        //将每一项转换成整数后添加到集合中去
        list.add(new Integer(s));
    }
    //对集合进行排序
    list.sort((a, b) -> b - a);
    //打印排序后的集合
    list.forEach(r -> System.out.print(r + "\t"));
}
案例七:编一段代码,实现在控制台输入一组数字后,排序后在控制台输出
public static void main(String[] args) {
    test05(new Scanner(System.in));
}

/**
 * 案例七:编一段代码,实现在控制台输入一组数字后,排序后在控制台输出 。
 */
private static void test05(Scanner scanner) {
    //定义一个存放数字的集合
    List<Integer> list = new ArrayList<>();
    //开始输出
    System.out.println("开始输入一组数据:");
    while (true){
        //得到输入的数字
        String number = scanner.next();
        //判断输入的数字是否是end
        if (number.equals("end")){
            break;
        }
        //使用正则表达式提取数字
        if (number.matches("[^0-9]+$")){
            list.add(new Integer(number));
        }
    }
    //对数字集合进行排序
    Collections.sort(list);
    //打印集合
    System.out.println(list);
}
案例八:从类似如下的文本文件中读取出所有的姓名,并打印出重复次数最多的姓名和重复的次数。
@Test
public void test01() {
    //1、定义一个list集合并且将这些数据添加到集合
    List<String> list = Arrays.asList("1,张三,28", "2,李四,35", "3,张三,28", "4,王五,35", "5,张三,28", "6,李四,35", "7,赵六,28", "8,田七,35");
    //2、定义一个map集合存储取出来的姓名和出现的次数
    Map<String, Integer> map = new HashMap<>();
    //3、遍历list集合
    for (String s : list) {
        //3.1、根据逗号拆分字符串
        String[] split = s.split(",");
        //3.2、得到人名
        String name = split[1];
        //3.3、根据人名获取出现的次数
        Integer count = map.get(name);
        //3.4、如果出现的次数为null,证明是第一次将人名放进map中
        if (count == null) {
            count = 0;
        }
        //3.5、将人名作为key,次数作为键存入到map集合中
        map.put(name, count + 1);
    }
    //4、找到人名出现最多的次数
    Integer max = Collections.max(map.values());
    System.out.println("max = " + max);
    //5、遍历map集合
    map.forEach((k, v) -> {
        if (v == max) {
            System.out.print(k + "\t");
        }
    });
}

15、Java常用类的使用

随机数类:

/**
 * Random类的基本用法
 */
@Test
public void test01(){
    //1、定义一个随机数类对象
    Random random = new Random();
    //2、查看一个整数范围内的随机数
    //2.1、查看整数范围
    int minValue = Integer.MIN_VALUE;
    int maxValue = Integer.MAX_VALUE;
    System.out.println("minValue = " + minValue);
    System.out.println("maxValue = " + maxValue);
    //2.2、输出随机数
    int i = random.nextInt();
    System.out.println("i = " + i);
    //3、在指定整数范围内产生随机数
    int i1 = random.nextInt(100);
    System.out.println("在[0,100)内的随机数:" + i1);
    //4、如何产生一个指定范围内的随机数?(m,n)之间的随机数?
    //4.1、定义参数的范围
    int m = 10,n=50;
    //4.2、产生在(0,n-m)之间的随机数
    int i2 = random.nextInt(n - m);
    //4.3、将当前获取的随机数加上m,即获取(m,n)之间的随机数
    int x = i2+m;
    //打印输出的随机数
    System.out.println("在[m,n)内的随机数:" + x);
}

日期类:

/**
 * 1、日期类(Date)
 */
@Test
public void test01() {
    //1.1、定义一个日期对象
    Date dt = new Date();
    //1.2、获取当前系统时间
    String s = dt.toLocaleString();
    System.out.println("当前系统时间:" + s);
    //1.3、得到日期的各个部分
    //1.3.1、获取当前日期的年份
    int year = dt.getYear() + 1900;
    //1.3.2、获取当前日期的月份
    int month = dt.getMonth() + 1;
    //1.3.3、获取当前日期的日
    int date = dt.getDate();
    //1.3.4、获取当前日期的时
    int hours = dt.getHours();
    //1.3.5、获取当前日期的分
    int minutes = dt.getMinutes();
    //1.3.6、获取当前日期的秒
    int seconds = dt.getSeconds();
    System.out.println(year + "-" + month + "-" + date + " " + hours + ":" + minutes + ":" + seconds);
}

日期格式化类:

/**
 * 2、日期格式化类(SimpleDateFormat)
 */
@Test
public void test02() {
    //获取当前时间
    Date date = new Date();
    //创建一个SimpleDateFormat对象
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");
    //对当前日期进行格式化处理
    String format = sdf.format(date);
    //打印结果
    System.out.println("format = " + format);
}

日历类:

/**
 * 3、日历类(Calendar)
 */
@Test
public void test03() {
    //3.1、创建日历类对象
    Calendar calendar = Calendar.getInstance();
    //3.2、得到日历的各个部分
    int year = calendar.get(Calendar.YEAR);
    int month = calendar.get(Calendar.MONTH) + 1;
    int date = calendar.get(Calendar.DAY_OF_MONTH);
    int hours = calendar.get(Calendar.HOUR_OF_DAY);
    int minutes = calendar.get(Calendar.MINUTE);
    int seconds = calendar.get(Calendar.SECOND);
    //3.3、打印
    System.out.println(year + "-" + month + "-" + date + " " + hours + ":" + minutes + ":" + seconds);
    //3.4、修改日历
    //3.4.1、修改指定年月日
    calendar.set(2000, 1, 1);
    //3.4.2、查看修改后的日历
    Date time = calendar.getTime();
    System.out.println(time.toLocaleString());
    //3.4.3、修改年份
    calendar.set(Calendar.YEAR, 2010);
    System.out.println(calendar.getTime().toLocaleString());
    //3.4.4、添加指定日期
    calendar.add(Calendar.MONTH, 5);
    System.out.println(calendar.getTime().toLocaleString());
}

日历类的应用:

/**
 * 案例一:求从2013年1月1日起,至2013年12月31日止,有多少个星期日
 */
@Test
public void test04() {
    //1、创建日历类
    Calendar calendar = Calendar.getInstance();
    //2、将日期修改为2013年1月1日
    calendar.set(2013, 1 - 1, 1);
    //3、定义一个计数器来统计出现星期日的次数
    int count = 0;
    //4、开始循环
    while (true) {
        //4.1、得到当前年份数,如果年份数不等于2013则跳出循环
        int year = calendar.get(Calendar.YEAR);
        if (year != 2013) {
            break;
        }
        //4.2、判断当前的星期数是不是星期日
        if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            count++;
            //格式化当前日期
            String dtStr = formatDate(calendar.getTime());
            //输出当前日期
            System.out.println(dtStr);
        }
        //4.3、将当前日期增加1天
        calendar.add(Calendar.DATE, 1);
    }
    System.out.println("2013年一共有" + count + "个星期日");
}

/**
 * 日期格式化
 */
private String formatDate(Date time) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss E");
    return sdf.format(time);
}

/**
 * 案例二:求本月所有星期六的日期,并以yyyy年MM月dd日的方式输出?
 */
@Test
public void test05() {
    //1、创建日历类
    Calendar calendar = Calendar.getInstance();
    //2、修改日期为本月1日
    calendar.set(Calendar.DATE, 1);
    //3、得到当前月份数
    int month = calendar.get(Calendar.MONTH);
    //4、开始循环
    while (true){
        //4.1、判断当前月份数是不是本月
        if (calendar.get(Calendar.MONTH)!=month){
            break;
        }
        //4.2、判断是否是星期六,如果是就打印
        if (calendar.get(Calendar.DAY_OF_WEEK)==Calendar.SATURDAY){
            String dtStr = formatDate(calendar.getTime());
            System.out.println(dtStr);
        }
        //4.3、每次添加1天
        calendar.add(Calendar.DATE,1);
    }
}

JDK8新特性 LocalDateTime类和ZonedDateTime类:

/**
 * LocalDateTime与ZonedDateTime的使用
 */
@Test
public void test01() {
    //1.1、得到LocalDateTime对象(LocalDateTime: 本地日期时间处理类)
    LocalDateTime now = LocalDateTime.now();
    //1.2、将上面的对象进行格式化处理
    // String format = now.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E"));
    //  String format = now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);

    //ZonedDateTime: 代表一个跟时区相关的日期时间类,一般在一些通过框架中使用springboot/springCloud
    String string = ZonedDateTime.now().toString();
    System.out.println("string = " + string);

    String fmt = ZonedDateTime.now().format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL));
    //String format = now.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL));
    //1.3、打印
    System.out.println("fmt = " + fmt);

    //1.4、修改时间并格式化(LocalDateTime的用法)
    //1.4.1、增加时间,可以是负数
    // String dtStr = now.plus(1, ChronoUnit.YEARS)
    //         .format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E"));
    String dtStr = now.plusYears(1).format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E"));
    System.out.println("dtStr = " + dtStr);
    //1.4.2、减少1月
    //now.minus(1,ChronoUnit.MONTHS);
    dtStr = now.minusMonths(1).format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E"));
    System.out.println("dtStr = " + dtStr);
    //1.4.3、增加一天
    dtStr = now.plusDays(1).format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E"));
    System.out.println("dtStr = " + dtStr);

    //1.5、修改日期与时间(ZonedDateTime的用法)
    // dtStr = ZonedDateTime.now().plus(5, ChronoUnit.DAYS)     //通用写法
    dtStr = ZonedDateTime.now().plusDays(5)                  //简化写法
            .format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL));
    System.out.println("dtStr = " + dtStr);
}

LocalDateTime类的应用:

1、使用LocalDateTime修改时间
/**
 * 1、使用LocalDateTime修改时间
 */
@Test
public void test01() {
    //1.1、定义LocalDateTime对象
    String format = LocalDateTime.now()
            .withYear(2011) //年份
            .with(ChronoField.MONTH_OF_YEAR, 10) //月
            .withDayOfMonth(20) //日
            .withHour(12).withMinute(30).withSecond(50) //时分秒
            .format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E"));
    //1.2、打印结果
    System.out.println(format);
}
2、求本月所有星期六的日期,并以yyyy年MM月dd日的方式输出
/**
 * 2、求本月所有星期六的日期,并以yyyy年MM月dd日的方式输出
 */
@Test
public void test02() {
    //2.1、将当前时间的天数修改为当前月份的第一天
    LocalDateTime dt = LocalDateTime.now().withDayOfMonth(1);
    //2.2、得到当前时间的月份数
    int month = dt.getMonthValue();
    System.out.println("month = " + month);
    //2.3、构造一个循环每次添加一天,直到月份数不是当前月
    while (true) {
        //2.3.1、判断是否是星期六
        if (dt.getDayOfWeek() == DayOfWeek.SATURDAY) {
            String dtStr = dt.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 E"));
            System.out.println(dtStr);
        }
        //2.3.2、判断是否是本月,不是就退出
        if (dt.getMonthValue() != month) {
            break;
        }
        //2.3.3、每次增加一天
        dt = dt.plusDays(1);
    }
}
3、写一程序在控制台输出,今年下半年中,所有日期尾号是3、6、9的日期。如:3号、6号、9号、13号、16号、19号
/**
 * 3、写一程序在控制台输出,今年下半年中,所有日期尾号是3、6、9的日期。如:3号、6号、9号、13号、16号、19号
 */
@Test
public void test03() {
    //3.1、得到当前日期并修改为7月1日
    LocalDateTime dt = LocalDateTime.now().withMonth(7).withDayOfMonth(1);
    //3.2、得到当前日期的年份
    int year = dt.getYear();
    //3.3、构造一个循环,每次增加一天,判断当前天数的尾号是否是3、6、9
    while (true) {
        //3.3.1、得到当前天数
        int day = dt.getDayOfMonth();
        //3.3.2、判断个位数是否是3、6、9
        if (day % 10 == 3 || day % 10 == 6 || day % 10 == 9) {
            String dtStr = dt.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 E"));
            System.out.println(dtStr);
        }
        //3.3.3、判断退出条件
        if (dt.getYear() != year) {
            break;
        }
        //3.3.4、每次增加一天
        dt = dt.plusDays(1);
    }
}
4、根据所学的java类库,设计一个方法,随机输入一个日期(例如2014-4-15)后,得到该日期对应星期几,距离下个月的1日(2014-5-1)还有多少天
/**
 * 1、根据所学的java类库,设计一个方法,随机输入一个日期(例如2014-4-15)后,得到该日期对应星期几,距离下个月的1日(2014-5-1)还有多少天
 */
@Test
public void test01() {
    //1.1 根据传入的日期字符串,返回这个日期距离下个月一号的天数
    int days = getDays("2020-04-15");
    System.out.println("距离下个月一号还有:" + days + "天!");
}

/**
 * 2、根据传入的日期串,返回当前日期距离下个月一号的天数
 *
 * @param dtStr
 * @return
 */
private int getDays(String dtStr) {
    //2.1、转换字符串为日期
    LocalDate dt = LocalDate.parse(dtStr, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    //2.2、得到当前月份数
    int month = dt.getMonthValue();
    //2.3、定义代表天数的计数器
    int count = 0;
    //2.4、构造循环,判断是否到了下个月一号
    while (true) {
        //2.4.1、每次增加一天
        dt = dt.plusDays(1);
        //2.4.2、累加计数器
        count++;
        //2.4.3、判断是否到达下个月
        if (dt.getMonthValue() != month) {
            break;
        }
    }
    //2.5、返回实际的天数
    return count;
}
5、将字符串”2021-1-1″表示的日期数据,使用LocalDate进行封装,并继续下面要求
/**
 * 1、案例二:将字符串"2021-1-1"表示的日期数据,使用LocalDate进行封装,并继续下面要求 (20分)
 * 1)输出为星期几(10分)
 * 2)计算上面"2021-1-1"日期距离今天有多少天(10分)
 */
@Test
public void test01() {
    //1.1、调用方法根据传入的日期串,返回距离今天的天数
    int days = getDays("2021-01-01");
    //1.2、打印天数
    System.out.println("days = " + days);
}

private int getDays(String s) {
    //2.1、定义返回的结果计数器
    int count = 0;
    //2.2、首先,将传入的日期字符串转换为日期对象LocalDate
    LocalDate dt = LocalDate.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    //2.3、得到今天的年月日
    LocalDate now = LocalDate.now();
    //2.4、得到今天的年份数
    int year = now.getYear();
    //2.5、得到今天的月份数
    int month = now.getMonthValue();
    //2.6、得到今天的天数
    int day = now.getDayOfMonth();
    //2.7、开始循环,判断如果到达当前日期就退出
    while (true) {
        //2.7.1、每次增加一天
        dt = dt.plusDays(1);
        //2.7.2、累加计数器
        count++;
        //2.7.3、判断是否是今天的日期,如果是就退出
        if (dt.getYear() == year && dt.getMonthValue() == month && dt.getDayOfMonth() == day) {
            break;
        }
    }
    //2.8、返回计数器对应的天数
    return count;
}
6、根据所学的java类库,设计一个方法,随机输入一个日期(例如2021-4-15)
/**
 * 1、根据所学的java类库,设计一个方法,随机输入一个日期(例如2021-4-15)
 */
@Test
public void test01() {
    int days = getDays("2021-04-15");
    System.out.println("距离下个月1号还有:" + days + "天!");
}

private int getDays(String dtStr) {
    //2.1、将传入的日期串转换为日期对象
    Date dt = MyUtil.convertToDate(dtStr);
    //2.2、定义当前时间的日历对象
    Calendar cal = Calendar.getInstance();
    cal.setTime(dt);
    //2.3、定义计数器
    int count = 0;
    //2.4、得到当前的月份数
    int month = cal.get(Calendar.MONTH);
    //2.5、循环判断,是否到达5月,如果到达就退出
    while (true) {
        //2.5.1、每次增加一天
        cal.add(Calendar.DAY_OF_MONTH, 1);
        //2.5.2、累加计数器
        count++;
        //2.5.3、判断当前的月份数是否与源来的相等,不相等证明到达了下个月
        if (cal.get(Calendar.MONTH) != month) {
            break;
        }
    }
    //2.6 返回天数
    return count;
}
public class MyUtil {
    /**
     * 将日期字符串转换为日期对象
     * @param dtStr 日期字符串
     * @return 返回值
     */
    public static Date convertToDate(String dtStr) {
        //1.1 定义SimpleDateFormat对象
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        //1.2 转换并输出
        try {
            return sdf.parse(dtStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}

16、Java IO流操作

16.1、File类的使用

File类对文件的操作:
/**
 * 1、File类操作文件
 */
@Test
public void test01() throws IOException {
    //1.1、定义一个File类
    File file = new File("d:/abc.txt");
    //1.2、判断文件是否存在
    if (!file.exists()) {
        //文件不存在就创建文件
        file.createNewFile();
    }
    //1.3、查看文件是否可读、可写、可执行
    boolean canRead = file.canRead();           //是否可读
    boolean canWrite = file.canWrite();         //是否可写
    boolean canExecute = file.canExecute();     //是否可执行
    System.out.println("canRead = " + canRead + ", canWrite = " + canWrite + ", canExecute = " + canExecute);
    //1.4、查看文件大小(以字节为单位)
    long length = file.length();
    System.out.println("length = " + length);
    //1.5、查看文件名和文件路径
    String fileName = file.getName();
    System.out.println("文件名:" + fileName);
    String fileAbsolutePath = file.getAbsolutePath();
    System.out.println("文件的绝对路径:" + fileAbsolutePath);
    String fileParent = file.getParent();
    System.out.println("文件的父路径:" + fileParent);
    //1.6、查看文件所在磁盘的总共大小(以字节为单位)
    long totalSpace = file.getTotalSpace();
    System.out.println("磁盘总大小:" + totalSpace / 1024 / 1024 / 1024 + "GB.");
    //1.7、查看文件所在磁盘的可用大小
    long freeSpace = file.getFreeSpace();
    System.out.println("磁盘可用大小:" + freeSpace / 1024 / 1024 / 1024 + "GB.");
    //1.8、给文件改名
    file.renameTo(new File("d:/ac.txt"));
    //1.9、删除文件
    file.delete();
}
File类对文件夹的操作:
/**
 * 2、File类操作文件夹
 */
@Test
public void test02(){
    //2.1、创建单个文件夹
    File dir = new File("d:/abcd");
    //2.2、判断该文件夹是否存在
    if (!dir.exists()){
        dir.mkdir();
    }
    //2.3、创建多个文件夹
    dir = new File("d:/a/b/c");
    if (!dir.exists()){
        dir.mkdirs();
    }
    //2.4、判断是文件还是文件夹
    boolean dirDirectory = dir.isDirectory();
    boolean dirFile = dir.isFile();
    System.out.println("dirDirectory = " + dirDirectory);
    System.out.println("dirFile = " + dirFile);
    //2.5、遍历文件夹
    //2.5.1、查看文件夹中的文件及文件夹名字
    File dirs = new File("d:/java");
    String[] list = dirs.list();
    for (String s : list) {
        System.out.println(s);
    }
    System.out.println("--------------------------------------------");
    //2.5.2、将指定文件夹中的文件及文件夹遍历到File数组中
    File[] files = dirs.listFiles();
    for (File file : files) {
        System.out.println(file.getAbsolutePath()+",大小:"+file.length());
    }
}
File类的应用:
/**
 * 3、File类实战-查看指定文件夹下所有内容(含子文件夹)
 */
@Test
public void test03(){
    //3.1、定义要查看的文件夹
    File dirs = new File("d:/java");
    //3.2、定义要查看目录的文件
    getDirs(dirs);
}

/**
 * 递归查看指定文件夹
 */
private void getDirs(File dirs) {
    if (dirs.isDirectory()){
        System.out.println("[目录]:"+dirs.getAbsolutePath());
        for (File file : dirs.listFiles()) {
            getDirs(file);
        }
    }else {
        System.out.println(dirs.getAbsolutePath());
    }
}

16.2、字节流的使用

字节输入流:FileInputStream
/**
 * 1、使用FileInputStream读取文件
 */
@Test
public void test01() throws IOException {
    //1.1、定义文件对象
    File file = new File("d:/abc.txt");
    //1.2、定义输入流对象
    FileInputStream fileInputStream = new FileInputStream(file);
    //1.3、定义存放读取数据的数组
    byte[] b = new byte[(int) file.length()];
    //1.4、将文件读取到字节数组中
    fileInputStream.read(b);
    //1.5、将字节数组转换为字符串
    String str = new String(b);
    //1.6、打印
    System.out.println("str = " + str);
    //1.7、关闭流
    fileInputStream.close();
}
字节输出流:FileOutputStream
/**
 * 2、使用FileOutputStream读取文件
 */
@Test
public void test02() throws IOException {
    //2.1、定义文件对象
    File file = new File("d:/abc.txt");
    //2.2、定义输出流对象
    //情况一:采用覆盖的方式定义输出流
    //FileOutputStream fileOutputStream = new FileOutputStream(file);
    //情况二:采用追加的方式定义输出流
    FileOutputStream fileOutputStream = new FileOutputStream(file,true);
    //2.3、准备要写出去的数据
    String info = "hahaha";
    //2.4、将字符串转换为字节数组
    byte[] bytes = info.getBytes();
    //2.5、将指定的字节数组输出
    fileOutputStream.write(bytes);
    //2.6、关闭流
    fileOutputStream.close();
}
字节流的应用:
案例一:使用字节流读写文本文件
/**
 *3、使用字节流读写文本文件
 */
@Test
public void test03() throws IOException{
    //3.1、定义要读取的文件对象
    File file = new File("d:/abc.txt");
    //3.2、定义要写入的文件对象
    File destFile = new File("e:/abc.txt");
    //3.3、定义输入流与输出流
    FileInputStream fileInputStream = new FileInputStream(file);
    FileOutputStream fileOutputStream = new FileOutputStream(destFile);
    //3.4、定义存放数据的字节数组
    byte[] b = new byte[(int) file.length()];
    //3.5、将文件中的内容读取到字节数组中
    fileInputStream.read(b);
    //3.6、将字节数组中的数据写入到目标文件中
    fileOutputStream.write(b);
    //3.7、关闭流
    fileInputStream.close();
    fileOutputStream.close();
}
案例二:实现mp3文件的复制功能
/**
 * 4、实现mp3文件的复制功能
 */
@Test
public void test04() throws IOException{
    //4.1、定义要读取的源文件
    File file = new File("f:/music/HandClap.mp3");
    //4.2、定义要追加的目标文件
    File destFile = new File("f:/music/生僻字.mp3");
    //4.3、定义文件输入流对象
    FileInputStream fileInputStream = new FileInputStream(file);
    //4.4、定义文件输出流对象
    FileOutputStream fileOutputStream = new FileOutputStream(destFile);
    //4.5、定义存放读取数据的字节数组
    byte[] b = new byte[(int) file.length()];
    //4.6、将文件中的内容读取到字节数组中
    fileInputStream.read(b);
    //4.7、将字节数组中的数据写入到目标文件中
    fileOutputStream.write(b);
    //4.8、关闭流
    fileInputStream.close();
    fileOutputStream.close();
}

16.3、字符流的使用

字符输入流:FileReader
/**
 * 1、FileReader读取文件内容
 */
@Test
public void test01() throws IOException {
    //1.1、定义要读取的文件对象
    File file = new File("d:/abc.txt");
    //1.2、定义输入流对象
    FileReader fileReader = new FileReader(file);
    //1.3、定义存放数据的字符数组
    char[] ch = new char[(int) file.length()];
    //1.4、读取文件存放到字符数组中
    fileReader.read(ch);
    //1.5、将字符数组转换为字符串
    String info = new String(ch);
    //1.6、输出
    System.out.println("info = " + info);
    //1.7、关闭流
    fileReader.close();
}
字符输出流:FileWriter
/**
 * 2、FileWrite写入文件内容
 */
@Test
public void test02() throws IOException{
    //2.1、定义要写入的文件内容
    File file = new File("d:/abc.txt");
    //2.2、定义文件的输出流写入文件内容,以追加的方式添加内容
    FileWriter fileWriter = new FileWriter(file,true);
    //2.3、定义要写入的文件内容
    String info ="hello,java";
    //2.4、开始写入文件内容
    fileWriter.write(info);
    //2.5、关闭流
    fileWriter.close();
}
字符流的应用:
案例一:实现文本文件的复制
/**
 * 3、实现文本文件的复制
 */
@Test
public void test03() throws IOException{
    //3.1、定义源文件
    File file = new File("d:/abc.txt");
    //3.2、定义目标文件
    File destFile = new File("d:/ab.txt");
    //3.3、定义输入流对象用来读取文件内容
    FileReader fileReader = new FileReader(file);
    //3.4、定义输出流对象用来写入文件内容
    FileWriter fileWriter = new FileWriter(destFile);
    //3.5、定义字符数组用来存放读取的文件内容
    char[] ch = new char[(int)file.length()];
    //3.6、开始读取内容
    fileReader.read(ch);
    //3.7、将字符数组中的内容写入到目标文件中
    fileWriter.write(ch);
    //3.8、关闭流
    fileReader.close();
    fileWriter.close();
}
案例二:将某个目录下的.java的文件所有文件复制至另一个目录下,子目录文件也能复制
/**
 *案例一:将某个目录下的.java的文件所有文件复制至另一个目录下,子目录文件也能复制
 */
@Test
public void test01() throws IOException {
    //1.1、定义要读取文件的对象
    File file = new File("d:/javabak");
    //1.2、递归进行文件的复制
    getDirs(file);
}

/**
 * 2、递归复制文件
 */
private void getDirs(File file) throws IOException{
    //2.1、如果是目录就递归
    if (file.isDirectory()){
        File[] files = file.listFiles();
        for (File f : files) {
            getDirs(f);
        }
    }else { //2.2、如果是文件,并且文件后缀名为.java,就复制文件
        //2.2.1、得到文件名
        String name = file.getName();
        //2.2.2、判断后缀名是.java
        if (name.endsWith(".java")){
            //2.2.3、定义要复制到目标文件的对象
            //第一步:得到源文件的父路径
            String parent = file.getParent();
            //第二步:将源文件的父路径替换成目标文件的父路径
            String destParent = parent.replace("d:", "e:");
            //第三步:根据源文件父路径创建多级文件夹
            File parentDir = new File(destParent);
            if (!parentDir.exists()){
                parentDir.mkdirs();
            }
            //第四步:构建目标文件对象
            File destFile = new File(parentDir,name);

            //2.2.4、定义输入流对象用来读取文件内容
            FileReader fileReader = new FileReader(file);
            //2.2.5、定义输出流对象用来写入文件内容
            FileWriter fileWriter = new FileWriter(destFile);
            //2.2.6、定义字符数组用来存放读取的文件内容
            char[] ch = new char[(int)file.length()];
            //2.2.7、开始读取内容
            fileReader.read(ch);
            //2.2.8、将字符数组中的内容写入到目标文件中
            fileWriter.write(ch);
            //2.2.9、关闭流
            fileReader.close();
            fileWriter.close();
        }
    }
}
案例三:将指定文件中内容读取按指定格式输出
/**
 * 案例二:将指定文件中内容读取按指定格式输出
 * 方法一:对字符串按照|进行拆分
 */
@Test
public void test02() throws IOException{
    //定义要读取的文件对象
    File file = new File("f:/testdemo.txt");
    //定义输入流对象
    FileReader fileReader = new FileReader(file);
    //定义存放读取的文件内容的字符数组
    char[] ch = new char[(int) file.length()];
    fileReader.read(ch);
    //将字符数组转换为字符串
    String info = new String(ch);
    //将字符串进行拆分
    String[] split = info.split("\\|");
    //对拆分后的数组进行打印
    for (String s : split) {
        System.out.println(s);
    }
    //关闭流
    fileReader.close();
}
/**
 * 案例二:将指定文件中内容读取按指定格式输出
 * 方法二:对字符串按照|进行拆分
 */
@Test
public void test03() throws IOException{
    //定义要读取的文件对象
    File file = new File("f:/testdemo.txt");
    //定义输入流对象
    FileReader fileReader = new FileReader(file);
    //定义存放读取的文件内容的字符数组
    char[] ch = new char[(int) file.length()];
    fileReader.read(ch);
    //将字符数组转换为字符串
    String info = new String(ch);
    //将字符串中的|替换成\n
    String replace = info.replace("|", "\n");
    System.out.println(replace);
    //关闭流
    fileReader.close();
}
案例四:递归某个指定目录,并输出此目录下的文件后缀名及后缀名出现的次数
/**
 * 案例三:递归某个指定目录,并输出此目录下的文件后缀名及后缀名出现的次数
 */
@Test
public void test04(){
    //定义一个大Map
    Map<String,Map<String,Integer>> mapMap = new HashMap<>();
    //定义要读取的文件对象
    File file = new File("d:/java");
    //进行递归调用
    getFiles(file,mapMap);
    //打印map值
    System.out.println(mapMap);
}

/**
 * 读取指定目录下的后缀名及其出现的次数
 */
private void getFiles(File file, Map<String, Map<String, Integer>> mapMap) {
    //如果是目录就递归
    if (file.isDirectory()){
        //得到子目录
        File[] files = file.listFiles();
        //将当前的目录路径放到大map中作为key,其值为新的小map
        mapMap.put(file.getAbsolutePath(), new HashMap<>());
        //进行递归调用
        for (File f : files) {
            getFiles(f,mapMap);
        }
    }else{ //如果是文件就得到文件的父路径,根据父路径得到上面添加进去的小map,从而在小map中放后缀名和出现的次数
        //得到当前文件的父路径
        String parent = file.getParent();
        //根据父路径得到小map
        Map<String,Integer> small = mapMap.get(parent);
        //得到当前文件的后缀名
        //得到文件名
        String name = file.getName();
        //得到文件的后缀名
        int index = name.lastIndexOf(".");
        String suffix = "";  //代表后缀名
        if (index > -1){
            suffix = name.substring(index);
        }
        //根据后缀名在小map中获取出现的次数
        Integer count = small.get(suffix);
        //如果是第一次出现,次数为null,为count设置默认值为0
        if (count == null){
            count = 0;
        }
        //将当前后缀名出现的次数加1后添加到小map中
        small.put(suffix,count + 1);
    }
}

16.4、缓冲流的使用

缓冲输入流:BufferReader
import java.io.*;

/**
 * Reader字符输入流(读文件)
 * -子类BufferedReader
 * -缓冲区,效率更高
 */
public class Demo04 {
    public static void main(String[] args) {
        //show1();

        show2();
    }

    private static void show2() {
        //通过InputStreamReader指定编码
        try(FileInputStream inputStream = new FileInputStream("file/a.txt");
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "GBK");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader)){

            //读完
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                //读不到换行符,所以需要println
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void show1() {
        try (FileReader fileReader = new FileReader("file/a.txt");
             BufferedReader bufferedReader = new BufferedReader(fileReader)) {

            /**
             * 读取一行,游标下移
             * 返回读取到的内容,读不到时,返回null
             * 读不到换行符
             */
            //读一次
           /* String line = bufferedReader.readLine();
            System.out.println(line);

            String line2 = bufferedReader.readLine();
            System.out.println(line2);*/

            //读完
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                //读不到换行符,所以需要println
                System.out.println(line);
            }

            //可以读取到换行符
            /*char[] c = new char[10];
            int length;
            while((length = bufferedReader.read(c)) != -1){
                String s = new String(c, 0, length);
                System.out.print(s);
            }*/
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
缓冲输出流:BufferWriter
import java.io.*;

/**
 * Writer字符输出流(写文件)
 * -子类BufferedWriter
 * 带缓冲区,效率更高
 */
public class Demo08 {
    public static void main(String[] args) {
        //show1();

        show2();
    }

    private static void show2() {
        //BufferedWriter使用OutputStreamWriter构造,指定输出文件的编码
        try (FileOutputStream outputStream = new FileOutputStream("file/d.txt");
             OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, "GBK");
             BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter)) {

            //输出字符串到文件中
            String s = "Hello你好啊";
            bufferedWriter.write(s);

            //新建一行(输出一个换行符)
            bufferedWriter.newLine();

            bufferedWriter.write(s);

            //输出流关闭前,刷新缓冲区
            bufferedWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void show1() {
        //BufferedWriter使用FileWriter构造,无法指定编码,默认当前程序的编码输出
        try (FileWriter fileWriter = new FileWriter("file/c.txt");
             BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) {

            //输出字符串到文件中
            String s = "Hello你好啊";
            bufferedWriter.write(s);

            //新建一行(输出一个换行符),方案一:
            bufferedWriter.newLine();

            //新建一行(输出一个换行符),方案二:
            //bufferedWriter.write("\r\n");

            bufferedWriter.write(s);

            //输出流关闭前,刷新缓冲区
            bufferedWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
缓冲流的应用:
案例一:实现文本文件的复制
import java.io.*;

/**
 * 练习:复制文本文件
 * 复制文件:C:/Windows/setupact.log
 * 到文件:D:/myFile/myPrime.txt
 */
public class Demo09 {
    public static void main(String[] args) {
        //判断目标文件夹是否存在
        File file = new File("D:/myFile");
        if (!file.exists()) {
            //不存在则创建该文件夹
            boolean mkdir = file.mkdir();
            System.out.println("是否创建文件夹:" + mkdir);
        }

        try (InputStream inputStream = new FileInputStream("C:/Windows/setupact.log");
             InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "GBK");
             BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
             OutputStream outputStream = new FileOutputStream("D:/myFile/myPrime.txt");
             OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, "GBK");
             BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter)) {

            //读取内容
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                //将内容写到指定文件中,使用GBK编码输出
                bufferedWriter.write(line);
                //输出换行符
                bufferedWriter.newLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

16.5、数据流的使用

数据输入流:DataInputStream
数据输出流:DataOutputStream
数据流的应用:
案例一:实现二进制文件的读写
import java.io.*;

/**
 * 二进制文件的读写
 */
public class Demo10 {
    public static void main(String[] args) {
        try (InputStream inputStream = new FileInputStream("file/1.jpg");
             DataInputStream dataInputStream = new DataInputStream(inputStream);
             OutputStream outputStream = new FileOutputStream("file/222.png");
             DataOutputStream dataOutputStream = new DataOutputStream(outputStream)) {

            //读取文件内容
            byte[] b = new byte[1024];
            int length;
            while ((length = dataInputStream.read(b)) != -1) {
                //将读取到的内容存入另一个文件
                dataOutputStream.write(b, 0, length);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

16.6、序列化和反序列化

序列化:将对象的状态写入到特定的流中的过程

反序列化:从特定的流中获取数据重写构建对象的过程

实现序列化的步骤:

第一步:实现Serializable接口

第二步:

第三步:

第四步:

版权声明:本文为爱星觉罗原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/axaxwan/p/16703637.html