Java基础学习笔记

基础语法

变量

标识符的组成部分: 下划线、数字和字符 三部分组成,且不能以数字为开头。

变量: 程序在运行期间可以被改变的量;
变量的定义: 数据类型 变量名;
变量初始化: 变量名 = 初始化值;
变 量 必 须 先 声 明 后 使 用。

package chap01; // package的作用是声明当前类所在的包,放在最上面.
// 引入包: import 包;
// 我们引入包的目的是要使用该包下的类

import java.util.Scanner;   // 引入一个Scanner(键盘输入)类

public class bianLiangUse {
    public static void main(String[] args) {
        
	    // 变量在同一作用域内不能重名;
        int numBer01 = 1;        // 定义(声明)整型变量 long > int > short > byte
        float numBer02 = 1F;     // 定义(声明)浮点型变量,float > double(精度更高,占8个字节)
        String str01 = "String数据";  // " "双引号为字符串型, ' '单引号为字符型
        String str02 = " ";

        System.out.println("整型变量:" + numBer01 + "," 
                           + "浮点型变量:" 
                           + numBer02 + "," 
                           + "运算结果:"  
                           + (numBer01 + numBer01));
        System.out.println("String数据:" + str01);
        System.out.println("字符数据:" + str02);

        /*
            int age;
            String name;
            age = sr.nextInt();
            name = sr.next();
            System.out.println("个人信息如下:");
            System.out.println(age);
            System.out.println(name);
        */
    }
}

/*  
	final 关键字 -> 常量
    在某些情况下会使用到 final 关键字
    1. 当不希望类被继承时,可以用final修饰
    2. 当不希望父类的某个方法被子类覆盖/重写时,可以用final修饰
    3. 当不希望类的某个属性的值被修改时,可以用final修饰
    4. 当不希望某个局部变量被修改时,可以用final修饰(即我们常说的常量)  
*/

变量分为: 属性(成员变量) 和 局部变量;
全局变量: 即属性,作用域为整个类.
局部变量: 除了属性之外的其他变量,作用域仅在它的代码块内.

全局变量可以不赋值直接使用,因为它有默认值,但是局部变量必须赋值后才能使用

class bianliangOne {
    int num1; // 全局变量,可以被本类使用,也可以被其他类使用(通过对象调用)
    public void show() {
        int num2; // 局部变量,作用域就在这个大括号(代码块)内.
    }
    // 属性和局部变量可以重名,在访问时遵循就近原则;如果在同一个方法中,两个局部变量不能重名.
}

数据类型

数据类型有两类:基本数据类型、引用数据类型
基本数据类型(8种):byte、short、int、long, float, double, char, boolean;
引用数据类型:数组, 接口, 类;

import java.util.Scanner;

public class DataTypeUse {
    public static void main(String[] args){
        
        byte byteNum01 = 10;        // byte在内存中占1个字节,1个字节等于8个bit(位)
        short shortNum01 = 10;      // short占2个字节
        int intNum01 = 10;          // int占4个字节
        long longNum01 = 10L;       // long占8个字节,在声明long变量时, 初始化值需在后面加上L
        float floatNum01 = 10F;     // float位浮点型,占用4个字节,声明float时,需要后面加上f或F
        double doubleNum01 = 10;    // double为浮点型,占用8个字节;double的精度比float更高。
        char charNum01 = '@';       // char在Java中占用2个字节,可以存放汉字和字符, 用单引号括起来。
        // char数据可以进行运算,它们在计算机中有对应的ASCII码值。
        boolean Boolean01 = false;  // boolean为布尔类型,占1个字节。
        // boolean在逻辑判断中以逻辑值返回(flase为0假,ture为非0真)。

        Scanner sr = new Scanner(System.in);    // 键盘输入
        System.out.println("请输入整型数据,浮点型数据(请按回车进行下一行输入):");
        intNum01 = sr.nextInt();    // 输入整型数据
        floatNum01 = sr.nextFloat();  // 输入浮点型数据

        System.out.println(charNum01 + charNum01);  // char数据进行运算(即它们的ASCII码运算)

        if(Boolean01){    // Boolean01为false
            System.out.println("false在逻辑中为假,是进不来if、while和switch的");
        }
}

/* 自动类型转换:按照基本数据类型的内存空间大小排序进行转换(Boolean不参与转换)。*/
// byte > char、short > int > float > long > double
int intNum02 = 'c'; // 符合自动类型转化规则,是可以的。
double doubleNum02 = 80;

// int n1 = 1.1; 这种将double赋值给int是错误的,容量大的赋值给容量小的会报错。
// byte、short、char三者可以进行运算,在运算前应先转换为int类型。
byteNum01 = 1;
shortNum01 = 1;
charNum01 = 'a';
int result01 = byteNum01 + shortNum01 + charNum01;
System.out.println("byte、short、char三者运算:" + result01);

/* 强制类型转换:当需要从大的转到小的,就需要用到强制类型转换。*/
// 语法:(需要强制类型转换的数据类型)变量名;
doubleNum01 = (int)20;  // 将double类型转换为int类型

/* 基本数据类型和String类型转换 */
// 1. 基本数据类型转换为String类型: 用 " + " 号即可
int n1 = 100;
System.out.println(n1 + "");
String s1 = 100 + "";
// 2. String类型转换为基本数据类型: 需调用parseXX方法
// Integer.parseInt(String.valueOf)
// Double.parseDouble(String.valueOf)
// Float.parseFloat(String.valueOf)
// Boolean.parseBoolean(String.valueOf)
// Long.parseLong(String.valueOf)
String s2 = "123";
System.out.println(Double.parseDouble(s2));
System.out.println(Integer.parseInt("123"));

// charAt(I): 得到字符串中第I个字符
String s3 = "123456ABCDE";
System.out.println(s3.charAt(2));   // 输出字符串中第3个字符(下标从0开始)
}
public class binarySystem {
    public static void main(String[] args) {
        // 二进制 0b开头
        int num01 = 0b1010;
        // 十进制 没有前缀
        int num02 = 1010;
        // 八进制 0开头
        int num03 = 01010;
        // 十六进制 0x开头
        int num04 = 0x1010;
        System.out.println("二进制:" + num01);     // 10
        System.out.println("十进制:" + num02);     // 1010
        System.out.println("八进制:" + num03);     // 520
        System.out.println("十六进制:" + num04);    // 4112
    }
}

运算符

public class OperationSymble {
    public static void main(String[] args) {
        
        // 运算符是一种特殊的符号,用于数据之间的运算、赋值和比较等操作

        // 一、算术运算符:+加 -减 *乘 /除
        int numBer01 = 12;
        int numBer02 = 123;
        System.out.println(numBer01 + numBer02);    // ’ + ‘ 号是数据之间进行相加,字符串中是连接。
        System.out.println(numBer01 - numBer02);
        System.out.println(numBer01 * numBer02);
        System.out.println(numBer02 / numBer01);

        // ++ --
        int a = 1;
        System.out.println(a++);    // a++: 先输出结果,再结果加1。例如输出结果后数值为2
        System.out.println(a--);    // a--: 先输出结果,再结果减1。例如输出结果后数值为0
        System.out.println(--a);    // --a: 数值减1,再输出结果。
        System.out.println(++a);    // ++a: 数值加1,再输出结果。
        int b = 10;
        int c = ++b;    // 等价于 b=b+1, c=b;
        c = b++;    // 等价于 c=b, b=b+1;

        // 面试题1:试问i等于多少?
        int temp,i = 1;
        i = i++;
        temp = i;
        i = i + 1;  // 未使用到i
        i = temp;
        System.out.println("i的结果为:"+ i);    // 1

        i = 1;
        i = ++i;
        i = i + 1;
        temp = i;
        i = temp;
        System.out.println("i的结果为:" + i);   // 3
        // i初始值为1,经过++i之后数值为2(++是先自增1后赋值),再经过i+1(2+1=3)。
        // 把i赋值给temp,再temp赋值给i,实际上i的值没有变化。

        /*
        * 1. 需求:假如还有59天放假,问:合XX个星期零XX天。
        * 2. 思路分析:
        *   1)使用 int 变量 days 保存天数
        *   2)一个星期是7天
        *      星期weeks: days / 7;
        *      零X天leftDays:days % 7;
        * */
        int days = 25911;
        int weeks = days / 7;
        int leftDays = days % 7;
        System.out.println(days + "天 共" + weeks + "星期零" + leftDays + "天");

        /* 二、关系运算符(比较运算符)
            关系运算符的结果都是boolean型,即 false 或 true;
            关系表达式常用于if语句或者循环语句中。*/
        int gxNum01 = 12;
        int gxNum02 = 13;
        System.out.println(gxNum01 >= gxNum02); // >= 大于等于, 符合条件则返回true 否则返回false。
        System.out.println(gxNum01 <= gxNum02); // <= 小于等于
        System.out.println(gxNum01 == gxNum02); // == 等于
        System.out.println(gxNum01 != gxNum02); // != 不等于

        /* 三、逻辑运算符
         *   逻辑于 && : 表达式有一边假,即为假(返回false),两边为真(非零)即为真
         *   逻辑或 || : 表达式有一边为真,即为真(返回true)
         *
         *   &&和&的区别:
         *       &: 如果第一个条件为false,后面的条件仍然为判断
         *      &&: 如果第一个条件为false,后面的条件不会判断,最终结果为false */
        int logicalNum01 = 5;
        int logicalNum02 = 6;
        if(logicalNum01 == 5 && logicalNum02 == 5){
            System.out.println(logicalNum01 + " " + logicalNum02);
        }
        if(logicalNum01 == 5 & logicalNum02 == 5){
            System.out.println(logicalNum01 + " " + logicalNum02);
        }

        /* 三元运算符: 条件表达式?表达式1:表达式2 */
        // 如果条件表达式为真则输出表达式1,否则输出表达式2
        int syNum01 = 1;
        int syNum02 = 2;
        int result = syNum01 > syNum02 ? 12 : 13;

        /* 利用三元运算符实现三个数中的最大值 */
        // 写法1
        int syMax01 = 6, syMax02 = 21, syMax03 = 3;
        int syMaxNum,syMaxResult;
        syMaxNum = syMax01 > syMax02 ? syMax01 : syMax02;
        syMaxResult = syMaxNum > syMax03 ? syMaxNum : syMax03;
        System.out.println("三个数中最大值为:" + syMaxResult);
        // 写法2
        int max =(syMax01 > syMax02 ? syMax01 : syMax02) 
            > syMax03 ?((syMax01 > syMax02) ? syMax01 : syMax02) 
            : syMax03;
        System.out.println("三个数中最大值为:" + max);
    }
}

控制结构

Java的控制结构有:顺序结构、选择结构、循环结构三种

顺序结构是指代码从上往下顺序执行,中间没有任何跳转和判断。

选择结构

public class ProcessControl {
    public static void main(String[] args){
       
        // 单if语句
        if(true){
            System.out.println(true);
        }
        
        // if..else 语句
        if(true){
            System.out.println(true);
        }else{
            System.out.println(false);
        }
        
        // if..else if..else 语句
        if(true){
            System.out.println(true);
        }else if(true){
            System.out.println(true);
        }else{
            System.out.println(false);
        }
}
// switch 选择语句
int n = 1;
switch(n){
    case 1:
        System.out.println(1);
        break;
    case 2:
        System.out.println(2);
        break;
    case 3:
        System.out.println(3);
        break;
    default:
        System.out.println("default");
}
/*  switch注意点:
        *   case子句必须是常量,而不能是变量;
        *   default是可选的,当没有匹配的case子句时就会执行default;
        *   如果没有break,代码会顺序执行到switch结尾,直到遇到break;
*/

循环结构

// for 循环
int i;
for(i = 1; i < 10; i++){
    System.out.println(1);
}

/*
for(1;2;4){
   3
}  代码先从1条件初始值开始,
   进入到2判断条件是否符合,
   再进入到3执行代码,
   4进行条件迭代,迭代后2条件符合则继续,否则就跳出循环。
*/
// while 循环
boolean boolean01 = true;
while(boolean01){   // 括号内为条件表达式,如果为假(0)则不进入循环体
    if(n == 1){
        boolean01 = false;
    }
    System.out.println(1);
}
// do..while 循环
do{
    if(n == 1){
        boolean01 = false;
    }
    System.out.println(1);
}while(boolean01);
}

控制结构案例

public class ProcessControl_homework_one {
    public static void main(String[] args) {

        /* 定义两个整型变量,判断二者的和是否能够被3和5整除并打印,求出能够整除的数值。*/
        int numBer01 = 10;
        int numBer02 = 15;
        int numResult01 = numBer01 + numBer02;
        if (numResult01 % 3 == 0 && numResult01 % 5 == 0) {
            System.out.println(numResult01 + "能够被3和5整除");
        } else {
            System.out.println(numResult01 + "不能被3和5整除");
        }
        int i,j;
        System.out.print("能被3和5整除的数:");
        for (i = 1; i < 100; i++) {
            if (i % 3 == 0 && i % 5 == 0) {
                System.out.print("\t" + i);
            }
        }
        System.out.println();

        /* 判断年份是否为闰年 */
        // 闰年条件:1.能被4整除,但不能被100整除;2.能被400整除
        int year = 2003;
        if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
            System.out.println(year + "是闰年");
        } else {
            System.out.println(year + "不是闰年");
        }

        /* 判断成绩得分 */
        // 写法1:switch语句
        int score = 89;
        switch (score / 10) {
            case 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("不合格或不合法");
        }
        // 写法2:if..else语句
        if (score >= 1 && score <= 100) {
            if (score >= 90) {
                System.out.println("成绩优秀");
            } else if (score >= 80 && score < 90) {
                System.out.println("成绩中等");
            } else if (score >= 70 && score < 80) {
                System.out.println("成绩良好");
            } else if (score >= 60 && score < 70) {
                System.out.println("成绩合格");
            } else {
                System.out.println("成绩不合格");
            }
        }

        /* 参加歌手比赛,如果初赛大于80分则进入决赛,否则提示淘汰,并且根据性别来选择进入男子组和女子组。*/
        // 输入成绩和性别,进行判断并打印信息。
        int singScore = 89;
        boolean singSex = false;    // false为女,true为男
        // 如果用键盘输入性别,则将boolean替换成char即可
        if (singScore >= 80) {
            System.out.println("恭喜您,成功进入决赛");
            if (singSex == false) {
                System.out.println("您将进入女子组");
            } else {
                System.out.println("您将进入男子组");
            }
        } else {
            System.out.println("很遗憾,你未能进入决赛!");
        }

        /* 打印1~100之间所有是9的倍数,统计个数和总和 */
        int count = 0; // 统计个数
        int sum = 0;
        for (i = 1; i <= 100; i++) {
            if (i % 9 == 0) {     // 判断是否为9的倍数
                count++;
                sum += i;
            }
        }
        System.out.println("1~100之间9的倍数的个数为:" + count + ",总和为:" + sum);

        /* 使用 while 语句打印1-100之间所有能被3整除的数 */
        i = 1;
        while (i <= 100) {
            if (i % 3 == 0) {
                System.out.print("\t" + i);
            }
            i++;    // 条件迭代
        }
        System.out.println();
        // 使用 while 语句打印40-200之间所有的偶数
        i = 1;
        while (i <= 200) {
            if (i % 2 == 0) {
                System.out.print("\t" + i);
            }
            i++;
        }
        System.out.println();

        // 使用 do..while 语句统计1-200之间能被5整除而不能被3整除的个数
        count = 0;
        i = 1;
        do {
            if (i % 5 == 0 && i % 3 != 0) {
                count++;
            }
            i++;
        } while (i <= 200);
        System.out.println("1-200之间能被5整除而不能被3整除的个数:" + count);

        /* 打印三角星星 */
        for(i = 1; i < 10; i++){
           for(j = 1; j <= (2 * i - 1); j++){
               System.out.print("*");
           }
           System.out.println();
        }
        /* 打印倒三角星星 */
        for(i = 10; i >= 1; i--){
            for(j = (2 * i - 1); j >= 1; j--){
                System.out.print("*");
            }
            System.out.println();
        }
    }
}
import java.util.Scanner;

public class ProcessControl_homework_two {
    public static void main(String[] args){

        /* 统计3个班级的成绩情况,每个班级有5人,求出各班级的平均分和所有班级的平均分 */
        // 统计三个班级的成绩合格人数。
        Scanner sr = new Scanner(System.in);
        int passCount = 0;  // 统计合格个数
        double scoreSum = 0;    // 所有班级的总分
        double scoreAver = 0;   // 统计所有班级的平均分
        int i, j, classNum = 3, stuNum = 5; // 班级和学生人数
        for(i = 1; i <= classNum; i++){
            double sum = 0;
            for(j = 1; j <= classNum; j++){
                System.out.println("请输入第"+i+"个班的第"+j+"个同学的成绩:");
                double score = sr.nextDouble();
                if(score > 60){    // 输入的score大于60分则使passCount计数+1
                    passCount++;
                }
                sum += score;   // 等价于 sum = sum+score; 班级总分
                System.out.println("成绩为:" + score);
            }
            System.out.println("sum = " + sum + "平均分 = " + (sum / stuNum));
            scoreSum += sum;    // 将班级总分赋值到所有班级总分的变量
            scoreAver = scoreSum / classNum;  // 所有班级平均分等于所有班级总分除以所有班级数
        }
        System.out.println("班级合格人数" + passCount);
        System.out.println("三个班级总分为:" + scoreSum + "\n平均分为:" + scoreAver);
    }
}
import java.util.Scanner;

public class ProcessControl_homework_three {
    public static void main(String[] args){

        /* for+break 实现登录验证,有3次机会,如果用户名为"丁真",密码为"666"则验证成功.否则提示还有几次机会 */
        Scanner sr = new Scanner(System.in);
        String userName = "";
        String passWord = "";
        int i, chance = 3;
        for(i = 1; i <= 3; i++){    // 循环执行,直到条件迭代不符合或者遇到break跳出;
            System.out.println("请输入您的用户名:");
            userName = sr.nextLine();
            System.out.println("请输入您的密码:");
            passWord = sr.nextLine();

            // 字符串的比较用.equals()方法
            if("丁真".equals(userName) && "666".equals(passWord)){
                System.out.println("登陆成功");
                break;
            }
            // 登录的机会减少
            chance--;
            System.out.println("您还有" + chance + "次机会");
        }
    }
}
package chap01;

public class ProcessControl_homework_four {
    public static void main(String[] args){
        RoadFree roadfree = new RoadFree();
        roadfree.show();
        DigitalRange digitalrange = new DigitalRange();
        digitalrange.show();
        ShuiXianhua shuixianhua = new ShuiXianhua();
        shuixianhua.show();
        PrintfNumber printfnumber = new PrintfNumber();
        printfnumber.show();
    }
}

class RoadFree{
    public void show(){
        /*
         某人有100000元,每经过一次路口则需要缴费
         缴费规则如下:
                  当现金 > 50000元时,需要缴5%
                  当现金 <= 50000元时,每次缴1000元
         该人可以过路口多少次?
        */
        double money = 100000;
        int count = 0;
        while(money > 0){
            if(money > 50000){
                money = money - (money * 0.05);
                count++;
                continue;
            }
            if(money <= 50000){
                money = money - 1000;
                count++;
            }
        }
        System.out.println("该人可以过路:" + count + "次");
    }
}

class DigitalRange{
    public void show(){
        // 实现判断一个整数,属于哪个范围,大于\小于\等于
        int numBer01 = 12;
        if(numBer01 > 0){
            System.out.println("大于0");
        }else if(numBer01 < 0){
            System.out.println("小于0");
        }else{
            System.out.println("等于0");
        }
    }
}

class ShuiXianhua{
    public void show(){
        // 判断一个整数是否为水仙花数. 水仙花数是指一个3位数,其个位数上立方和等于其本身
        // 例如: 153 = 1*1*1 + 3*3*3 + 5*5*5
        int num = 153;
        int n1 = num % 10;        // 个位数
        int n2 = (num / 10) % 10; // 十位数
        int n3 = num / 100;      // 百位数
        int result = n1*n1*n1 + n2*n2*n2 + n3*n3*n3;
        if(num == result){
            System.out.println(num + "是水仙花数");
        }else{
            System.out.println(num + "不是水仙花数");
        }
    }
}

class PrintfNumber{
    // 输出1-100之间不能被5整除的数
    public void show(){
        int i;
        for(i = 1; i <= 100; i++){
            if((i % 5) != 0){
                System.out.print(i + "\t");
            }
            if(i % 5 == 0){     // 5个换行
                System.out.println();
            }
        }
    }
}

常用类

public class CommonClass {
    public static void main(String[] args){
        /* 常用类 */
        System.out.println(Integer.MIN_VALUE);  // 返回最小值
        System.out.println(Integer.MAX_VALUE);  // 返回最大值
        System.out.println(Character.isDigit('a')); // 判断是不是数字
        System.out.println(Character.isLetter('a'));    // 判断是不是字母
        System.out.println(Character.isUpperCase('a')); // 判断是不是大写
        System.out.println(Character.isLowerCase('a'));     // 判断是不是小写
        System.out.println(Character.isWhitespace('a'));    // 判断是不是空格
        System.out.println(Character.toUpperCase('a')); // 转换成大写
        System.out.println(Character.toLowerCase('A')); // 转换成小写

        // 1. equals() 判断字符串是否相等
        String str1 = "hello";
        String str2 = "Hello";
        System.out.println(str1.equals(str2));
        // 2. equalsIgnoreCase() 忽略大小写的判断内容是否相等
        System.out.println(str1.equalsIgnoreCase(str2));
        // 3. length() 获取字符串的长度
        System.out.println(str1.length());
        // 4. indexOf() 获取字符在字符串对象中第一次出现的索引,索引从0开始,如果找不到则返回-1
        String str3 = "hello@@ooaa";
        System.out.println(str3.indexOf("@"));
        // 5. lastIndexOf() 获取字符在字符串对象中最后一次出现的索引
        System.out.println(str3.lastIndexOf("@"));
        // 6. substring() 截取指定范围的子串
        String name = "hello,张三";
        System.out.println(name.substring(6));

        // 1. toUpperCase() 转换成大写
        System.out.println(str1.toUpperCase());
        // 2. toLowerCase() 转换成小写
        // 3. concat() 拼接成字符串
        System.out.println(str1.concat(str2).concat(str3).concat(name));
        // 4. replace() 替换字符串的字符
        String name1 = name.replace("张三","李四"); // 把字符串里的张三替换成李四
        // 5. split() 分隔字符串
        // 6. toCharArray() 转换成字符数组
        // 7. compareTo() 比较两个字符串的大小,如果前者大则返回正数,否则返回负数,相等则返回0
    }
}

Math类

public class CommonClass_Math {
    public static void main(String[] args){
	// Math类即数学类,用于数学运算
        // 1 abs() 绝对值
        int num1 = Math.abs(-9);
        // 2 pow() 求幂
        double num2 = Math.pow(10,2);   // 10的2次方
        // 3 ceil() 向上取整,返回该参数的最小整数
        double num3 = Math.ceil(3.9);   // 4
        // 4 floor() 向下取整
        double num4 = Math.floor(2.2);  // 2
        // 5 round() 四舍五入(结果为该参数+0.5)
        long num5 = Math.round(5.51);   // 6
        // 6 sqrt() 求开方
        double num6 = Math.sqrt(9.0);
        // 7 random() 求随机数
        // random返回的是 0<=x<1 之间的一个随机小数
        // 获取a-b之间的随机整数,ab均为整数的公式为: (int)(a+Math.random()*(b-a+1))
    }
}

StringBuffer类

// 1 String保存的是常量,里面的值无法被修改,每次String类的更新实际上就是在修改地址,效率低
// 2 StringBuffer保存的是字符串变量,里面的值可以更改,每次StringBuffer的更新可以更新内容,不用修改地址,效率高
// 3 StringBuffer类是字符串类,用于处理字符串数据

public class CommonClass_StringBuffer {
    public static void main(String[] args){

        // String --> StringBuffer
        String str = "hello";
        // 方式1 使用构造器
        // 注意: 返回的才是stringBuffer对象,对str没有任何影响
        StringBuffer stringbuffer = new StringBuffer(str);
        // 方式2 使用 append 方法
        StringBuffer stringbuffer2 = new StringBuffer();
        stringbuffer2.append(str);

        // StringBuffer --> String
        // 方式1 使用StringBuffer提供的toString方法
        StringBuffer stringbuffer3 = new StringBuffer("狠狠赚一笔");
        String str2 = stringbuffer3.toString();
        // 方式2 使用构造器
        String str3 = new String(stringbuffer3);

        StringBuffer s = new StringBuffer("hello");
        // append 增加
        s.append(",");
        s.append("张三");
        System.out.println(s);

        // delete 删除
        s.delete(2,3);
        // replace 替换
        s.replace(2,3,"aa");
        // insert 插入
        s.insert(2,"aa");
        System.out.println(s);

        // 输入商品名称和商品价格并打印,价格的小数点前面每三位用","隔开再输出
        String price = "82133244.59";
        StringBuffer stringBuffer1 = new StringBuffer(price);
        for(int i = stringBuffer1.lastIndexOf(".") - 3; i > 0; i -= 3){
            stringBuffer1 = stringBuffer1.insert(i,",");
        }
        System.out.println(stringBuffer1);
    }
}

使用原则:

  1. 如果字符串存在大量的修改操作,一般使用StringBuffer或者StringBuilder
  2. 如果字符串存在大量的修改操作并且存在单线程情况,使用StringBuilder
  3. 如果字符串存在大量的修改操作并且存在多线程情况,使用StringBuffer
  4. 如果字符串很少修改,被多个对象引用,使用String

常用类案例

import java.util.Scanner;

public class CommonClass_homework_one {
    public static void main(String[] args){
        Scanner sr = new Scanner(System.in);
        System.out.println("请输入字符串:");
        String str = sr.nextLine(); // next()针对不带空格的字符串,nextLine()可以有空格
        CCforWordCount count = new CCforWordCount(str);
        count.count();
    }
}

/* 统计输入的参数有多少个单词(大小写字母\数字\空格) */
class CCforWordCount{
    private String str;
    public CCforWordCount(String str) {
        this.str = str;
    }
    public void setStr(String str) {
        this.str = str;
    }
    private int digitCount;
    private int spaceCount;
    private int upperCount;
    private int lowerCount;
    public void count(){
        for(int i=0; i < str.length(); i++){
            // 判断是否字母
            if(Character.isLetter(str.charAt(i))){  // charAt(): 字符串首字符
                // 判断是否为大写
                if(Character.isUpperCase(str.charAt(i))){
                    upperCount++;
                }
                // 判断是否为小写
                if(Character.isLowerCase(str.charAt(i))){
                    lowerCount++;
                }
            }
            // 判断是否数字
            if(Character.isDigit(str.charAt(i))){
                digitCount++;
            }
            // 判断是否空格
            if(Character.isWhitespace(str.charAt(i))){
                spaceCount++;
            }
        }
        System.out.println("大写字母有" + upperCount +
                "个,小写字母有" + lowerCount +
                "个,数字有" + digitCount +
                "个,空格有" + spaceCount +
                "个,");
    }
}

数组

数组注意事项:

  1. 数组是多个相同数据类型的组合,实现对这些数据的统一管理
  2. 数组中的元素可以是任意数据类型,但不能混用
  3. 数组创建后,如果没有赋值,则数据类型有默认值,例如 int为0, double为0.0, boolean为false等.
  4. 数组的下标必须在指定范围内使用,否则会出现越界等报错信息.
// 一维数组的定义: 数据类型[] 数组名 = new 数据类型[数组长度];
// 一维数组的引用: 数组名[下标]; 下标从0开始,例如你要找第2个数组元素,则定义数组名[1];
double[] arrayOne = {3, 5, 3.4, 5, 4};
System.out.println(arrayOne.length);    // 可以通过数组名.length获取数组长度

int[] IntArray = new int[5]; // 定义了长度为5的数组,则有效下标为0-4;

// 定义了String类型的数组,则元素只能是String类型
String[] StringArray = {"a", "b", "c", "d", "e"};   

// 数组赋值机制: 在默认情况下数组是引用传递,赋的值是地址.

/*  二维数组
    语法: 数据类型[][] 数组名 = new 数据类型[列][行]; 
    例如 int[][] Arr = new int[2][3]; */

/*
        ArrayAll array01 = new ArrayAll();
        array01.show();
        arrayMaxMax arrayone = new arrayMaxMax();
        arrayone.show();
        arrayTwo arraytwo = new arrayTwo();
        arraytwo.show();
        arrayThree arraythree = new arrayThree();
        arraythree.show();
        arrayCopyCopy arrayfour = new arrayCopyCopy();
        arrayfour.show();
        arrayRe arrayfive = new arrayRe();
        arrayfive.show();
        arraySix arraysix = new arraySix();
        arraysix.show();
        arraySeven arrayseven = new arraySeven();
        arrayseven.show();
*/
ArrayEight arrayeight = new ArrayEight();
arrayeight.show();

class ArrayAll{
    public void show(){
        Scanner sr = new Scanner(System.in);
        // 数组遍历 输入和输出
        int[][] array01 = new int[2][3];
        for(int i = 0; i < array01.length; i++){
            for(int j = 0; j < array01[i].length; j++){     // 对每个一维数组遍历
                System.out.println("请输入第" + (i+1) + "行,第" + (j+1) + "列元素:" );
                array01[i][j] = sr.nextInt();
            }
        }
        for(int i = 0; i < array01.length; i++) {
            for (int j = 0; j < array01[i].length; j++) {
                System.out.print(array01[i][j] + "\t");
            }
            System.out.println();
        }
    }
}

class arrayMax {
    public void show() {
        // 求出数组中的最大值,并得到下标.
        int[] intArray01 = {90, 89, 56, 99, 56};
        int max = intArray01[0], maxIndex = 0;  // 先定义max假设最大值为下标0
        int i;
        for (i = 0; i < intArray01.length; i++) {
            if (intArray01[i] > max) {    // 再进行当前下标与定义的max比较
                max = intArray01[i];
                maxIndex = i;
            }
        }
        System.out.println("max:" + max + ",maxIndex:" + maxIndex);
    }
}

class arrayTwo{
    public void show(){
        // 创建char类型的数组分别放置"A-Z",并循环输出
        char[] charArray = new char[26];
        int i;
        for (i = 0; i < charArray.length; i++) {
            charArray[i] = (char) ('A' + i);   // 'A'+1 是int类型,故需要强制转换char
        }
        for (i = 0; i < charArray.length; i++) {
            System.out.print(charArray[i] + "\t");
        }
        System.out.println();
    }
}

class arrayThree{
    public void show(){
        Scanner sr = new Scanner(System.in);    // 键盘输入
        // 循环输入5个成绩,保存到double数组
        int i;
        double[] arrayScore = new double[5];
        for (i = 0; i < arrayScore.length; i++) {     // 循环输入数据保存到数组中
            System.out.print("第" + (i + 1) + "位成绩:");
            arrayScore[i] = sr.nextDouble();
        }
        for (i = 0; i < arrayScore.length; i++) {     // 循环i下标输出数组中的数据
            System.out.print("第" + (i + 1) + "位成绩:");
            System.out.println(arrayScore[i]);
        }
    }
}

class arrayCopy {
    public void show(){
        // 数组拷贝
        int[] array01 = {1,2,3,4,5};
        int[] array02 = new int[5];
        int i;
        for(i = 0; i < array01.length; i++){
            array02[i] = array01[i];    // 将数组1的元素通过循环下标i赋值给数组2实现数组的拷贝
        }
        for(i = 0; i < array02.length; i++){
            System.out.print(array02[i] + "\t");
        }
        System.out.println();
    }
}

class arrayRe {
    public void show(){
        // 数组反转
        int[] array01 = {1,2,3,4,5};
        int i, temp = 0, len = array01.length;
        for(i = 0; i < len / 2; i++){    // 共交换3次,则 len / 2
            temp = array01[len - 1 - i];    // 利用临时变量去存储元素
            array01[len - 1 - i] = array01[i];
            array01[i] = temp;
        }
        System.out.println("反转后的数组:");
        for(i = 0; i < len; i++){
            System.out.print(array01[i] + "\t");
        }
        System.out.println();

        // 写法2, 利用逆序情况实现反转
        int j;
        int[] array02 = new int[array01.length];
        for(i = len - 1, j = 0; i >= 0; i--, j++){
            array02[j] = array01[i];
        }
        for(i = 0; i < len; i++){
            System.out.print(array01[i] + "\t");
        }
        System.out.println();
    }
}

class arraySix{
    public void show(){
        /*
                要求: 实现动态的给数组元素添加元素效果,实现对数组扩容.
                1. 原始数组使用静态分配 int[] arr = {1,2,3,};
                2. 增加元素4,直接放在数组的最后 arr = {1,2,3,4};
                3. 用户可以通过 y/n 来决定是否继续;
        */
        Scanner sr = new Scanner(System.in);
        int[] array = {1,2,3};
        do{
            int[] arrayNew = new int[array.length + 1]; // 定义新的数组(长度+1)
            for(int i = 0; i < array.length; i++){
                arrayNew[i] = array[i];         // 循环将array的元素拷贝给arrayNew
            }
            System.out.println("请输入您要添加的元素:");
            int addNum = sr.nextInt();
            arrayNew[arrayNew.length - 1] = addNum;
            array = arrayNew;    // 将array指向arrayNew
            System.out.println("扩容后的数组:");
            for(int i = 0; i < array.length; i++){
                System.out.print(array[i] + "\t");
            }
            System.out.println();
            // 询问用户是否继续
            System.out.println("请问是否继续添加?y/n");
            char key = sr.next().charAt(0);
            if(key == 'n'){     // 输入n则结束
                break;
            }
        }while(true);
        System.out.println("您退出了添加!");
    }
}

class arraySeven{
    public void show(){
        /*  有一个数组{1,2,3,4,5}可以将该数组进行删减,提示用户是否继续删减,每次删减最后那个元素.
            当只剩下最后一个元素时提示无法再继续删减,退出程序. */
        int[] array = {1,2,3,4,5};
        do{
            int[] arrayNew = new int[array.length - 1];
            for(int i = 0; i < arrayNew.length; i++){
                arrayNew[i] = array[i]; // 将array拷贝给arrayNew
            }
            array = arrayNew;
            System.out.println("删减后的数组:");
            for(int i = 0; i < array.length; i++){
                System.out.print(array[i] + "\t");
            }
            System.out.println();
            System.out.println("是否继续删减?y/n");

            Scanner sr = new Scanner(System.in);
            char n = sr.next().charAt(0);
            if(n == 'n'){
                break;
            }
            if(array.length == 1){
                System.out.println("无法再删减!");
                break;
            }
        }while(true);
        System.out.println("您已经退出!");
    }
}

class ArrayEight{
    public void show(){
        // 二维数组动态初始化
        int[][] array = new int[3][];
        for(int i = 0; i < array.length; i++){
            // 给每个一维数组开空间,如果没有new,那么这个数组就是null
            array[i] = new int[i+1];
            for(int j = 0; j < array[i].length; j++){
                array[i][j] = i + 1; // 赋值
            }
        }
        for(int i = 0; i < array.length; i++){
            for(int j = 0; j < array[i].length; j++){
                System.out.print(array[i][j]);
            }
            System.out.println();
        }
        // 1
        // 22
        // 333
    }
}

数组排序

package chap01;
import java.util.Scanner;
public class ArraySort {
    public static void main(String[] args){

        // 排序: 指将多个数据根据指定的顺序进行排列的过程
        /* 排序的分类:
            1. 外部排序\内部排序
            2. 冒泡排序:
                通过对待排序序列从后向前(从下标较大的元素开始),依次比较相邻元素的值,
                若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。
        */

        /*ArrayMaopao arraymaopao = new ArrayMaopao();
        arraymaopao.show();*/
        ArraySeek arrayseek = new ArraySeek();
        arrayseek.show();
    }
}

// 排序
class ArrayMaopao{  // 冒泡排序
    public void show(){
        // 我们将五个无序:24,69,80,57,13 使用冒泡排序法将其排成一个从小到大的有序数列。
        int[] array = {24,69,80,57,13};
        int temp = 0;
        for(int i = 0; i < array.length; i++) {
            for (int j = 0; j < array.length - 1 - i; j++) {
                if (array[j] > array[j + 1]) {
                    temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
            }
            // 第2次比较
            for(int j = 0; j < 4; j++) {
                if(array[j] > array[j+1]){
                    temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                }
            }
            for(int j = 0; j < 3; j++){
                if(array[j] > array[j+1]){
                    temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                }
            }
            for(int j = 0; j < 2; j++){
                if(array[j] > array[j+1]){
                    temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                }
            }
            for(int j = 0; j < 1; j++){
                if(array[j] > array[j+1]){
                    temp = array[j];
                    array[j] = array[j+1];
                    array[j+i] = temp;
                }
            }
        }

        System.out.println("排序后的数组:");
        for(int i = 0; i < array.length; i++){
            System.out.print(array[i] + "\t");
        }
        System.out.println();
    }
}

// 查找
class ArraySeek{
    public void show(){
        /*
           有一个数列:白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王猜数游戏:
           从键盘中任意输入一个名称,判断数列中是否包含此名称【顺序查找】
           要求: 如果找到了,就提示找到,并给出下标值
         */
        System.out.println("请输入您要找的名字:");
        String names[] = {"顾九思","柳玉茹","周烨","秦婉之","叶世安","沈明","叶韵"};
        Scanner sr = new Scanner(System.in);
        String findNames = sr.next();
        int index = 1;
        for(int i = 0; i < names.length; i++){
            if(findNames.equals(names[i])){
                System.out.println("恭喜您找到了!");
                System.out.println("下标为:" + i);
                break;
            }else{
                index = -1;
            }
        }
        if(index == -1){
            System.out.println("很抱歉,未找到!");
        }
    }
}
数组排序案例
package chap01;
import java.util.Arrays;
import java.util.Comparator;
public class ArraySort_homework_one {
    public static void main(String[] args){
        ArraySortBooks[] books = new ArraySortBooks[4];
        books[0] = new ArraySortBooks("红楼梦",100);
        books[1] = new ArraySortBooks("三国演义",90);
        books[2] = new ArraySortBooks("水浒传",98);
        books[3] = new ArraySortBooks("西游记",80);

        Arrays.sort(books,new Comparator(){     // 定制排序
            @Override
            public int compare(Object o1, Object o2) {
                // price 从大到小
                ArraySortBooks book1 = (ArraySortBooks)o1;
                ArraySortBooks book2 = (ArraySortBooks)o2;
                int priceVel = book2.getPrice() - book1.getPrice();
                return priceVel;
            }
        });
        /*
        Arrays.sort(books,new Comparator(){
            @Override
            //  按照书名长度进行排序
            public int compare(Object o1, Object o2) {
                ArraySortBooks book1 = (ArraySortBooks)o1;
                ArraySortBooks book2 = (ArraySortBooks)o2;
                return book2.getName().length() - book1.getName().length();
            }
        });
         */
        System.out.println(Arrays.toString(books));
    }
}
class ArraySortBooks{
    private String name;
    private int price;

    public ArraySortBooks(String name, int price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getPrice() {
        return price;
    }
    public void setPrice(int price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return name + price ;
    }
}

面向对象(OOP)

public class OOP_main {

    // 静态的变量/属性
    private static String name = "Roy";
    // 非静态的属性
    private int n1 = 1000;

    // static 静态方法
    public static void Hi(){
        System.out.println("静态方法");
    }
    // 非静态方法
    public void Cry(){
        System.out.println("非静态方法");
    }

    public static void main(String[] args){
        // 可以直接使用name
        // 1. 静态方法main可以访问本类的静态成员
        System.out.println("name = " + name);
        Hi();
        // 2. 静态方法main不可以访问本类的非静态成员,必须创建对象再调用
        // cay(); // 错误
        // System.out.println("n1 = " + n1);    // 错误
        OOP_main oop_main = new OOP_main();
        oop_main.Cry();
        System.out.println("n1 = " + oop_main.n1);
    }
}

/*
    代码块:
        [修饰符]{
             ..
        }
    修饰符可选,但只能是static;
    代码块分为两类,static静态代码块和普通代码块;
    逻辑语句可以是任何逻辑语句(输入输出\方法调用\循环)
*/

// 代码块相当于是另一种形式的构造器(对构造器的补充机制),可以做初始化的操作

/*
    1. static代码块也叫静态代码块,作用就是对类初始化,
       而且它随类的加载而执行,并且只执行一次,如果是普通代码块则每创建一个对象就会执行.
    2. 类什么时候被加载?
        1) 创建对象实例时 (new)
        2) 创建子类对象实例,父类也会被加载
        3) 使用类的静态成员时(静态属性,静态方法)
*/

方法

import java.util.Scanner;
public class OOP_object {
    public static void main(String[] args){
        
       /*  OOP(面向对象) 方法使用
           1. 方法写好后,如果不去调用(使用)则不会输出
           2. 先创建对象,然后调用方法即可. */
        Cats cats = new Cats(); // 创建实例对象 (创建好之后才能调用它)
        cats.show();    //  实例对象调用语法: 对象名.方法名; 静态(带有static)对象调用: 类名.方法名;
        GetSum getsum = new GetSum();
        getsum.show();

        // 调用构造器
        Person person = new Person("Roy",22);
    }
}

/*  方法的定义:
    class [访问限定符] 类名{
        [访问限定符] [返回值类型] [] 方法名(形参列表){
            // 成员方法体
        }
    } */
// 成员方法的好处就是提高代码复用率,实现代码细节封装.
// 方法的命名规则: 首字母应小写

class Cats{
    public void show(){
        /*
        有人养了两只猫猫:一只名字叫小白,今年 3 岁,白色。还有一只叫小花,今年 8 岁,花色。
        请编写一个程序,当用户输入小猫的名字时,就显示该猫的名字,年龄,颜色。
        如果用户输入的小猫名错误,则显示没有这只猫猫。
        */
        /*
        // 单独用变量 -> 不利于数据的管理
        String catName = "小白";
        int catAge = 3;
        String catColor01 = "白色";
        String catName02 = "小花";
        int catAge02 = 8;
        String catColor02 = "花色";
        // 数组 -> 数据类型不能体现,只能通过下标来获取信息,不能体现猫的行为
        String[] cat01 = {"小白","3岁","白色"};
        String[] cat02 = {"小花","8岁","花色"};

        /* 使用面向对象的方法来解决某类事件 */
        // 属性/成员变量
        // 属性的定义同变量: 访问修饰符 属性的数据类型 属性名;
        String catName1 = "小白";
        int catAge1 = 3;
        String catColor1 = "白色";
        String catName2 = "小花";
        int catAge2 = 8;
        String catColor2 = "花色";
        // 行为
        System.out.println("第一只猫的信息:");
        System.out.println("姓名:" + catName1 + ",年龄:" + catAge1 + ",颜色:" + catColor1);
        System.out.println("第二只猫的信息:");
        System.out.println("姓名:" + catName2 + ",年龄:" + catAge2 + ",颜色:" + catColor2);
    }
}

// 添加getsum成员方法,可以计算两个数之和
class GetSum{
    public void show(){
        Scanner sr = new Scanner(System.in);
        System.out.println("请输入两个数值:");
        int num1,num2;
        num1 = sr.nextInt();
        num2 = sr.nextInt();
        int sum = num1 + num2;
        System.out.println("两数之和为:" + sum);
    }
}

/*  构造器和成员方法的区别:
    1. 构造器完成对象的初始化,没有返回值(没有void)
    2. 成员方法是某个事件的具体操作,有返回值也可以void.
    */

/*  构造方法(构造器),是类的一种特殊方法,主要作用是完成对新对象的初始化.
    1. 方法名和类名相同
    2. 没有返回值
    3. 在创建对象时,系统会自动的调用该类的构造器完成对象的初始化
*/
class Person{
    String name;
    int age;
    // 构造器没有返回类型,void也没有
    // 构造器是完成对象的初始化,并不是创建对象.
    public Person(String name, int age){    // 1. 带有参数的构造器
        this.name = name;
        this.age = age;
        System.out.println("姓名:" + name + ",年龄:" + age);
    }
    public Person(){    // 2. 无参构造器
        age = 18;   // 利用构造器设置所有人的age初始值都为18
    }
}
/* this注意事项
   1. this关键字可以用来访问本类的属性、方法、构造器
   2. this用于区分当前类的属性和局部变量
   3. 访问成员方法的语法: this.方法名(参数列表)
   4. 访问构造器的语法: this(参数列表) 只能在构造器中使用(即在构造器中访问另一个构造器,且放在第一条语句)
   5. this不能在类定义的外部使用, 只能在类定义的方法中使用 */
class oopFour{
    String name;
    int age;
    public oopFour(String name,int age){
        // Java虚拟机给每个对象分配了this,代表当前对象
        // 构造器的name不是属性,是局部变量
        // 这个是用使用this就可以直接引用当前对象的属性
        this.name = name;   // 当前对象属性的name
        this.age = age;
        System.out.println("姓名:" + name + ",年龄:" + age);
    }
}

/*  == 和 equal()方法
    1. == 是一个比较运算符,既可以判断基本类型,也可以判断引用类型
    2. == 判断基本类型, 判断的是值是否相等
    3. == 判断引用类型, 判断的是地址是否相等
    4. equal(), 是Object类的方法,只能判断引用类型
    5. 默认的是判断地址是否相等,子类中往往重写该方法,用于判断内容是否相等 */
class EqualOne{
    public void show(){
        String str1 = "abc";
        String str2 = "qwe";
        if(str1.equals(str2)){
            System.out.println("相等");
        }else{
            System.out.println("不相等");
        }
    }
}

方法案例

import java.util.Scanner;
public class OOP_object_homework_one {
    public static void main(String[] args){
        /*
        oopOne oopone = new oopOne();
        oopone.show();
        oopTwo ooptwo = new oopTwo();
        ooptwo.show();
        */
        oopThree oopthree = new oopThree("Roy",22);
        oopthree.show();
    }
}

// 判断一个数是奇数 odd 还是偶数
class oopOne{
    public void show(){
        System.out.println("请输入一个数判断:");
        Scanner sr = new Scanner(System.in);
        int num1;
        num1 = sr.nextInt();
        if( num1 % 2 == 0){
            System.out.println( num1 + "为偶数" );
        }else{
            System.out.println(num1 + "是奇数");
        }
    }
}

// 根据行、列、字符打印 对应行数和列数的字符,比如:行:4,列:4,字符#,则打印相应的效果
class oopTwo{
    public void show(){
        Scanner sr = new Scanner(System.in);
        int i, j, a, b;
        System.out.println("请输入行数:");
        a = sr.nextInt();
        System.out.println("请输入列数:");
        b = sr.nextInt();
        for(i = 0; i < a; i++){
            for(j = 0; j < b; j++){
                System.out.print("*");
            }
            System.out.println();
        }
    }
}

class oopThree{
    String name;
    int age;
    // 成员方法
    public void show(){
        System.out.println("姓名:" + name + ",年龄:" + age);
    }
    // 构造器
    public oopThree(String name,int age){
        this.name = name;
        this.age = age;
    }
}
import java.util.Scanner;
public class OOP_object_homework_two {
    public static void main(String[] args){
        /*
        Array01 array01 = new Array01();
        array01.doubleMax();
        Array02 array02 = new Array02();
        array02.stringAt();
        Array03 array03 = new Array03();
        array03.arrCopy();
        Book book = new Book();
        book.updatePrice();
        */
        Calculate calculate = new Calculate();
        calculate.plus();
        calculate.minus();
        calculate.multiply();
        calculate.divide();
    }
}

class Array01{
    // 实现找到double数组的最大值
    public void doubleMax(){
        double[] Arr= {21,34,100,77,23};
        double max = 0, temp = 0;
        for(int i = 0; i < Arr.length; i++){
            if(Arr[i] > max){
                max = Arr[i];
            }
        }
        System.out.println("max为:" + max);
    }
}
class Array03{
    // 实现数组的拷贝, 输入旧数组返回一个新的数组A(元素和旧数组一样)
    public void arrCopy(){
        Scanner sr = new Scanner(System.in);
        System.out.println("请输入数组长度:");
        int size = sr.nextInt();
        int[] arr = new int[size];
        System.out.println("请输入数组元素");
        for(int i = 0; i < size; i++){
            arr[i] = sr.nextInt();
        }
        System.out.println("数组元素:");
        for(int i = 0; i < arr.length; i++){
            System.out.print(arr[i] + "\t");
        }
        System.out.println();
    }
}
class Book{
    public void updatePrice(){
        Scanner sr = new Scanner(System.in);
        System.out.println("请输入价格:");
        int price = sr.nextInt();
        if(price > 150){
            price = 150;
        }else if(price > 100){
            price = 100;
        }
        System.out.println("价格为:" + price);
    }
}
class Calculate{
    Scanner sr = new Scanner(System.in);
    double num1 = sr.nextDouble();
    double num2 = sr.nextDouble();
    public void plus(){
        System.out.println("result:" + (num1 + num2));
    }
    public void minus(){
        System.out.println("result:" + (num1 - num2));
    }
    public void divide(){
        if(num1 == 0 || num2 == 0 ){
            System.out.println("除数为0,错误");
        }else {
            System.out.println("result:" + (num1 / num2));
        }
    }
    public void multiply(){
        System.out.println("result:" + (num1 * num2));
    }
}
public class OOP_object_homework_three {
    public static void main(String[] args){
        // 创建3个person对象,初始化person数组,并按年龄大小进行排序(使用冒泡排序)

        PersonMaopao[] person = new PersonMaopao[3];
        person[0] = new PersonMaopao("Roy",22,"后端");
        person[1] = new PersonMaopao("Tom",20,"测试");
        person[2] = new PersonMaopao("Judy",28,"前端");

        PersonMaopao temp = null;
        for(int i = 0; i < person.length - 1; i++){
            for(int j = 0; j < person.length -1 -i; j++){
                if(person[j + 1].getAge() > person[j].getAge()){
                    temp = person[j];
                    person[j] = person[j + 1];
                    person[j + 1] = temp;
                }
            }
        }
        System.out.println("年龄从小到大排序后数组:");
        for(int i = 0; i < person.length; i++){
            System.out.println(person[i].show());
        }
        System.out.println();
    }
}

class PersonMaopao{
    private String name;
    private int age;
    private String job;

    public PersonMaopao(String name, int age, String job) {
        this.name = name;
        this.age = age;
        this.job = job;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getJob() {
        return job;
    }
    public void setJob(String job) {
        this.job = job;
    }

    public String show(){
        return "name = " + name + ",age = " + age + ",job = " + job;
    }
}
public class OOP_object_homework_four {
    public static void main(String[] args){
        /*
            1. 编写教师类要求有属性: name,age,职称post,基本工资salary
            2. 编写方法,intrduce(),实现输出一个教师的信息
            3. 编写教师类的三个子类,教授类(Profesor),副教授类,讲师类,工资职级为 1.3 \ 1.2 \ 1.1
               在三个子类中都重写intrduce()方法.
            4. 定义并初始化一个老师对象,调用业务方法,实现对象基本信息的后台打印
        */
        TeacherMessage teacher = new TeacherMessage("Roy",28,"副教授",6000);
        System.out.println(teacher.intrduce());
        Profesor profesor = new Profesor("Tom",48,"教授",9000);
        System.out.println(profesor.intrduce());
    }
}

class TeacherMessage{
    private String name;
    private int age;
    private String post;    // 职称
    private double salary;  // 基本工资

    public TeacherMessage(String name, int age, String post, double salary) {
        this.name = name;
        this.age = age;
        this.post = post;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getPost() {
        return post;
    }
    public void setPost(String post) {
        this.post = post;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }

    public String intrduce(){
        return name + " " + age + " " + post + " " + salary;
    }
}

// 老师子类 教授类
class Profesor extends TeacherMessage{
    private double salaryZ = 1.3;
    public Profesor(String name, int age, String post, double salary) {
        super(name, age, post, salary);
    }
    public String intrduce(){
        return super.intrduce() + "教授工资级别为" + salaryZ;
    }
}
// 老师子类 副教授类
class AssociateProfesor extends TeacherMessage{
    private double salaryZ = 1.2;
    public AssociateProfesor(String name, int age, String post, double salary) {
        super(name, age, post, salary);
    }
    public String intrduce(){
        return super.intrduce() + "副教授工资级别为" + salaryZ;
    }
}
// 老师子类 讲师类
class lecturer extends TeacherMessage{
    private double salaryZ = 1.1;
    public lecturer(String name, int age, String post, double salary) {
        super(name, age, post, salary);
    }
    public String intrduce(){
        return super.intrduce() + "讲师工资级别为" + salaryZ;
    }
}

/*
    父类: 员工类(Employee)
    子类: 部门经理类(Manager)\普通员工类(Worker)
    1. 部门经理工资 = 1000 + 单日工资*天数*等级(1.2)  => 奖金+基本工资
    2. 普通员工工资 = 单日工资*天数*等级(1.0)  => 基本工资
    3. 员工属性: 姓名,单日工资,工作天数
    4. 员工方法(打印工资)
    5. 普通员工及部门经理都是员工子类,需要重写打印工资方法
    6. 定义并初始化普通员工对象,调用打印工资方法输出工资,定义并初始化部门经理对象,调用打印工资方法输出工资
*/

public class OOP_object_homework_five {
    public static void main(String[] args){

        // 定义并初始化对象
        Manager manager = new Manager("Roy",400,27);
        System.out.println(manager.Info());
        Worker worker = new Worker("Tom",200,29);
        System.out.println(worker.Info());
    }
}
// 父类: 员工类
class Employee{
    private String name;
    private double salary;  // 单日工资
    private int workdays;   // 工作天数

    public Employee(String name, double salary, int workdays) {
        this.name = name;
        this.salary = salary;
        this.workdays = workdays;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
    public int getWorkdays() {
        return workdays;
    }
    public void setWorkdays(int workdays) {
        this.workdays = workdays;
    }

    public String Info(){
        return " " + name;
    }
}
// 子类: 经理类
class Manager extends Employee{
    public Manager(String name, double salary, int workdays) {
        super(name, salary, workdays);
    }
    private double salaryZ = 1.2;
    private double mSalary = 1000 + super.getSalary() * super.getWorkdays() * salaryZ;

    public String Info(){
        return super.Info() + ",你是经理,工资为" + mSalary ;
    }
}
class Worker extends Employee{
    public Worker(String name, double salary, int workdays) {
        super(name, salary, workdays);
    }
    private double salaryZ = 1;
    private double mSalary = super.getSalary() * super.getWorkdays() * salaryZ;

    public String Info(){
        return super.Info() + ",你是普通员工,工资为:" + mSalary ;
    }
}
public class OOP_object_homework_six {
    public static void main(String[] args) {
        BankAccount bankaccount = new BankAccount(89);
        bankaccount.withdraw(200);
        bankaccount.deposit(100);
        System.out.println("账户余额:" + bankaccount.getBalance() + "$");   // 获取余额
    }
}
class BankAccount {
    private double balance;
    private String sum;
    // 构造器
    public BankAccount(double initiaBalance){
        this.balance = initiaBalance;
    }
    // 存款
    public void deposit(double amount){
        balance += amount;
        System.out.println("您存了" + amount + "$");
    }
    // 取款
    public void withdraw(double amount){
        if(balance >= amount){
            balance -= amount;
            System.out.println("您取了" + amount + "$");
        }else{
            System.out.println("账户余额不足!");
        }
    }
    // set & get
    public double getBalance() {
        return balance;
    }
    public void setBalance(double balance) {
        this.balance = balance;
    }
}
// 要求在上面类的基础上扩展新类 CheckingAccount 对每次存取收1美元手续费
public class OOP_object_homework_seven {
    public static void main(String[] args){
        StudentSeven student = new StudentSeven("Roy","男",22,"07201030");
        System.out.println(student.info());
        TeacherSeven teacher = new TeacherSeven("Tom","男",48,12);
        System.out.println(teacher.info());
    }
}
class PersonSeven{
    private String name;
    private String sex;
    private int age;

    public PersonSeven(String name, String sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    public String info(){
        return "姓名:" + name + "\n" + "性别:" + sex + "\n" + "年龄:" + age + "\n";
    }
    public String study(){
        return "我承诺,我会好好学习。";
    }
    public String teach(){
        return "我承诺,我会认真教学。";
    }
}
class StudentSeven extends PersonSeven{
    private String stu_id;
    // Student类 做合理封装,通过构造器在创建对象时将4个属性赋值
    public StudentSeven(String name, String sex, int age, String stu_id) {
        super(name, sex, age);
        this.stu_id = stu_id;
    }

    // 打印学生信息
    public String info(){
        return "学生的信息:\n" + super.info() + "学号:" + stu_id + "\n" + super.study() + "\n";
    }
}
class TeacherSeven extends PersonSeven{
    private int work_age;
    public TeacherSeven(String name, String sex, int age, int work_age) {
        super(name, sex, age);
        this.work_age = work_age;
    }

    public String info(){
        return "老师的信息:\n" + super.info() + "工龄:" + work_age + "\n" + super.teach() + "\n";
    }
}

抽象方法

public class OOP_abstract {
    public static void main(String[] args){
        // new AbstractOne(); // 抽象类不能被实例化
    }
}
// 当父类的某些方法需要声明,但是又不确定如何实现时,可以将其声明为抽象方法,那么这个类就是抽象类.
// 用abstract关键字来修饰一个类时,这个类就叫抽象类 => " 访问权限符 abstract 类名{} "
abstract class AbstractOne{
    private String name;

    public AbstractOne(String name) {
        this.name = name;
    }

    // 所谓抽象方法就是没有实现的方法,所谓没有实现指的就是没有方法体
    // 用abstract修饰一个方法时,这个方法就是抽象方法
    // => " 访问权限符 abstract 返回类型 方法名(参数列表); " 没有方法体.
    public abstract void eat();
    // 一旦类包含了abstract方法,则这个类就必须声明为abstract
}

// 抽象类不一定要包含abstract方法. 也就是说抽象类可以没有abstract方法,还可以有实现的方法
abstract class AbstractTwo{
    public void hi(){
        System.out.println("hi");
    }
    // abstract 只能修饰类和方法 不能修饰其他
    // public abstract int n1 = 100;
}

// 抽象类的最佳实践 - 模板设计模式
/*  模板设计模式能解决的问题
1) 当功能内部一部分实现是确定,一部分实现是不确定的. 这时就可以把不确定的部分给暴露出去让子类实现
2) 编写一个抽象子类,父类提供了多个子类的通用方法,并把一个或多个方法留给其他子类实现 */

抽象方法案例

/*
   抽象类的使用
   1 动物类AbstractAnimal01包含了抽象方法 shout();
   2 AbstractCat01 继承了 AbstractAnimal01 的抽象方法shout() 打印"猫会喵喵叫"
   3 AbstractDog01 继承了 AbstractAnimal01 的抽象方法shout() 打印"狗会汪汪叫"
   4 在main方法中实例化对象AbstractAnimal01 cat = new AbstractCat01();
   5 在main方法中实例化对象AbstractAnimal01 dog = new AbstractDog01();
*/

public class OOP_abstract_homework_two {
    public static void main(String[] args){
        AbstractAnimal01 cat = new AbstractCat01();
        AbstractAnimal01 dog = new AbstractDog01();
        cat.shout();
        dog.shout();
    }
}
abstract class AbstractAnimal01{
    public abstract void shout();
}
class AbstractCat01 extends AbstractAnimal01{
    @Override
    public void shout() {
        System.out.println("猫会喵喵叫");
    }
}
class AbstractDog01 extends AbstractAnimal01{
    @Override
    public void shout() {
        System.out.println("狗会汪汪叫");
    }
}
public class OOP_abstract_homework_one {   // 抽象类 - 模板设计模式
    public static void main(String[] args){
        AbstractAA aa = new AbstractAA();
        aa.calculateTime();
        AbstractBB bb = new AbstractBB();
        bb.calculateTime();
    }
}

abstract class abstract01{
    public abstract void job();

    public void calculateTime(){    // 实现方法,调用job方法
        // 得到开始的时间
        long start = System.currentTimeMillis();
        job();  // 动态绑定时间
        // 得到结束的时间
        long end = System.currentTimeMillis();
        System.out.println("任务执行时间 " + (end - start));
    }
}
class AbstractAA extends abstract01{
    // 1+...+800000;
    @Override
    public void job() {
        long num = 0;
        for(int i = 1; i <= 800000; i++){
            num += i;
        }
    }
}
class AbstractBB extends abstract01{
    @Override
    public void job() {
        long num = 0;
        for(int i = 1; i <= 800000; i++){   // 重写了abstract01的job方法
            num *= i;
        }
    }
}

类变量

/*
    类变量也叫静态变量/静态属性,是该类中所有对象共享的属性,任何一个类去访问它时,取到的都是同一个值,修改时也是同一个值
    语法格式: 访问修饰符 static 数据类型 变量名;
    类变量访问: 类名.类变量名 或者 对象.类变量名

    什么时候使用类变量?
        当我们需要让某个类的所有对象都共享一个变量时,就可以考虑使用类变量; 比如一个学生类,统计学生共交多少钱.
    类变量与实例变量的区别?
        1. 类变量是该类所有对象共享的,实例变量是每个对象独享的
        2. 加上static修饰的即为静态变量或类变量,否则称为实例变量/普通变量/非静态变量
        3. 实例变量不能通过 类名.类变量名 访问
        4. 类变量在类加载时就初始化了,也就是说,即使你没有创建对象,只要类加载了就可以使用类变量
        5. 类变量的生命周期随着类的加载开始,随着类消亡而销毁
*/

public class OOP_class {
    public static void main(String[] args) {
        int count = 0;
        Child child1 = new Child("John");    // 创建对象, 调用
        child1.join();
        child1.count++;
        Child child2 = new Child("Roy");
        child2.join();
        child2.count++;
        Child child3 = new Child("Kim");
        child3.join();
        child3.count++;

        // 类变量可以通过类名访问
        System.out.println("共有" + Child.count + "个小孩加入了游戏");

        ClassOne classone = new ClassOne("Roy");
        ClassOne.payFee(200);   // 类方法正确访问 "类名.类方法名"
        // clasone.payFee(200); // 类方法错误访问
        ClassOne.feeInfo();
    }
}

// 有一群小孩在玩堆雪人,不时有新的小孩加入,请问如何知道现在共有多少人?
// 传统方法是定义一个变量count然后再使它++,但这访问count很麻烦,没有用到OOP.
class Child{
    private String name;
    // 定义一个类变量/静态变量 static
    // 该变量的最大特点就是会被Child类的所有对象实例共享
    public static int count = 0;

    public Child(String name) {
        this.name = name;
    }
    public void join(){
        System.out.println(name + "加入了游戏..");
    }
}

// 类方法也叫静态方法
// 形式: 访问修饰符 static 数据返回类型 方法名(){}
// 调用: 类名.类方法名
class ClassOne{
    // 求出两个数的和
    public static double calSum(double n1,double n2){
        return n1 + n2;
    }

    private String name;
    private static double fee = 0;

    public ClassOne(String name) {
        this.name = name;
    }

    // 说明
    // 1. 当方法使用了static修饰后,该方法就是静态方法
    // 2. 静态方法可以访问静态属性/变量
    public static void payFee(double fee){
        ClassOne.fee += fee;    // 累积
    }
    public static void feeInfo(){
        System.out.println("总学费共有" + ClassOne.fee + "$");
    }
}

// 当方法中不涉及到任何与对象有关的成员,则可以将方法设计成静态方法提高开发效率,比如工具类Utility
// 在实际开发中,程序员会把一些通用的方法编写成静态方法,比如数组遍历,冒泡排序,完成某个计算任务等..

内部变量

/*
    内部类: 一个类的内部又嵌套了一个类结构
    内部类的最大特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系
    语法:
        class Outer{    // 外部类
            class Inter{    // 内部类

            }
        }
        class Other{    // 外部其他类

        }
*/
public class OOP_inClass {
    public static void main(String[] args){

    }
}

class inClassInter{ // 外部类
    private int n1 = 100;   // 属性

    // 构造器
    public inClassInter(int n1) {
        this.n1 = n1;
    }

    public void ml(){   // 方法
        System.out.println("ml()");
    }

    class InclassOut{   // 内部类, 在外部类的内部定义的类
        public void ml(){
            System.out.println("内部类");
        }
    }

    {   // 代码块
        System.out.println("代码块");
    }
}

/*
    局部类是定义在外部类的局部位置,比如方法中,并且有类名.
    1. 可以直接访问外部类的所有成员,包括私有的
    2. 不能添加访问权限符,因为它的地位就是一个局部变量. 但可以用final修饰(局部变量也是可以用final修饰的)
    3. 局部内部类 -- 访问 --> 外部类的成员 [访问方式:直接访问]
    4. 外部类 -- 访问 --> 局部内部类的成员
       访问方式: 创建对象,再访问(必须在作用域内)
    5. 外部其他类 -- 不能访问 --> 局部内部类(因为局部内部类的地位就是一个局部变量)
    6. 如果外部类和局部内部类成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用"外部类名.this.成员"去访问
       Sytem.out.println(外部类名.this.成员名);
*/

/*
    匿名内部类:
    1) 本质还是类
    2) 内部类
    3) 该类没有名字
    4) 同时还是一个对象
    语法格式:
        new 类或接口(参数列表) {
            类体
        }

*/

内部变量案例

package chap01;

// 1 有一个铃声接口Bell,里面有个ring方法
// 2 有一个Cellphone类,具有闹钟功能alarmClock,参数是Bell类型
// 3 测试手机类的闹钟功能,通过匿名类(对象)作为参数,打印"懒猪起床了"
// 4 再传入另一个匿名内部类(对象),打印"小伙伴上课了"

public class OOP_inClass_homework_one {
    public static void main(String[] args){
        inClassCellphone cellphone = new inClassCellphone();

        /* inClassBell bell = new inClassBell(){
            @Override
            public void ring() {
                System.out.println("懒猪起床了");
            }
        } */

        cellphone.alarmClock(new inClassBell(){
            @Override
            public void ring() {
                System.out.println("懒猪起床了");
            }
        });
        cellphone.alarmClock(new inClassBell(){
            @Override
            public void ring() {
                System.out.println("小伙伴上课了");
            }
        });
    }
}

interface inClassBell{  // 接口
    public void ring(); // 方法
}

class inClassCellphone{
    public void alarmClock(inClassBell bell){
        System.out.println(bell.getClass());
        bell.ring(); // 动态绑定
    }
}
package chap01;

public class OOP_inClass_homework_two {
    public static void main(String[] args){

        // 当作实参直接传递,简洁高效
        fl(new inClassIl(){
            @Override
            public void show() {
                System.out.println("这是一副名画!");
            }
        });

        // 传统方法
        fl(new inClassPicture());
    }

    public static void fl(inClassIl il){
        il.show();
    }
}

interface inClassIl{
    void show();
}
class inClassPicture implements inClassIl{
    @Override
    public void show() {
        System.out.println("这是一副名画.");
    }
}
// 1 在inCLassFrock类中声明私有属性currentNum[int类型],初始值为100000,作为衣服出厂的序列号初始值
// 2 声明公有的静态方法getNextNum,作为生成上衣唯一序列号的方法。每调用一次,将currentNum增加100,并作为返回值
// 3 在OOP_inClass_homework_three类的main方法中,分两次调用getNextNum方法,获取序列号并打印输出。
// 4 在inClassFrock类中声明serialNumber(序列号)属性,并提供对应的get方法
// 5 在inClassFrock类的构造器中,通过调用getNextNum方法为inClassFrock对象获取唯一的序列号,赋给serialNumber属性
// 6 在main方法中,分别创建三个inClassFrock对象,并打印三个对象的序列号,验证是否为按100递增

public class OOP_inClass_homework_three {
    public static void main(String[] args){
        System.out.println(inClassFrock.getNextNum());
        System.out.println(inClassFrock.getNextNum());
        inClassFrock frock1 = new inClassFrock();
        inClassFrock frock2 = new inClassFrock();
        inClassFrock frock3 = new inClassFrock();
        System.out.println(frock1.getSeralNumber());
        System.out.println(frock2.getSeralNumber());
        System.out.println(frock3.getSeralNumber());
    }
}
class inClassFrock{
    private static int currentNum = 100000;    // 衣服出厂的序列号
    int seralNumber;    // 序列号

    public static int getNextNum(){   // 生成上衣唯一序列号的方法
        currentNum += 100;
        return currentNum;
    }

    public inClassFrock() {
        seralNumber = getNextNum();
    }

    public int getSeralNumber() {
        return seralNumber;
    }
}

面向对象特性

import java.util.Scanner;

// 面向对象编程三大特性: 封装、继承和多态
public class OOP_others {
    // 访问权限符可以用来修饰类中的属性、成员方法和类
    public static void main(String[] args){
        /*
        oopSymble oopsymble = new oopSymble();
        oopsymble.show();
        */
        PersonOne personone = new PersonOne();
        personone.setName("Roy");   // 通过set方法写入信息到类
        personone.setAge(22);
        personone.setSalary(5000.0);
        System.out.println("姓名:" + personone.getName());    // 通过get方法获取
        System.out.println("年龄:" + personone.getAge());
        System.out.println("工资:" + personone.getSalary());

        Account account = new Account();
        account.setName("Roy");     // 调用private
        account.setSalary(5000);
        account.setPassword("123456");
        account.info();

        Roy roy = new Roy("Roy",22);
        // roy.name = "Roy";
        roy.show();
    }
}
// 在同一个包下,可以调用public default protected修饰的变量,但不能调用private修饰的变量.

// 只有default和public可以修饰类
class oopSymble{
    public int n1 = 100;    // 公共的
    private int n2 = 100;   // 私人用
    int n3 = 100;           // default 默认
    protected int n4 = 100; // 子孙用
    public void show(){
        // 在同一个类下,成员方法可以调用public private default protected修饰的变量.
        System.out.println("" + n1 +"\t" + n2 + "\t" + n3 + "\t" + n4);
    }
}

/*
    封装:把抽象出来的数据(属性)和对数据的操作(方法)封装在一起,
    数据被保护在内部,程序的其他部分只有通过被授权的操作(方法)才能对数据进行操作.
    封装的步骤:
        1. 将属性进行私有化private(不能直接修改属性)
        2. 提供一个公共(public)set方法,用于对属性判断并赋值
            public void setXXX(类型 参数名){ // XXX表示某个属性
               // 加入数据验证的业务逻辑
               属性 = 参数名;
            }
        3. 提供一个公共(public)get方法,用于获取属性的值
            public void getXXX(){   // 权限判断,XXX某个属性
                return XXX;
            }
*/

// 代码封装示例1
// private 不能直接调用,只能间接调用
class PersonOne{
    // 不能随便查看人的年龄,工资等隐私,并对设置的年龄进行合理的验证。
    // 年龄合理就设置,否则给默认年龄,必须在 1-120,年龄,工资不能直接查看,name 的长度在 2-6 字符之间.
    public String name; // 名字公开
    private int age;    // 年龄私有
    private double salary;

    // 第一种写入: alt+insert 生成构造器
    /*
    public PersonOne(String name, int age, double salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;

        //也可以将set方法写入到构造器中
    }
    */
    // 第二种写入: set方法 + get方法
    public void setName(String name) {
        this.name = name;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    // get方法: 可获取封装的代码
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
    public double getSalary() {
        return salary;
    }
    // 这个方法的作用是返回属性信息
    public String info(){
        return "name=" + name + ",age=" + age + ",salary=" + salary;
    }
}

// 代码封装示例2
/*
 * 创建程序,在其中定义两个类:Account 和 AccountTest 类体会 Java 的封装性。
 * Account 类要求具有属性:姓名(长度为 2 位 3 位或 4 位)、余额(必须>20)、
 * 密码(必须是六位), 如果不满足,则给出提示信息,并给默认值(程序员自己定)
 * 通过 setXxx 的方法给 Account 的属性赋值。
 * */
class Account{
    private String name;
    private int salary;
    private String password;

    // 提供两个构造器
    public Account() {
    }

    public Account(String name, int salary, String password) {
        this.name = name;
        this.salary = salary;
        this.password = password;
    }

    public String getName() {
        return name;
    }
    // set方法, 加入信息判断的业务逻辑
    public void setName(String name){
        if(name.length() >= 2 && name.length() <= 4){
            this.name = name;
        }else{
            System.out.println("姓名要求(长度为2位\3位\4位),默认值为无名");
            this.name = "无名";
        }
    }

    public int getSalary() {
        return salary;
    }
    public void setSalary(int salary) {
        if(salary > 20){
            this.salary = salary;
        }else{
            System.out.println("余额(必须>20),默认为0");
            this.salary = 0;
        }
    }

    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        if(password.length() == 6){
            this.password = password;
        }else{
            System.out.println("密码必须大于6位,默认密码为000000");
            this.password = "000000";
        }
    }

    // 显示账户信息
    public void info(){
        // 可以增加权限的校验
        System.out.println("账号信息:" + name + "\t余额:" + salary + "\t密码:" + password);
    }
}

/*
    继承可以解决代码复用问题
    当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法.
    所有的子类不需要重新定义这些属性和方法,只需要通过extends来声明继承类即可.
    继承语法: class 子类名 extends 父类名{}
        1. 子类就会自动拥有父类定义的属性和方法.
        2. 父类又叫作超类,基类等.
        3. 子类又叫派生类.
*/
// 继承示例1
class StudentOne{
    public String name;
    public int age;

    // 父类构造器
    public StudentOne(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
class Roy extends StudentOne{
    public Roy(String name, int age) {
        super(name,age);    // 调用父类的构造器
    }
    // 子类的show和父类的show名字相同,但功能不同即为重写
    public void show(){
        System.out.println("姓名:" + name + "正在读大学," + "目前" + age + "岁");
    }
}
/*
    继承的注意事项:
    1. 子类继承了所有的属性和方法,非私有的属性可以直接在子类中访问,
       但是私有的属性和方法不能在子类直接访问,要通过父类提供的公共的方法去访问
    2. 子类必须调用父类的构造器,完成父类的初始化
    3. 当创建子类时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,
       如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父类的哪个构造器完成对父类的初始化工作.
    4. 如果希望指定去调用父类的某个构造器,则显示的调用一下: super(参数列表)
    5. 子类最多可以继承一个父类,即Java是单继承机制.
*/

/*  super代表父引用,用于访问父类的属性、方法、构造器
    1. 访问父类的属性,但不能访问父类的private属性
        super.属性名
    2. 访问父类的方法,但不能访问父类的private方法
        super.方法名(参数列表)
*/

特性案例

public class OOP_others_homework_one {
    public static void main(String[] args){

        PC pc = new PC("Intel",16,500,"IBM","white");   // 写入构造器
        pc.setCPU("Not Intel");    // set方法可修改
        pc.printInfo();

    }
}

// 编写Computer类,包含CPU、内存、硬盘等信息,getDetails方法返回Computer信息
// 编写PC子类,继承Computer类,添加特有属性【品牌】【color】
// 编写主类,在main方法中创建PC和NotePad对象,分别给对象中特有属性赋值以及继承来的属性赋值并打印信息。
class Computer{
    private String CPU;
    private int RAM;
    private int hardpan;

    public Computer(String CPU,int RAM,int hardpan){
        this.CPU = CPU;
        this.RAM = RAM;
        this.hardpan = hardpan;
    }

    // get方法
    public String getCPU() {
        return CPU;
    }
    public int getRAM() {
        return RAM;
    }
    public int getHardpan() {
        return hardpan;
    }
    // set方法
    public void setCPU(String CPU) {
        this.CPU = CPU;
    }
    public void setRAM(int RAM) {
        this.RAM = RAM;
    }
    public void setHardpan(int hardpan) {
        this.hardpan = hardpan;
    }

    // 返回Computer信息
    public String getDetails(){
        return "CPU = " + CPU + "\tRAM = " + RAM + "\thardpan = " + hardpan;
    }
}

class PC extends Computer{
    private String brand;
    private String color;
    public PC(String CPU, int RAM, int hardpan, String brand, String color) {
        super(CPU, RAM, hardpan);
        this.brand = brand;
        this.color = color;
    }

    public String getBrand() {
        return brand;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }

    public void printInfo(){
        System.out.println("PC信息 = ");
        System.out.println(getDetails() + "\tbrand = " + brand + "\tcolor = " + color);
    }
}

方法重载

public class OOP_oveload {
    public static void main(String[] args) {
        // 方法重载: 在同一个类中,允许多个同名的方法存在,但方法的参数列表需不同
        // 好处: 减去了取名和记名的麻烦

        // 何为参数列表不同?(参数的顺序、数据类型,个数):
        /* calculate(int n1, int n2); 两个整数的和
           calculate(int n1, double n2); 一个整数和,一个 double 和
           calculate(double n1, double n2); 两个 double 和
           calculate(int n1, int n2, int n3); 三个整数的和 */

        /*
        OverLoadOne overloadone = new OverLoadOne();
        overloadone.OverLoad(2);
        overloadone.OverLoad(2,2);
        overloadone.OverLoad("您好!");
        OverLoadTwo overloadtwo = new OverLoadTwo();
        overloadtwo.intMax(1,2);
        overloadtwo.doubleMax(1.0,2.0);
        */

        // 可变参数: 实现将同一个类中许多同名同功能但参数个数不同的方法封装起来.
        Student student = new Student();
        System.out.println(student.studentScore("Roy", 78, 89, 92, 90));
    }
}

class OverLoadOne {
    // 方法的重载
    // 要求: 方法名相同;形参列表必须不同(形参个数或顺序不同);返回值类型无要求;
    public void OverLoad(int n) {
        System.out.println(n * n);
    }

    public void OverLoad(int n1, int n2) {
        System.out.println(n1 * n2);
    }

    public void OverLoad(String str) {
        System.out.println(str);
    }
}

class OverLoadTwo {
    public void intMax(int n1, int n2) {
        int result = n1 > n2 ? n1 : n2;
        System.out.println("两个int中最大值为:" + result);
    }

    public void doubleMax(double n1, double n2) {
        double result = n1 > n2 ? n1 : n2;
        System.out.println("两个double中最大值为:" + result);
    }
}

/*
	利用可变参数,在Student类中定义一个静态方法,以达到这样的效果:
	调用该方法时,需要传入学生的姓名,年级和他四门课的成绩,然后会在控制台上打印出该学生的信息。
*/
class Student {
    public String studentScore(String name, double... scores) {
        int scoreSum = 0;
        // 可变参数本质就是数组
        for (int i = 0; i < scores.length; i++) {
            scoreSum += scores[i];
        }
        return name + "有" + scores.length + "门课程" + ",总分为" + scoreSum;
    }
}

方法重写

public class OOP_override {
    public static void main(String[] args){
        // 方法重写:子类有一个方法,和父类的某个方法的名称、返回类型、参数一样,那么就是这个子类的方法覆盖了父类的方法
        StudentOverride student = new StudentOverride("Roy",22,"07201030",98);
        student.setName("Roy");
        student.say();
    }
}
/*  方法重写要求:
    1. 子类的形参列表,方法名称,要和父类方法的形参列表,方法名称一样.
    2. 子类方法的返回类型和父类方法返回类型一样,或者是父类返回类型的子类.
    3. 子类方法不能缩小父类方法的访问权限, public > protected > default > private
*/
class PersonOverride{
    //  1) 编写一个 Person 类,包括属性/private(name、age),构造器、方法 say(返回自我介绍的字符串)。
    //  2) 编写一个 Student 类,继承 Person 类,增加 id、score 属性/private,以及构造器,定义 say 方法(返回自我介绍的信息)。
    //  3) 在 main 中,分别创建 Person 和 Student 对象,调用 say 方法输出自我介绍
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    // 返回自我介绍的字符串
    public void say(){
        System.out.println("自我介绍:");
        System.out.println("姓名:" + name + ",\t年龄" + age);
    }
}
class StudentOverride extends PersonOverride{
    private String id;
    private double score;
    public StudentOverride(String name, int age, String id, double score) {
        super(name, age);
        this.id = id;
        this.score = score;
    }
    // 返回自我介绍, 和父类的say方法重写.
    public void say(){
        super.say();    // super.对象名(属性名) 访问父类的属性或方法,不能访问父类的private属性或方法
        System.out.println("学号:" + id + ",\t成绩" + score);
    }

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public double getScore() {
        return score;
    }
    public void setScore(double score) {
        this.score = score;
    }
}

多态性

public class OOP_ploymethod {
    public static void main(String[] args){
        // 多态是建立在封装和继承基础之上的
        // 方法重载体现多态
        A a = new A();
        // 这里我们传入不同的参数,就会调用不同sum方法,就构成了多态.
        a.sum(10,20);
        a.sum(10,20,30);
    }
}
// 多态示例1
class A{
    public void sum(int n1,int n2){
        System.out.println(n1 + n2);
    }
    public void sum(int n1,int n2,int n3){
        System.out.println(n1 + n2 + n3);
    }
}

/*  多态的前提是:两个对象存在继承关系
    1. 多态向上型
        本质: 父类的引用指向了子类的对象
        语法: 父类类型 引用名 = new 子类类型();
    2. 多态向下型
        语法: 子类类型 引用名 = (子类类型) 父类引用;
        只能强装父类的引用,不能强装父类的对象
*/

/*  Java的动态绑定机制
    1. 当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定
    2. 当调用对象属性的时候,没有动态绑定机制,哪里声明便哪里使用
*/

/*  
	多态的应用
        多态数组
        多态参数
*/

多态性案例

package chap01;

public class OOP_ploymethod_homework_one {
    public static void main(String[] args){
        // 多态应用: 多态数组
        PloyMethodPerson_one[] persons = new PloyMethodPerson_one[5];
        persons[0] = new PloyMethodStudent_one("John",22,90.0);
        persons[1] = new PloyMethodPerson_one("Roy",21);
        persons[2] = new PloyMethodStudent_one("Kim",22,88.0);
        persons[3] = new PloyMethodStudent_one("Tom",20,92.0);
        persons[4] = new PloyMethodPerson_one("Judy",20);

        for(int i = 0; i < persons.length; i++){
            System.out.println(persons[i]);
        }
    }
}
class PloyMethodPerson_one{
    private String name;
    private int age;

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

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

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

    @Override
    public String toString() {
        return name + ", age= " + age;
    }
}
class PloyMethodStudent_one extends PloyMethodPerson_one{
    private double score;

    public PloyMethodStudent_one(String name, int age, double score) {
        super(name, age);
        this.score = score;
    }

    public double getScore() {
        return score;
    }
    public void setScore(double score) {
        this.score = score;
    }

    @Override
    public String toString(){
        return "学生:" + super.toString() + ", score=" + score;
    }
}
class ployMethodStudent_two extends PloyMethodPerson_one{
    private double salary;

    public ployMethodStudent_two(String name, int age, double salary) {
        super(name, age);
        this.salary = salary;
    }

    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }

    @Override
    public String toString(){
        return "老师 " + super.toString() + ", salary = " + salary;
    }
}

设计模式(单例模式)

package chap01;

/*
    设计模式是在大量的实践中总结和理论化之后优选的代码结构\编程风格以及解决问题的思考方式;
    什么是单例模式?
        所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,
        对某个类只能存在一个对象实例,并且该类只提供了一个取得对象实例的方法.
    单例模式分为: 饿汉式和懒汉式
*/

/*
    饿汉式和懒汉式单例模式的实现:
    1) 构造器私有化 => 防止直接new
    2) 类的内部创建对象
    3) 向外暴露一个静态的公共方法.
    4) 代码实现
*/
public class OOP_SingleCase {
    public static void main(String[] args){
        // 1 饿汉式, 通过方法可以获取对象
        SingleCase01 instance01 = SingleCase01.getInstance();
        System.out.println(instance01);

        // 2 懒汉式
        SingleCase02 instance02 = SingleCase02.getInstance();
        System.out.println(instance02);
    }
}

// 01 饿汉式
class SingleCase01{
    private String name;
    // 为了能够在静态方法中返回,需要将其修饰为static
    private static SingleCase01 gf = new SingleCase01("小红红");

    // 单例模式[饿汉式]
    // 1. 将构造器私有化
    // 2. 在类的内部直接创建对象(该对象是static)
    // 3. 提供一个公共的static方法,返回gf
    private SingleCase01(String name) {
        this.name = name;
    }

    public static SingleCase01 getInstance(){
        return gf;
    }

    @Override
    public String toString() {
        return "name = " + name;
    }
}

//  懒汉式
class SingleCase02 {
    private String name;
    public static int n1 = 999;
    private static SingleCase02 singlecase02; // 默认是null

    // 懒汉式实现步骤:
    // 1. 构造器私有化
    // 2. 定义一个static静态属性对象
    // 3. 提供一个public的static方法,可以返回一个SingleCase02对象
    // 4. 懒汉式只有当用户使用getInstance时才返回SingleCase02对象,后面在调用时会返回上次创建的对象.

    private SingleCase02(String name) {
        this.name = name;
    }

    public static SingleCase02 getInstance(){
        if(singlecase02 == null){
            singlecase02 = new SingleCase02("小红红");
        }
        return singlecase02;
    }

    @Override
    public String toString() {
        return "name=" + name;
    }
}

/*
    饿汉式 vs 懒汉式
    1. 二者最主要的区别在于创建对象的时机不同;
       饿汉式是在类加载就创建了对象实例,而懒汉式是在使用时才创建
    2. 饿汉式不存在线程安全问题,懒汉式存在线程安全问题
    3. 饿汉式存在浪费资源的可能,因为如果程序员一个对象实例都没有使用,那么饿汉式创建的对象就浪费了
       懒汉式是使用时才创建,就没有存在这个问题.
*/

接口

public class OOP_Interface {
    public static void main(String[] args){
        // 创建对象
        // InterfaceA01 实现了 Interface01
        InterfaceA01 interface01 = new InterfaceA01();
        InterfaceA02 interface02 = new InterfaceA02();
    }
}

interface Interface01{  // 接口, 为了方便学习,我将它写在同个类下(同个类下的接口不用访问权限符)
    public void start();
    public void stop();
}

class InterfaceA01 implements Interface01{  // 实现接口, 就是把接口的方法实现
    @Override
    public void start() {
        System.out.println("相机开始工作..");
    }
    @Override
    public void stop() {
        System.out.println("相机停止工作..");
    }
}
class InterfaceA02 implements Interface01{
    @Override
    public void start() {
        System.out.println("手机开始工作..");
    }
    @Override
    public void stop() {
        System.out.println("手机停止工作..");
    }
}

/*
    接口是更加抽象的抽象类, 抽象类里的方法可以有方法体,接口里所有方法都没有方法体
    接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,再根据具体情况把这些方法写出来.
    语法:
        interface 接口名{
            // 属性
            // 抽象方法
        }
        class 类名 implements 接口{
            // 自己属性
            // 自己方法
            // 必须实现的接口的抽象方法
        }
    " 接口体现了程序设计的多态和高内聚低耦合的设计思想. "
*/

接口案例

package chap01;

public class OOP_Interface_one {
    public static void main(String[] args){
        MysqlDB mysqlDB = new MysqlDB();
        t(mysqlDB);
        OracleDB oracleDB = new OracleDB();
        t(oracleDB);
    }
    public static void t(DBInterface db){
        db.connect();
        db.close();
    }
}

interface DBInterface{  // 接口
    public void connect();
    public void close();
}

class MysqlDB implements DBInterface{   // 类, 实现接口的抽象方法
    @Override
    public void connect() {
        System.out.println("连接Mysql");
    }
    @Override
    public void close() {
        System.out.println("关闭Mysql");
    }
}
class OracleDB implements DBInterface{
    @Override
    public void connect() {
        System.out.println("连接Oracle");
    }
    @Override
    public void close() {
        System.out.println("关闭Oracle");
    }
}

/*
    接口注意事项:
    1. 接口不能被实例化
    2. 接口中所有的方法是public方法,接口中的抽象方法可以不用abstract修饰
    3. 一个普通类实现接口,就必须将该接口的所有方法都实现
    4. 抽象类实现接口,可以不用实现接口的方法
    5. 一个类同时可以实现多个接口
    6. 接口中的属性只能是final,而且是public static final修饰符
    7. 接口中属性的访问形式: 接口名.属性名
    8. 接口不能继承其它的类,但是可以继承多个别的接口
    9. 当子类继承了父类,就自动拥有父类的功能,
       如果子类需要拓展功能,可以通过实现接口的方式拓展,
       可以理解为 实现接口 是对Java单继承机制的一种补充.
    10. 接口和继承不同之处
       继承的价值在于: 解决代码的复用性和可维护性
       接口的价值在于: 设计,规范好各种规范(方法),让其他类去实现这些方法.
*/
package chap01;
import java.util.Scanner;

public class OOP_interface_homework_one {
    public static void main(String[] args){
        interfacePerson person = new interfacePerson("唐僧","Horse");
        interfaceHorse horse = new interfaceHorse();
        interfaceBoat boat = new interfaceBoat();
        boolean isFlag = true;
        if(isFlag){
            horse.work();
        }else{
            boat.work();
        }
    }
}

interface interfaceWork{
    public void work();
}
class interfaceHorse implements interfaceWork{
    @Override
    public void work() {
        System.out.println("Use the Horse");
    }
}
class interfaceBoat implements interfaceWork{
    @Override
    public void work() {
        System.out.println("Use the Boat");
    }
}

// Person类
class interfacePerson{
    private String name;
    private String Vehicles;

    public interfacePerson(String name, String vehicles) {
        this.name = name;
        Vehicles = vehicles;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getVehicles() {
        return Vehicles;
    }
    public void setVehicles(String vehicles) {
        Vehicles = vehicles;
    }

    @Override
    public String toString() {
        return name  + Vehicles ;
    }
}

枚举

public class Enum {
    public static void main(String[] args){

        /*
        Seasons01 winter = new Seasons01("冬天","寒冷");
        winter.setDesc("非常地冷");
        System.out.println(spring.toString());
         */

        // 使用枚举1(自定义类实现枚举)
        System.out.println(Seasons02.SPRING);
        System.out.println(Seasons02.SUMMER);

        // 使用枚举2(enum关键字实现枚举)
        System.out.println(Seasons03.SPRING);
        System.out.println(Seasons03.SUMMER);

        // 枚举类实现接口
        EnumMusic01.CLASSICMUSIC.playing();
    }
}

/*
// 情况1: 没使用枚举
class Seasons01{
    private String name;
    private String desc;    // 描述

    public Seasons01(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDesc() {
        return desc;
    }
    public void setDesc(String desc) {
        this.desc = desc;
    }

    @Override
    public String toString() {
        return name + desc ;
    }
}
*/

/*
    枚举(enum)是一组常量的集合(枚举属于一种特殊的类,里面只包含一组有限的特定对象)
    实现枚举的两种方式:
    1. 自定义类实现枚举
    2. 使用enum关键字实现枚举
*/
/*
    自定义类实现枚举案例
    1. 不需要setXXX方法,因为枚举对象值通常为只读
    2. 对枚举对象/属性使用 final + static 共同修饰,实现底层优化
    3. 枚举对象名通常全部使用大写
    4. 枚举对象根据需要,也可以有多个属性
*/
// 情况2: 使用了枚举(自定义类实现枚举)
class Seasons02 {
    private String name;
    private String desc;    // 描述

    // 1. 将构造器私有化,防止直接new
    // 2. 去掉setXXX方法,防止属性被更改
    // 3. 再Seasons02内部直接创建固定对象
    private Seasons02(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    // 定义四个对象,固定
    public static final Seasons02 SPRING = new Seasons02("春天","温暖");
    public static final Seasons02 SUMMER = new Seasons02("夏天","炎热");

    public String getName() {
        return name;
    }
    public String getDesc() {
        return desc;
    }

    @Override
    public String toString() {
        return  name +  desc;
    }
}

// 情况3: 使用了枚举(enum关键字实现枚举)
enum Seasons03{
    SPRING("春天","温暖"),SUMMER("夏天","炎热");

    private String name;
    private String desc;

    // 1. 用关键字enum替代了class
    // 2. public static final Seasons03 SPRING = new Seasons03("春天","温暖"); 直接替代成 SPRING("春天","温暖");
    // 3. 我们使用无参构造器,创建常量对象,则可以省略()

    private Seasons03() {   // 无参构造器

    }

    Seasons03(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    public String getName() {
        return name;
    }
    public String getDesc() {
        return desc;
    }

    @Override
    public String toString() {
        return name +  desc ;
    }
}

// enum实现接口
// 使用enum关键字后就不能继承其它类了,因为enum会隐式继承Enum,而Java是单继承机制
// 枚举和普通类不同,可以实现接口, 语法: enum 类名 iumplements 接口1,接口2{}

interface EnumInterface01{
    public void playing();
}
enum EnumMusic01 implements EnumInterface01{
    CLASSICMUSIC;

    @Override
    public void playing() {
        System.out.println("播放好听的音乐..");
    }
}

枚举案例

/*
    声明 Week 枚举类,其中包含星期一至星期日的定义;
        MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
    使用 values 返回所有的枚举数组, 并遍历
*/
public class OOP_Enum_homework_one {
    public static void main(String[] args){
        EnumWeek01[] weeks = EnumWeek01.values();   // 获取到所有枚举对象, 即数组
        // 数组遍历
        System.out.println("所有星期信息如下:");
        for(EnumWeek01 week : weeks){
            System.out.println(week);
        }
    }
}

enum EnumWeek01{
    // 定义枚举对象
    MONDAY("星期一","工作日"),
    TUESDAY("星期二","工作日"),
    WEDNESDAY("星期三","工作日"),
    THURSDAY("星期四","工作日"),
    FRIDAY("星期五","工作日"),
    SATURDAY("星期六","周末了"),
    SUNDAY("星期日","周末了");

    private String name;
    private String desc; // 描述

    EnumWeek01(String name, String desc) {    // 构造器
        this.name = name;
        this.desc = desc;
    }

    public String getName() {
        return name;
    }
    public String getDesc() {
        return desc;
    }

    @Override
    public String toString() {
        return name + desc ;
    }
}

异常处理

package chap01;

import java.util.Arrays;

public class Exception extends Throwable {
    public static void main(String[] args){
        int num1 = 1,num2 = 0;
        String name = null;
        int[] arr = new int[3];

        // System.out.println(num1 / num2);    // 1 数学运算异常: 除数为0
        // System.out.println(name.length());  // 2 空指针异常
        // System.out.println(arr[3]); // 3 数组下标越界异常

        ExceptionA a1 = new ExceptionB();   // 向上转型
        ExceptionB b1 = (ExceptionB)a1;     // 向下转型,是可以的
        // ExceptionC c1 = (ExceptionC)a1;     // 这里会抛出类型转换异常

        String str = "狠狠赚一笔";   // 中文没有对应的ASCII
        // int strTo = Integer.parseInt(str);
        // System.out.println(strTo);  //  数字格式不正确

        // 如果程序员认为一段代码可能存在异常,可以使用try..catch异常处理机制来处理

        // 单个catch
        try{
            String str01 = "狠狠赚一笔";
            int strTo01 = Integer.parseInt(str01);
            System.out.println(strTo01);
        }catch(NumberFormatException e){
            System.out.println("异常信息:" + e.getMessage());
        }finally{
            System.out.println("finally块被执行");
        }

        // 多个catch
        try{
            System.out.println(name.length());
            System.out.println(num1 / num2);
        }catch(NumberFormatException e){
            System.out.println(e.getMessage());
        }catch(NullPointerException e){
            System.out.println(e.getMessage());
        }
    }
}

/*
    try..catch() 异常捕获: 对异常进行捕获,确保程序可以正常运行

    异常分为两大类: 运行时异常(程序运行时发生的异常)和编译时异常(编程时,编译器检查出的异常)
        运行时异常:编译器检查不出来,通常是编程逻辑错误
            NullPointException:空指针异常
            ArithmeticException:数学运算异常
            ArrayIndexOutOfBoundsException:数组下标越界异常
            ClassNotFoundException:类型转换异常(将对象强制转换为不是实例的子类时发出的异常)
            NumberFormatException: 数组格式不正确异常(试图将字符串转换为一种数值类型,但该字符串无法转换为适当格式时,抛出异常)
        编译时异常:编译器必须要处理的异常
*/

/*
    异常处理方式: 异常发生时对异常处理的方式
    1) try-catch-finally 程序员在代码中捕获发生的异常
        语法:
            try{
                // 可疑代码
                // 将异常生成对应的异常对象,传递给catch块
            }catch(Exception e){
                // 异常处理的代码
            }finally{ }
        1 如果异常发生了,则异常发生后面的代码不会执行,直接进入到catch块
        2 如果异常没有发生,则顺序执行try的代码块,不会进入到catch
        3 如果希望不管是否发生都执行某段代码(比如关闭连接,释放资源等)则使用 finally{ }
        4 可以有多个catch子句来捕获不同的异常(进行不同的业务处理),要求父类异常在子类异常前
          (比如Exception在前,NullPointerException在后)如果发生异常只会匹配一个catch
    2) throws 将发生的异常抛出,交给调用者(方法)来处理,最顶级的处理者就是JVM
        1 在方法声明中用throws语句可以抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类
        2 对于运行时异常,程序中如果没有处理,默认的就是throws的方式处理
        语法: public 返回值类型 方法名称(参数列表) throws 异常类型{ }
    3) 自定义异常: 当程序出现异常,但信息没有在throws详细描述处理,这时就可以设计异常类型,用于描述错误信息
*/

/*
    throws 和 throw 的区别:
    throws: 异常处理的一种方式,位置在方法声明处,后面跟异常类型;
    throw: 手动生成异常对象的一种方式,位置在方法体中,后面跟异常对象;
*/

class ExceptionA{ }
class ExceptionB extends ExceptionA{ }
class ExceptionC extends ExceptionA{ }

异常处理案例

import java.util.Scanner;

// 如果用户输入的不是一个整数,就提示它反复输入,知道输入一个整数为止

public class Exception_homework_one {
    public static void main(String[] args) {
        Scanner sr = new Scanner(System.in);
        int num = 0;
        String inputStr = "";
        System.out.print("请输入一个整数:");
        inputStr = sr.next();
        while (true) {      // 使用无限循环去接收一个输入,然后将输入的值转换为int
            try {       // 如果在转换时抛出异常,说明输入的内容不是一个可以转换成int的内容
                num = Integer.parseInt(inputStr);   // 这里是抛出异常
                break;  // 如果没有抛出异常则break结束循环
            } catch (NumberFormatException e ) {
                System.out.println("您输入的不是一个整数!");
            }
        }
        System.out.println("您输入的值是" + num);
    }
}
import java.util.Scanner;

/*
    1) 编写程序,接收命令行的两个参数(整数),计算两数相除
    2) 计算两个数相除,要求使用方法ExceptionCal(int n1,int n2)
    3) 对数据格式不正确(NumberFormatException)
       缺少命令行参数(ArrayIndexOutOfBoundsException)
       除0进行异常处理(ArithmeticException)
*/

public class Exception_homework_two {
    public static void main(String[] args){
        Scanner sr = new Scanner(System.in);
        ExceptionCal cal = new ExceptionCal();
        System.out.println("请输入两个参数:");
        String str1 = sr.next();
        String str2 = sr.next();
        System.out.println(cal.cal(str1,str2));
    }
}
class ExceptionCal{
    public String cal(String n1,String n2){
        int result = 0;
        try{
            result = Integer.parseInt(n1) / Integer.parseInt(n2);
        }catch(NumberFormatException e){
            return "数据类型转换失败";
        }catch(ArrayIndexOutOfBoundsException e){
           return "数组下标越界";
        }catch(ArithmeticException e){
            return "除数不能为0";
        }
        return result + " ";
    }
}
/*
    输入用户名、密码、邮箱,如果信息输入正确则提示登录成功,否则生成异常对象
    要求:1. 用户名长度为2或3或4
         2. 密码的长度为6,要求全是数字
         3. 邮箱中包含@和. 并且@在.前面
*/

public class Exception_homework_three {
    public static void main(String[] args) throws Exception {
        String username = "aa";
        String password = "123456";
        String email = "aa@qq.com";
        Method(username, password,email);
        System.out.println("注册成功!");
    }

    // 自定义异常类
    public static void Method(String username,String password,String email){
        if(!(2 <= username.length() && username.length() <= 4)){
            throw new RuntimeException("用户名格式错误");
        }
        if(!(password.length() == 6) && (isDigital(password))){
            throw new RuntimeException("密码格式错误!");
        }
        int index1 = email.indexOf('@');
        int index2 = email.indexOf('.');
        if(!(index1 > -1 && index2 > index1)){
            throw new RuntimeException("邮箱格式错误!");
        }
    }

    public static boolean isDigital(String password){
        char[] chars = password.toCharArray();
        for(int i=0; i<chars.length; i++){
            if(chars[i] < '0' && chars[i] > '9'){
                return false;
            }
        }
        return true;
    }
}

集合

/*
    数组和集合的区别:
    数组:
        1) 长度在声明是必须指定,而且一旦指定,就不能再更改
        2) 保存的必须是同一类型的元素
        3) 使用数组进行增加/删除元素的示意代码 -> 比较麻烦
    集合:
        1) 可以动态保存多个任意对象,使用比较方便
        2) 提供了一系列方便操作对象的方法:add,remove,set,get等
        3) 使用集合添加/删除元素的示意代码 -> 简洁了

    集合分为两类: Collection和Map
*/

import java.util.ArrayList;
import java.util.HashMap;

public class Grather {
    public static void main(String[] args){

        /* list的操作 */
        ArrayList arraylist = new ArrayList();
        // add: 添加单个元素
        arraylist.add("Java");
        arraylist.add(1,"Python");  // 在index为1的位置插入python
        // remove: 删除指定元素
        arraylist.remove("Python");
        arraylist.remove(0); // 删除第一个元素
        // contains: 查找元素是否存在
        System.out.println(arraylist.contains("Java")); // 找到则返回true,否则false
        // get: 获取元素
        System.out.println(arraylist.get(4));   // 集合名.get(希望获取元素索引i)
        // set: 修改元素
        arraylist.set(4,"Java");    // 集合名.set(索引i,修改的数据)
        // size: 获取元素个数
        System.out.println(arraylist.size());
        // isEmpty: 判断是否为空
        System.out.println(arraylist.isEmpty());
        // clear: 清空
        arraylist.clear();
        // addAll: 添加多个元素
        ArrayList arraylist2 = new ArrayList();
        arraylist2.add("C");
        arraylist2.add("PHP");
        arraylist.addAll(arraylist2);
        // containsAll: 查看多个元素是否都存在
        System.out.println(arraylist.containsAll(arraylist2));
        // removeAll: 删除多个元素
        System.out.println(arraylist.removeAll(arraylist2));

        HashMap hashmap = new HashMap();
        hashmap.put("No.1","北京");
        hashmap.put("No.2","深圳");
    }
}

Collection

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Grather_Collections {
    public static void main(String[] args){

        // 创建ArrayList 用于测试
        List arraylist = new ArrayList();
        arraylist.add("tom");
        arraylist.add("roy");
        arraylist.add("jack");
        arraylist.add("king");

        // reverse(List): 反转List中元素顺序
        Collections.reverse(arraylist);
        System.out.println("arraylist=" + arraylist);

        // shuffle(List): 对List集合元素进行随机排序
        for(int i = 0; i < 4; i++){
            Collections.shuffle(arraylist);
            System.out.println("arraylist=" + arraylist);
        }

        // sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序
        Collections.sort(arraylist);
        System.out.println("自然排序后:" + arraylist);

        // sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
            // 我们希望按照 字符串的长度大小排序
        Collections.sort(arraylist, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                //可以加入校验代码.
                return ((String) o2).length() - ((String) o1).length();
            }
        });
        System.out.println("字符串长度大小排序=" + arraylist);

        // swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换
        // 比如
        Collections.swap(arraylist, 0, 1);
        System.out.println("交换后的情况");
        System.out.println("list=" + arraylist);

        // int frequency(Collection,Object):返回指定集合中指定元素的出现次数
        System.out.println("tom 出现的次数=" + Collections.frequency(arraylist, "tom"));

        // copy(List dest,List src): 将 src 中的内容复制到 dest 中
        ArrayList dest = new ArrayList();
        //为了完成一个完整拷贝,我们需要先给 dest 赋值,大小和 list.size()一样
        for(int i = 0; i < arraylist.size(); i++) {
            dest.add("");
        }
        //拷贝
        Collections.copy(dest, arraylist);
        System.out.println("dest=" + dest);

        // boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值
        //如果 list 中,有 tom 就替换成 汤姆
        Collections.replaceAll(arraylist, "tom", "汤姆");
        System.out.println("替换后arraylist=" + arraylist);
    }
}

Collection案例

package chap01;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/*
1.封装一个新闻类:包含标题和内容属性,提供get,set方法,重写toString方法,打印对象时只打印标题
2.只提供一个带参数的构造器,实例化对象。只初始化标题。并实例化对象:
    新闻一:新冠确诊病例超千万,数百万印度教信徒赴恒河“圣浴” 引民众担忧
    新闻二:男子突然想起2个月前钓的鱼还在网兜里,捞起一看赶紧放生
    新闻三:我在南京梧桐道行走
3.将新闻对象添加到ArrayList集合中,并且进行倒叙遍历
4.在遍历过程中,对新闻标题进行处理,超过15字的只保留15个,然后再后边加“+”
5.在控制台打印遍历出经过处理的新闻标题
*/

/**
 * @author Carry
 */
public class Grather_Collections_homework_one {
    public static void main(String[] args){
        // 通过构造器创建两个对象
        GratherCollectionsNews news1 = new GratherCollectionsNews("新闻一:中国多地遭雾霾笼罩空气质量再成热议话题");
        GratherCollectionsNews news2 = new GratherCollectionsNews("新闻二:春节临近北京“卖房热”");
        // 使用arraylist存放数据
        List list = new ArrayList();
        list.add(news1);
        list.add(news2);
        int size = list.size();// 获取arrayList的字符串的长度
        for (int i = size-1; i >= 0 ; i--) { // 递减排序
            GratherCollectionsNews news = (GratherCollectionsNews)list.get(i);// 进行强转为 News 类型
            System.out.println(processtitle(news.getTitle()));
        }
    }
    // 提供方法进行判断
    public static String processtitle (String title){
        if(title == null) {
            return " ";//若字符串为空,则返回空
        }else if(title.length() > 15){//判断大于 15的字符串长度
            return title.substring(0,15) + "...";//将大于 15 的字符串长度 截取15的长度并在后面添加...
        }else
            return title;//都不满足则原路返回
    }
    }
// 封装的新闻类
class GratherCollectionsNews{
    private String title;
    private String text;

    public GratherCollectionsNews(String title) {
        this.title = title;
    }

    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getText() {
        return text;
    }
    public void setText(String text) {
        this.text = text;
    }

    @Override
    public String toString() {
        return title ;
    }
}
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class Grather_Collections_homework_two {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("jack",650);
        map.put("tom",1200);
        map.put("smith",2900);
        //1.将jack的工资改为2600元
        map.remove("jack",2600);
        //2.对所有员工进行 + 100
        Set set = map.keySet();
        for (Object key :set) {
            //为所有的员工工资加薪100元
            Integer price = (Integer) map.get(key) + 100;
            map.put(key,price);
        }
        System.out.println(map);
        System.out.println("===========增强for遍历==============");
        Set set1 = map.keySet();
        for (Object key :set1) {
            System.out.println(key + "=" + map.get(key));;
        }
        System.out.println("===========迭代器遍历==============");
        Iterator iterator = set1.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println(next + "=" + map.get(next));
        }
    }
}

HashSet

package chap01;

import java.util.HashSet;
import java.util.Objects;

public class Grather_HashSet_homework_one {
    public static void main(String[] args){
        HashSet hashset = new HashSet();
        hashset.add(new GratherHashSetEmployee("张三",20));
        hashset.add(new GratherHashSetEmployee("李四",22));
        hashset.add(new GratherHashSetEmployee("赵六",30));
        hashset.add(new GratherHashSetEmployee("张三",20));   // 因为HashSet无法重复元素存在,因此加入不成功
        System.out.println(hashset);
    }
}
class GratherHashSetEmployee{
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return name +age ;
    }

    //  如果name和age相同,就返回相同的hash值
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        GratherHashSetEmployee that = (GratherHashSetEmployee) o;
        return age == that.age && Objects.equals(name, that.name);
    }
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
package chap01;

/*  定义Employee类:
(1)该类包含:private成员变量name,sal,birthday,其中birthday为MyDate类的对象;
(2)为每一个属性定义getter,setter方法;
(3)重写toString方法输出name,sal,birthday
(4)MyDate类包含:private成员变量year,month,year;并为每一个属性定义getter,setter方法;
(5)创建该类的3个对象,并把这些对象放入ArrayList集合中(ArrayList需使用泛型来定义),
    对集合中的元素进行排序,并遍历输;
(6)排序方式:调用ArrayList的sort方法,传入Comparator对象[使用泛型],先按照name排序,
    如果name相同,则按生日日期的先后排序。*/

import java.util.HashSet;

public class Grather_HashSet_homework_two {
    public static void main(String[] args){
        // 创建对象并写入数据
        HashSet hashset = new HashSet();
        hashset.add(
                new GratherHashsetEmployee2("Roy",20,
                        new GratherHashsetMydate(2002,05,26)));
        hashset.add(
                new GratherHashsetEmployee2("Jack",25,
                        new GratherHashsetMydate(1997,02,19)));
        hashset.add(
                new GratherHashsetEmployee2("Nick",33,
                        new GratherHashsetMydate(1990,02,19)));
        // 遍历
        for(Object obj : hashset){
            System.out.println(obj);
        }
    }
}
class GratherHashsetMydate{
    private int year;
    private int month;
    private int day;

    public GratherHashsetMydate(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public int getYear() {
        return year;
    }
    public void setYear(int year) {
        this.year = year;
    }
    public int getMonth() {
        return month;
    }
    public void setMonth(int month) {
        this.month = month;
    }
    public int getDay() {
        return day;
    }
    public void setDay(int day) {
        this.day = day;
    }

    @Override
    public String toString() {
        return "" + year + "年" + month + "月" + day + "日";
    }

    // 手动重写equals方法
    @Override
    public boolean equals(Object obj) {
        if(this == obj)
            return true;
        if(obj == null)
            return false;
        if(getClass() != obj.getClass())
            return false;
        GratherHashsetMydate other = (GratherHashsetMydate) obj;
        if(day != other.day)
            return false;
        if(month != other.month)
            return false;
        if(year != other.year)
            return false;
        return true;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + day;
        result = prime * result + month;
        result = prime * result + year;
        return result;
    }
}

class GratherHashsetEmployee2{
    private String name;
    private int age;
    private GratherHashsetMydate birthday;

    public GratherHashsetEmployee2(String name, int age, GratherHashsetMydate birthday) {
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }

    @Override
    public boolean equals(Object obj) {
        if(this == obj){
            return true;
        }
        if(!(obj instanceof GratherHashsetEmployee2)){
            return false;
        }
        GratherHashsetEmployee2 e = (GratherHashsetEmployee2) obj;
        return name.equals(e.name) && birthday.equals(e.getBirthday());
    }

    @Override
    public int hashCode() {
        return name.hashCode() + birthday.hashCode();
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public GratherHashsetMydate getBirthday() {
        return birthday;
    }
    public void setBirthday(GratherHashsetMydate birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "姓名:" + name + "\t年龄:" + age + "\t生日:" + birthday;
    }
}

Iterator

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

// 集合
public class Grather_Iterator {
    public static void main(String[] args){
        ArrayList col = new ArrayList();
        col.add(new GratherBooks("三国演义","罗贯中",10.5));
        col.add(new GratherBooks("小李飞刀","古龙",5.1));
        col.add(new GratherBooks("红楼梦","曹雪芹",15.6));

        // 对 col 进行遍历
        // 1. 先得到col对应的迭代器
        Iterator iterator = col.iterator();
        // 2. 方式1: 使用 while 循环遍历集合     " 快捷键ctrl+j再输入itit "
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println(next);
        }
        // 3. 当退出while循环后,这是iterator迭代器,指向最后的元素

        /*
        // 4. 如果希望再次遍历,需要重置我们的迭代器
        iterator = col.iterator();
        System.out.println("第二次遍历");
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println(next);
        }
        */

        /*
            for增强循环语法:
            for(元素类型 元素名 : 集合名或数组名){
                访问元素
            }
        */
        // 方式2: 使用for增强循环 遍历集合
        for(Object obj : col){
            System.out.println(obj);
        }

        // 方式3: 使用普通for循环
        for(int i = 0; i < col.size(); i++){
            Object obj = col.get(i);
            System.out.println(obj);
        }
    }
}

class GratherBooks{
    private String name;
    private String author;
    private double price;

    public GratherBooks(String name, String author, double price) {
        this.name = name;
        this.author = author;
        this.price = price;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return  "书名 = " + name + ", 作者 = " + author + ", 价格 = " + price + "$" ;
    }
}

Iterator案例

package chap01;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Grather_Iterator_homework_one {
    public static void main(String[] args){
        ArrayList col = new ArrayList();
        col.add(new GratherDogs("小花",3));
        col.add(new GratherDogs("小白",1));
        col.add(new GratherDogs("小米",1));

        // 方式1: 使用while循环遍历
        // 遍历前要先声明好集合的iterator迭代器
        Iterator iterator = col.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println(next);
        }

        // 方式2: 使用for增强循环遍历
        for(Object obj : col){
            System.out.println(obj);
        }
    }
}
class GratherDogs{
    private String name;
    private int age;    // 私有属性

    // 构造器
    public GratherDogs(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // get方法可拿到数据
    public String getName() {
        return name;
    }
    // set方法可放入数据
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    // toString 返回数据
    @Override
    public String toString() {
        return "宠物" + name +", 今年" + age + "岁";
    }
}

List

package chap01;
import java.util.ArrayList;
import java.util.Iterator;

/*
    添加10个以上的元素(比如String "hello"),在2号位插入一个元素"学完Java",
    获得第5个元素,删除第6个元素,修改第7个元素,在使用迭代器遍历集合
*/
public class Grather_list_homework_one {
    public static void main(String[] args){
        ArrayList col = new ArrayList();
        for(int i = 0; i < 12; i++){
            col.add("hello" + i);
        }
        System.out.println(col);

        // 1. 在2号位插入元素
        col.add(1,"学完Java");    // 索引从0开始,所以2号位为1
        System.out.println(col);
        // 2. 获取第5个元素
        System.out.println(col.get(4));
        // 3. 删除第6个元素
        col.remove(5);
        System.out.println(col);
        // 4. 修改第7个元素
        col.set(6,"学好Java");
        System.out.println(col);

        Iterator iterator = col.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.print("\t" + next);
        }
    }
}


// 如果考虑线程安全,就使用Vector
/*
    如何选择ArrayList和LinkedList?
    1) 如果我们改查的操作多,就使用ArrayList
    2) 如果我们增删的操作多,就使用LinkedList
    3) 在一个项目中,要根据不同的业务需求来选择ArrayList和LinkedList
*/
package chap01;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class Grather_list_homework_two {
    public static void main(String[] args){
        List list = new LinkedList();
        list.add(new GratherListBooks("三国演义","罗贯中",10.6));
        list.add(new GratherListBooks("红楼梦","曹雪芹",15.4));
        list.add(new GratherListBooks("活着","余华",7.8));
        list.add(new GratherListBooks("西游记","吴承恩",11.1));
        list.add(new GratherListBooks("水浒传","施耐庵",12.1));

        // 排序
        sort(list);
        // 遍历输出
        for(Object obj : list){
            System.out.println(obj);
        }
    }
    // 静态方法, 要求价格从小到大
    public static void sort(List list){
        int listSize = list.size();
        for(int i = 0; i < listSize - 1; i++){
            for(int j = 0; j < listSize -1-i; j++){
                // 取出对象
                GratherListBooks book1 = (GratherListBooks) list.get(j);
                GratherListBooks book2 = (GratherListBooks) list.get(j + 1);
                if(book1.getPrice() > book2.getPrice()){
                    list.set(j,book2);
                    list.set(j+1,book1);    // 两者交换
                }
            }
        }
    }
}
class GratherListBooks{
    private String name;
    private String author;
    private double price;

    public GratherListBooks(String name, String author, double price) {
        this.name = name;
        this.author = author;
        this.price = price;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "书名 = " + name + ", 作者是" + author + ", 价格为"  + price ;
    }
}

Map

package chap01;

/*
    1) Map中的key和value可以是任何引用类型的数据,会封装到HashMap$Node对象中
    2) Map和Collection并列存在,用于保存具有映射关系的数据: Key-Value
    3) Map中的key不允许重复
    4) Map中的value允许重复
    5) Map中的key可以为null,value也可以为null,但只能有一个key为null,可以有多个value为null
    6) key和value之间存在单向一对一关系,即通过指定的key总能找到对应的value
*/

import java.util.*;

public class Grather_Map {
    public static void main (String[] args){
        /* Map的演示 */
        Map map = new HashMap();
        map.put("no1","学Java"); // key - value
        map.put("no2","学JavaScript");
        map.put(1,"张三");
        // 通过传入key,会返回对应的value
        System.out.println(map.get("no1"));

        map.put("邓超",new GratherMapBooks("",100));  // OK
        map.put("邓超","孙俪"); // 替换

        // remove: 根据键删除映射关系
        map.remove(null);
        System.out.println("map=" + map);
        // get: 根据键获取值
        Object val = map.get("鹿晗");
        System.out.println("val=" + val);
        // size: 获取元素个数
        System.out.println("k-v=" + map.size());
        // isEmpty: 判断个数是否为 0
        System.out.println(map.isEmpty()); // false
        // map.clear(): 清除 key - value
        System.out.println("map=" + map);

        // containsKey(): 查找键是否存在
        System.out.println("结果=" + map.containsKey("hsp")); // true
        // keySet(): 获取所有的键
        // entrySet(): 获取所有的关系 key - value
        // values(): 获取所有的值

        /* Map遍历的方式 */
        map.put("邓超", "孙俪");
        map.put("王宝强", "马蓉");
        map.put("宋喆", "马蓉");
        map.put("刘令博", null);
        map.put(null, "刘亦菲");
        map.put("鹿晗", "关晓彤");
        // 1 第一组: 先取出 所有的 Key , 通过 Key 取出对应的 Value
        Set keyset = map.keySet();
        // 第一种取出key的方式: for增强循环
        for(Object key : keyset){
            System.out.println(key + "-" + map.get(key));
        }
        // 第二种取出key的方式: 迭代器
        Iterator iterator = keyset.iterator();
        while (iterator.hasNext()) {
            Object key =  iterator.next();
            System.out.println(key + "-" + map.get(key));
        }

        // 2 第二组: 把所有的value取出
        Collection values = map.values();
        //这里可以使用所有的 Collections 使用的遍历方法
        // 第一种取出value的方式: for增强循环
        for(Object value : values){
            System.out.println(value);
        }
        // 第二种取出value的方式: 迭代器
        Iterator iterator2 = values.iterator();
        while (iterator2.hasNext()) {
            Object value =  iterator2.next();
            System.out.println(value);
        }

        // 3 第三组: 通过EntrySet来获取 key - value
        Set entrySet = map.entrySet();
        // (1) for循环
        for(Object entry : entrySet){
            // 将entry转为Map.Entry
            Map.Entry m = (Map.Entry)entry;
            System.out.println(m.getKey() + "-" + m.getKey());
        }
        // (2) 迭代器
        Iterator iterator3 = entrySet.iterator();
        while(iterator3.hasNext()){
            Object entry = iterator3.next();
            // 向下转型
            Map.Entry m = (Map.Entry) entry;
            System.out.println(m.getKey() + "-" + m.getValue());
        }

        /* Hashtable */
        // Hashtable的用法和Hashmap一致
        Hashtable table = new Hashtable();
        table.put("john",100);  // OK
        // table.put(null,200);   // hashtable的键和值都不能为null,否则会抛出NullPointException

        /* Map接口实现类Properties */
        // Properties还可以用于从xxx.properties文件中,加载数据到Properties类对象,并进行读取和修改
        Properties properties = new Properties();
        // properties.put(null,"abs"); // 抛出空指针异常
        properties.put("john",100); // key - value
        properties.put("lic", 100);
        properties.put("lic", 88);//如果有相同的 key , value 被替换
        //通过 k 获取对应值
        System.out.println(properties.get("lic"));//88
        //删除
        properties.remove("lic");
        System.out.println("properties=" + properties);
        //修改
        properties.put("john", "约翰");
        System.out.println("properties=" + properties);
    }
}
class GratherMapBooks{
    private String name;
    private int num;

    public GratherMapBooks(String name, int num) {
        this.name = name;
        this.num = num;
    }
}

/*
    HashMap小结:
    1) Map接口的常用类: HashMap\Hashtable\Proerties
    2) HashMap是Map接口使用频率最高的实现类
    3) HashMap是以key-val对的方式来存储数据
    4) key不能重复,但是值可以重复,允许使用null键和null值
    5) HashMap没有实现同步,因此线程是不安全的,方法没有做同步互斥的操作
*/

/*
    在开发中选择什么集合实现类,取决于业务操作特点,然后根据集合实现类特性进行选择
    1) 先判断存储的类型 (一组对象[单列]或者一组键值对[双列])
    2) 一组对象[单列]: Collection接口
       允许重复:List
              增删多: LinkdList [底层维护了一个双向链表]
              改查多: ArrayList [底层维护Object类型的可变数组]
       不允许重复:Set
              无序: HashSet [底层是HashMap,维护了哈希表,即(数组+链表+红黑树)]
              排序: TreeSet
              插入和取出的顺序一致: LinkdeHashSet
    3) 一组键值对[双列]: Map
       键无序: HashMap
       键排序: TreeMap
       键插入和取出顺序一致: LinkedHashMap
       读取文件: Properties
*/

Map案例

package chap01;

// 使用HashMap添加3个员工对象 (要求key键为员工id,value值为员工对象)
// 并遍历显示工资>18000的员工 (遍历至少两种)
// 员工类: 姓名\工资\员工id

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class Grather_Map_homework_one {
    public static void main(String[] args){
        Map empMap = new HashMap(); // 创建hashmap对象
        empMap.put(1,new GratherMapEmployee("Roy",8000,1));  // 添加对象
        empMap.put(2,new GratherMapEmployee("Jack",20000,2));
        empMap.put(3,new GratherMapEmployee("Rose",19000,3));
        empMap.put(4,new GratherMapEmployee("Nancy",20000,4));

        // Map遍历
        Set keySet = empMap.keySet();
        // 第一种遍历方式: 使用keySet -> for循环
        for(Object key : keySet){
            GratherMapEmployee emp = (GratherMapEmployee)empMap.get(key);
            if(emp.getSalary() > 18000){
                System.out.println(emp);
            }
        }

        // 第二种遍历方式: 使用entry -> 迭代器
        Set entrySet = empMap.entrySet();
        Iterator iterator = entrySet.iterator();
        while(iterator.hasNext()){
            Map.Entry entry = (Map.Entry) iterator.next();   // 通过entry获取key和value
            GratherMapEmployee emp = (GratherMapEmployee) entry.getValue();
            if(emp.getSalary() > 18000){
                System.out.println(emp);
            }
        }
    }
}
class GratherMapEmployee{
    private String name;
    private double salary;
    private int id;

    public GratherMapEmployee(String name, double salary, int id) {
        this.name = name;
        this.salary = salary;
        this.id = id;
    }

    public String getName() {
        return name;
    }
    public double getSalary() {
        return salary;
    }
    public int getId() {
        return id;
    }

    @Override
    public String toString() {
        return "GratherMapEmployee{" +
                "name='" + name + '\'' +
                ", salary=" + salary +
                '}';
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java基础学习笔记 # 一、Java简介 Java是一种面向对象的编程语言,由Sun Microsystems(现在是Oracle)于1995年首次发布。它具有跨平台的特性,可以在不同的操作系统上运行。Java语言被广泛应用于开发各种类型的应用程序,包括桌面应用、Web应用、移动应用等。 # 二、Java基本语法 ## 1. 变量与数据类型 Java是强类型语言,每个变量必须先声明后使用。Java提供了多种数据类型,包括基本数据类型(整数、浮点数、字符、布尔值)和引用数据类型(类、接口、数组)。 ## 2. 运算符 Java提供了多种运算符,包括算术运算符、关系运算符、逻辑运算符等,用于进行各种数学或逻辑运算。 ## 3. 控制流程 Java提供了多种控制流程语句,包括条件语句(if-else语句、switch语句)、循环语句(for循环、while循环)、跳转语句(break语句、continue语句)等,用于控制程序的执行流程。 ## 4. 方法和类 Java中的方法用于封装一段可重复使用的代码,可以带有参数和返回值。类是Java程序的基本组织单位,包含了属性和方法。可以使用关键字class定义一个类,通过实例化类的对象来调用其方法。 # 三、面向对象编程 Java是一种面向对象的编程语言,面向对象编程的核心概念包括封装、继承和多态。 ## 1. 封装 封装是将数据和行为打包成一个类,通过访问修饰符(public、private等)控制对类的成员的访问权限。 ## 2. 继承 继承允许一个类继承另一个类的属性和方法,并且可以通过重写来修改或扩展继承的方法。 ## 3. 多态 多态允许通过父类类型的引用来引用子类对象,实现对不同子类对象的统一调用。 # 四、异常处理 Java提供了异常处理机制,用于处理程序中的错误情况。异常分为可检查异常(checked exception)和不可检查异常(unchecked exception),可以使用try-catch语句来捕获和处理异常。 # 五、Java标准库 Java标准库提供了大量的类和接口,用于完成各种常见的任务。其中包括输入输出、集合、多线程、网络编程等功能,可以大大简化开发过程。 以上是我学习Java基础笔记总结,希望对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值