Java基础

第一部分 Java基础语法

1.1 注释

注释是解释说明程序的问题,方便自己和别人阅读代码

分类:

1.单行注释:
    //后面根解释文字
2.多行注释
    /*
    这里写注释文字
    可以写多行
    */
3.文档注释
    /**
    这里写文档注释
    也可以写多行,文档注释可以利用JDK的工具生成帮助文档
    */

举例:

/**
目标:学会使用注释
     这是程序的讲解注释
*/
public class NoteDemo{
    //这是程序的主方法,是程序的入口
    public static void main(String[] args){
        System.out.println("我开始学习Java程序,好嗨皮~~");
        /*
        窗前明月光
        疑是地上霜
        举头望明月
        低头思故乡
        */
        System.out.println("播仔");
        System.out.println("deli");
    }
}

快捷键

Ctrl + /    单行注释(对当前行进行注释)
Ctrl + Shift + /    对选中的代码进行多行注释。

1.2 字面量

image-20231115151312354

举例:

/*
目标:需要同学们掌握常见数据在程序中的书写格式
*/
public class LiteralDemo{
    public static void main(String[] args){
        //1.整数
        System.out.println(666);
        //2.小数
        System.out.println(3.66);
        //3.字符: 字符必须用单引号引起来
        System.out.println('a');
        System.out.println('0');
        System.out.println('中');
        System.out.println(' '); //空格也算字符
        //特殊字符:\t表示制表符 \n表示换行
        System.out.println('\t'); //这相当于一个tab键,专业叫做制表符
        System.out.println('\n'); //这是换行的意思
        //4.字符串:字符串是双引号引起来的
        System.out.println("我爱你中国abc");
        //5.布尔值:只有两个值true和false
        System.out.println(true);
        System.out.println(false);
    }
}

1.3 变量

什么是变量:变量是用来记录程序中的数据的。其本质上是内存中的一块区域

image-20231115151455158

int age = 18;
System.out.println(a);

为什么用变量:使用变量来记录数据,对于数据的管理更为灵活

应用场景:只要是程序中能发生变化的数据,都可以用变量存储

注意事项:

1.变量定义在哪个{}范围内,就只在哪个大括号内有效。变量的有效范围称之为变量的作用域
    {
        int a = 10;
        System.out.println(a); //这是是对的
    }
    System.out.println(a); //这里会出错
2.在同一个作用域内,不能有两个同名的变量
    {
        int a = 10;
        int a = 20; //这里会出错
    }
3.变量没有初始化只,不能直接使用
    int a; //仅仅定义了变量,但是没有初始值
    System.out.println(a); //这里会出错
4.变量可以定义在同一行
    如:int a=10, b=20; //a和b都是int类型

1.4 关键字

定义:关键字是java语言中有特殊含义的单词。

abstract assert boolean break byte
case catch char class const
continue default do double else
enum extends final finally float
for goto if implements import
instanceof int interface long native
new package private protected public
return strictfp short static super
switch synchronized this throw throws
transient try void volatile while

1.5 标志符

强制要求:必须遵守,不遵守就会报错
    1.最好是字母、数字、下划线、$组成
    2.不能以数字开头
    3.不能是Java的关键字
建议遵守:按照下面的方式取名字会显得更加专业
    1.所有的名字要见名知意,便于自己和别人阅读
        举例: class Student{} //一看这个类就知道表示一个学生
              int age =10;    //一看这个变量就知道表示年龄
2.类名:首字母大写(大驼峰命名)
    举例: class Student{}
3.变量名:第二个单词开始首字母大写(小驼峰命名)
    举例: double money = 6.88;  
          double applePrice = 7.5; 

第二部分 数据类型,运算符

一、数据的表示详解

1.1 整数在计算机中存储

任何数据在计算机中都是以二进制表示的

计算机的最小存储单位计算机中最小的存储单位是字节(Byte),一个字节占8位(bit),也就是说即使这个数据不足8位也需要用8位来存储

1.2 字符在计算机中存储

把每一个字符编为一个整数,存储的是字符对应整数的二进制形式,一套字符和整数的对应关系表,叫做ASCII编码表

ASCII编码表中字符编码的规律:
    1.字符0对应48,后面的1,2,3,4...9 对应的十进制整数依次往后顺延
    2.字符a对应97,后面的b,c,d,e...z 对应的十进制整数依次往后顺延
    3.字符A对应65,后面的B,C,D,E...Z 对应的十进制整数依次往后顺延

1.3 图片视频在计算机中存储

任何一种颜色可以使用三原色来表示,简称RGB,其中R(红色),G(绿色),B(蓝色),而RGB中每一种颜色又用一个字节的整数来表示,最小值是0最大值是255

RGB(0,0,0)表示黑色
RGB(255,255,255)表示白色
RGB(255,0,0) 表示红色
RGB(255,255,0) 表示红色和绿色混合为黄色
RGB(255,0,255) 表示红色和蓝色混合为紫色

视频:视频和图片是一样的,把多张图片连续播放

声音:把声波在表示在一个坐标系上,然后在坐标系上取一些点,把这些点的坐标值以二进制的形式存储到计算机中

1.4 数据的其他表现形式

二进制转十进制,八进制,十六进制

System.out.pirntln('a'+1); //98
System.out.pirntln(0b01100001); //97
System.out.pirntln(0141); //97
System.out.pirntln(0x61); //97

二、数据类型详解

数据类型是用来规定变量存储什么类型的数据

数据类型整体上来说分为两大类: 基本数据类型引用数据类型

image-20231115153711929

举例:

public class TypeDemo1 {
    public static void main(String[] args) {
        // 目标:掌握8种基本数据类型,用来定义变量。
        // 1、整型
        byte number = 98;
        System.out.println(number);
        short number2 = 9000;
        int number3 = 12323232; // 默认
        // 注意:随便写一个整型字面量,默认是int类型的,73642422442424虽然没有超过long的范围,但是它超过了本身int的范围了。
        // 如果希望随便写一个整型字面量是long类型的,需要在其后面加上L/l
        long number4 = 73642422442424L;
        // 2、浮点型
        //注意:
        //随便写一个小数字面量,默认当成double类型对待的,
        //如果希望这个小数是float类型的,需要在后面加上:F/f
        float score1 = 99.5F;
        double score2 = 99.8; // 默认定义方案。
        // 3、字符型
        char ch1 = 'a';
        char ch2 = '中';
        char ch3 = '国';
        // 4、布尔型
        boolean b1 = true;
        boolean b2 = false;
        // 引用数据类型:String.
        // String代表的是字符串类型,定义的变量可以用来记住字符串。
        String name = "黑马";
        System.out.println(name);
    }
}

三、数据类型转换

3.1 自动类型转换

数据范围小的变量可以直接赋值给数据范围大的变量

byte a = 12; 
    int b = a; //这里就发生了自动类型转换(把byte类型转换int类型)

原理:在较小数据类型数据前面,补了若干个字节

image-20231115153916659

转换顺序:

image-20231115153938006

举例:

public class TypeConversionDemo1 {
    public static void main(String[] args) {
        // 目标:理解自动类型转换机制。
        byte a = 12;
        int b = a; // 发生了自动类型转换了
        System.out.println(a);
        System.out.println(b);

        int c = 100; // 4
        double d = c;// 8 发生了自动类型转换了
        System.out.println(d);

        char ch = 'a'; // 'a' 97 => 00000000 01100001
        int i = ch; // 发生了自动类型转换了 =>  00000000 00000000  00000000 01100001
        System.out.println(i);
    }
}

表达式的自动类型转换:

多种数据类型参与运算,其结果以大的数据类型为准

byte,short,char 三种类型数据在和其他类型数据运算时,都会转换为int类型再运算

public class TypeConversionDemo2 {
    public static void main(String[] args) {
        // 目标:掌握表达式的自动类型转换机制。
        byte a = 10;
        int b = 20;
        long c = 30;
        long rs = a + b + c;
        System.out.println(rs);
        double rs2 = a + b + 1.0;
        System.out.println(rs2);
        byte i = 10;
        short j = 30;
        int rs3 = i + j;
        System.out.println(rs3);
        // 面试笔试题: 即使两个byte运算,结果也会提升为int
        byte b1 = 110;
        byte b2 = 80;
        int b3 = b1 + b2;
        System.out.println(b3);
    }
}

3.2 强制类型转换

格式:

目标数据类型  变量名  =  (目标数据类型)被转换的数据;

举例:

public class TypeConversionDemo3 {
    public static void main(String[] args) {
        // 目标:掌握强制类型转换。
        int a = 20;
        byte b = (byte) a;  // ALT + ENTER 强制类型转换。
        System.out.println(a);
        System.out.println(b);
        int i = 1500;
        byte j = (byte) i;
        System.out.println(j);   
        double d = 99.5;
        int m = (int) d; // 强制类型转换
        System.out.println(m); // 丢掉小数部分,保留整数部分
    }
}

原理:强行把前面几个字节砍掉,但是有数据丢失的风险

image-20231115155044317

四、运算符

4.1 算术运算符

/: 两个整数相除,结果也是一个整数
%: 表示两个数相除,取余数
public class OperatorDemo1 {
    public static void main(String[] args) {
        // 目标:掌握基本的算术运算符的使用。
        int a = 10;
        int b = 2;
        System.out.println(a + b);
        System.out.println(a - b);
        System.out.println(a * b); // 20
        System.out.println(a / b); // 5
        System.out.println(5 / 2); // 2.5 ==> 2
        System.out.println(5.0 / 2); // 2.5
        int i = 5;
        int j = 2;
        System.out.println(1.0 * i / j); // 2.5
        System.out.println(a % b); // 0
        System.out.println(3 % 2); // 1
        System.out.println("---------------------------------------");
        // 目标2:掌握使用+符号做连接符的情况。
        int a2 = 5;
        System.out.println("abc" + a2); // "abc5"
        System.out.println(a2 + 5); //  10
        System.out.println("itheima" + a2 + 'a'); // "itheima5a"
        System.out.println(a2 + 'a' + "itheima"); // 102itheima
    }
}

4.2 自增自减运算符

++读作自增,--读作自减

image-20231115155758328

自增自减只能对变量进行操作,不能操作字面量

举例:

1.单独使用:++或者--放在变量前面没有区别
       int a =10; 
        a++;  //11
        --a;  //10
        System.out.println(a); //10
2.混合使用:++或者--放在变量或者前面运算规则稍有不通过
    //++在后:先做其他事情,再做自增和自减
    int a = 10;
    int b = a++; //等价于 int b = a; a++; 
//++在前:先自增或者自减,再做其他运输
int x = 10;
int y = --x; //等价于x--; int y = x;

举例:

public class OperatorDemo2 {
    public static void main(String[] args) {
        // 目标:掌握自增自减运算符的使用。
        int a = 10;
        // a++; // a = a + 1
        ++a;
        System.out.println(a);
        // a--; // a = a - 1
        --a;
        System.out.println(a);
        // 自增自减只能操作变量不能操作字面量的,会报错!
        //System.out.println(2++);
        System.out.println("--------------------------------------");
        int i = 10;
        int rs = ++i; // 先加后用
        System.out.println(rs);
        System.out.println(i);
        int j = 10;
        int rs2 = j++; // 先用后加
        System.out.println(rs2);
        System.out.println(j);
    }
}

3.3 赋值运算符

image-20231115160643141

举例:

int a = 10;
//+=解析:在a原来记录值10的基础上累加5,将结果重新赋值给a; 
a+=5; 
//最终打印a的值为15
System.out.println(a); 

举例:

public class OperatorDemo3 {
    public static void main(String[] args) {
        // 目标:掌握扩展赋值运算符的使用。
        // +=
        // 需求:收红包
        double a = 9.5;
        double b = 520;
        a += b;  // a = (double)(a + b);
        System.out.println(a);
        // -= 需求:发红包
        double i = 600;
        double j = 520;
        i -= j;  // i = (double)(i - j);
        System.out.println(i); 
        int m = 10;
        int n = 5;
        // m *= n; // 等价形式: m = (int)(m * n)
        // m /= n; // 等价形式: m = (int)(m / n)
        m %= n;    // 等价形式: m = (int)(m % n)
        System.out.println(m);
    }
}

4.4 关系运算符

image-20231115161237832

举例:

public class OperatorDemo4 {
    public static void main(String[] args) {
        // 目标:掌握关系运算符的基本使用。
        int a = 10;
        int b = 5;
        boolean rs = a > b;
        System.out.println(rs);
        System.out.println(a >= b); // 要么a大于b,或者a等于b
        System.out.println(2 >= 2); // true
        System.out.println(a < b);
        System.out.println(a <= b); // false
        System.out.println(2 <= 2); // true
        System.out.println(a == b); // false
        System.out.println(5 == 5); // true  
        // 注意了:判断是否相等一定是用 == ,=是用来赋值的。
        // System.out.println(a = b); 
        System.out.println(a != b); // true
        System.out.println(10 != 10); // false  
        System.out.println(false ^ true ^ false);
    }
}

4.5 逻辑运算符

逻辑运算符是用来将多个条件放在一起运算,最终结果是true或者false

image-20231115161345439

4.6 三元运算符

格式:

关系表达式? 值1 : 值2;

举例:

public class OperatorDemo6 {
    public static void main(String[] args) {
        // 目标:掌握三元运算符的基本使用。
        double score = 58.5;
        String rs = score >= 60 ? "成绩及格" : "成绩不及格";
        System.out.println(rs);
        // 需求2:找出2个整数中的较大值,并输出。
        int a = 99;
        int b = 69;
        int max = a > b ? a : b;
        System.out.println(max); 
        // 需求3:找3个整数中的较大值。
        int i = 10;
        int j = 45;
        int k = 34; 
        // 找出2个整数中的较大值。
        int temp = i > j ? i : j;
        // 找出temp与k中的较大值。
        int max2 = temp > k ? temp : k;
        System.out.println(max2);
    }
}

4.7 运算优先级

image-20231115161604690

五、获取用户键盘输入分数据

public class ScannerDemo1 {
    public static void main(String[] args) {
        // 1、导包:一般不需要我们自己做,idea工具会自动帮助我们 导包的。
        // 2、抄写代码:得到一个键盘扫描器对象(东西)
        Scanner sc = new Scanner(System.in);
        // 3、开始 调用sc的功能,来接收用户键盘输入的数据。
        System.out.println("请您输入您的年龄:");
        int age = sc.nextInt(); // 执行到这儿,会开始等待用户输入一个整数,直到用户按了回车键,才会拿到数据。
        System.out.println("您的年龄是:"  + age);

        System.out.println("请您输入您的名字:");
        String name = sc.next(); // 执行到这儿,会开始等待用户输入一个字符串,直到用户按了回车键,才会拿到数据。
        System.out.println(name + "欢迎您进入系统~~");
    }
}

第三部分 程序流程控制

程序的流程控制一般分为3种:顺序结构、分支结构、循环结构

  • 顺序结构:就是不加任何控制,代码从main方法开始自上而下执行
  • 分支结构:就是根据条件判断是true还是false,有选择性的执行哪些代码。在Java语言中提供了两个格式if 、 switch
  • 循环结构:就是控制某一段代码重复执行。在Java语言中提供了三种格式,for、while、do-while

image-20231115161835977

一、分支结构

1.1 if分支

1. 场景

2. 格式

image-20231115162152944

3. 第一种格式

// 需求:测量用户体温,发现体温高于37度就报警。
double t = 36.9;
if(t > 37){
    System.out.println("这个人的温度异常,把他赶紧带走~~");
}

4. 第二种格式

// 需求2:发红包,你的钱包余额是99元,现在要发出90元
// 如果钱够触发发红包的动作,如果钱不够,则提示:余额不足。
double money = 19;
if(money >= 90){
    System.out.println("发红包成功了~");
}else {
    System.out.println("余额不足~~");
}

5. 第三种格式

// 需求3:某个公司有一个绩效系统,根据员工的打分输出对应的绩效级别。[0,60) D  [60,80) C [80,90) B [90,100] A
int score = 298;
if(score >= 0 && score < 60) {
    System.out.println("您的绩效级别是: D");
}else if(score >= 60 && score < 80){
    System.out.println("您的绩效级别是: C");
}else if(score >= 80 && score < 90){
    System.out.println("您的绩效级别是: B");
}else if(score >= 90 && score <= 100){
    System.out.println("您的绩效级别是: A");
}else {
    System.out.println("您录入的分数有毛病~~");
}

1.2 switch分支

通过比较值来决定执行哪条分支代码

image-20231115162415143

String week = "周三";
switch (week){
    case "周一":
        System.out.println("埋头苦干,解决bug");
        break;
    case "周二":
        System.out.println("请求大牛程序员帮忙");
        break;
    case "周三":
        System.out.println("今晚啤酒、龙虾、小烧烤");
        break;
    case "周四":
        System.out.println("主动帮助新来的女程序解决bug");
        break;
    case "周五":
        System.out.println("今晚吃鸡");
        break;
    case "周六":
        System.out.println("与王婆介绍的小芳相亲");
        break;
    case "周日":
        System.out.println("郁郁寡欢、准备上班");
        break;
    default:
        System.out.println("您输入的星期信息不存在~~~");
}
  • 如果是对一个范围进行判断,建议使用if分支结构

  • 如果是与一个一个的值比较的时候,建议使用switch分支结构

1.3 注意事项

1)表达式类型只能是byte、short、int、char
JDK5开始支持枚举,JDK7开始支持String
不支持double、float、double

2)case给出的值不允许重复,且只能是字面量,不能是变量。

3)正常使用switch的时候,不要忘记写break,否则会出现穿透现象。

二、循环结构

2.1 for循环

//for循环格式:
for (初始化语句; 循环条件; 迭代语句) {
    循环体语句(重复执行的代码);
}
初始化语句:一般是定义一个变量,并给初始值
循环条件:一般是一个关系表达式,结果必须是true或者false
迭代语句:用于对条件进行控制,一般是自增或者自减
循环语句体:需要重复执行的代码

2.2 举例

2.2.1 求和

//2.需求:求1~100中所有整数的和
int sum = 0;
//定义一个循环,先产生1-100,这100个数
for (int i = 1; i <= 100; i++) {
    //每产生一个数据,就把这个数和sum累加
    sum += i; //sum = sum  + i;
}
System.out.println("1-100的数据和:" +  sum);

2.2.2 求奇数和

写法一:

//1)定义一个变量用于求和
int sum1 = 0;
//2)定义一个循环产生1-100之间的奇数
for (int i = 1; i < 100; i+=2) {
    // i = 1 3 5 7 ...
    //3)让需要求和的数据和sum1累加,
    sum1 += i;
}
System.out.println("1-100之间的奇数和:" +  sum1);

写法二:

//1)首先需要定义一个求和变量,这里命名为sum2
int sum2 = 0; 
//2)再遍历得到所有需要求和的数据(1~100之间的所有整数)
for (int i = 1; i <= 100; i++) {
    //i = 1 2 3 4 5 6 ... 99 100
    //3)在求和之前先对数据判断,如果是奇数,才和sum1累加;否则什么也不干
    if(i % 2 == 1){
        // i = 1 3 5 7 9 ... 99
        sum2 += i;
    }
}
System.out.println("1-100之间的奇数和:" + sum2);

2.3 while循环

image-20231115162939955

// 需求:打印5行Hello World
int i = 0;
while (i < 5) {
    // i = 0 1 2 3 4
    System.out.println("Hello World");
    i++;
}

2.3.1 举例

需求:世界最高山峰珠穆朗玛峰高度是:8848.86米=8848860毫米,假如我有一张足够大的它的厚度是0.1毫米。请问:该纸张折叠多少次,可以折成珠穆朗玛峰的高度?

// 1、定义变量记住珠穆朗玛峰的高度和纸张的高度。
double peakHeight = 8848860;
double paperThickness = 0.1;
// 3、定义一个变量count用于记住纸张折叠了多少次
int count = 0;
// 2、定义while循环控制纸张开始折叠
while (paperThickness < peakHeight) {
    // 把纸张进行折叠,把纸张的厚度变成原来的2倍。
    paperThickness = paperThickness * 2;
    count++;
}
System.out.println("需要折叠多少次:" + count);
System.out.println("最终纸张的厚度是:" + paperThickness);

2.4 do-while循环

image-20231115163053458

2.5 循环嵌套

需求:在控制台使用 * 打印出4行5列的矩形
    ****
    ****
    ****
    ****
//1)先写一个循环用来在一行中打印5个"*"
for (int j = 1; j <= 5; j++) {
    System.out.print("*"); // 不换行
}
System.out.println(); //换行
System.out.println("-----------------");
//2)再将第一步的代码套一层循环,执行4次,就可以打印4行
for (int i = 1; i <= 4; i++) {
    for (int j = 1; j <= 5; j++) {
        System.out.print("*"); // 不换行
    }
    System.out.println(); //换行
}

2.6 跳转语句 break、continue

break作用:跳出并结束当前所在循环的执行

continue作用:结束本次循环,进入下一次循环

三、生成随机数

3.1 产生随机数案例

// 目标:掌握使用Random生成随机数的步骤。
// 1、导包。import java.util.Random; (idea会自动完成)
import java.util.Random;
public class RandomDemo1 {
    public static void main(String[] args) {
        // 2、创建一个Random对象,用于生成随机数。
        Random r = new Random();
        // 3、调用Random提供的功能:nextInt得到随机数。
        for (int i = 1; i <= 20; i++) {
            int data = r.nextInt(10); // 0 - 9
            System.out.println(data);
        }
    }
}

3.2 猜数字小游戏

import java.util.Random;
import java.util.Scanner;
public class RandomTest2 {
    public static void main(String[] args) {
        // 1、随机产生一个1-100之间的数据,做为中奖号码。
        Random r = new Random();
        int luckNumber = r.nextInt(100) + 1;
        // 2、定义一个死循环,让用户不断的猜测数据
        Scanner sc = new Scanner(System.in);
        while (true) {
            // 提示用户猜测
            System.out.println("请您输入您猜测的数据:");
            int guessNumber = sc.nextInt();
            // 3、判断用户猜测的数字与幸运号码的大小情况
            if(guessNumber > luckNumber){
                System.out.println("您猜测的数字过大~~");
            }else if(guessNumber < luckNumber){
                System.out.println("您猜测的数字过小~~");
            }else {
                System.out.println("恭喜您,猜测成功了,可以买单了~~");
                break; // 结束死循环
            }
        }
    }
}

第四部分 数组

一、认识数组

数组就是一个容器,用来存一批同种类型的数据的

int[] array = {20,10,80,60,90};
String[] names = {"牛二", "西门", "全蛋"};

场景:遇到批量数据的存储和操作时,数组比变量更适合

二、数组的定义和访问

2.1 数组的静态初始化

标准格式:

数据类型[] 变量名 = new 数据类型[]{元素1,元素2,元素3};

举例:

//定义数组,用来存储多个年龄
int[] ages = new int[]{12, 24, 36}
//定义数组,用来存储多个成绩
double[] scores = new double[]{89.9, 99.5, 59.5, 88.0};

简化格式:

数据类型[] 变量名 = {元素1,元素2,元素3};

举例:

//定义数组,用来存储多个年龄
int[] ages = {12, 24, 36}
//定义数组,用来存储多个成绩
double[] scores = {89.9, 99.5, 59.5, 88.0};

另一种格式:

定义数组时, 数据类型[] 数组名 也可写成 数据类型 数组名[]

举例:

//以下两种写法是等价的。但是建议大家用第一种,因为这种写法更加普遍
int[] ages = {12, 24, 36};
int ages[] = {12, 24, 36}

存储原理:

image-20231115164054535

2.2 数组的元素访问

image-20231115164246360

//索引:      0   1   2
int[] arr = {12, 24, 36};
// 1、访问数组的全部数据
System.out.println(arr[0]); //12
System.out.println(arr[1]); //24
System.out.println(arr[2]); //36
//下面代码没有3索引,会出现ArrayIndexOutOfBoundsException 索引越界异常
//System.out.println(arr[3]); 
// 2、修改数组中的数据
arr[0] = 66;
arr[2] = 100;
System.out.println(arr[0]); //66
System.out.println(arr[1]); 0
System.out.println(arr[2]); //100

2.3 数组的遍历

int[] ages = {12, 24, 36};
for (int i = 0; i < ages.length; i++) {
    // i的取值 = 0,1,2
    System.out.println(ages[i]); 
}

2.4 举例

需求:某部门5名员工的销售额分别是:16、26、36、6、100,请计算出他们部门的总销售额。
需求分析:
    1.看到有16、26、36、6、100这5个数据数据,而且数据值很明确;
        1)想到,可以使用数组静态初始化把这5个数据存起来
2.请计算出他们部门的总销售额(这不就是求数组中数据的和吗?)
    2)必须先将数组中所有的元素遍历出来
    3)想要求和,得先有一个求和变量sum
    4)再将每一个元素和求和变量sum进行累加(求和思想)
// 1、定义一个数组存储5名员工的销售额
//索引          0   1    2  3   4
int[] money = {16, 26, 36, 6, 100};
// 3、定义一个变量用于累加求和
int sum = 0;
// 2、遍历这个数组中的每个数据。
for (int i = 0; i < money.length; i++) {
    // i = 0  1  2  3  4
    sum += money[i];
}
System.out.println("员工的销售总额:" + sum);

2.5 数组的动态初始化

//数据类型[]  数组名 = new 数据类型[长度];
int[] arr = new int[3];

image-20231115164521740

使用动态初始化定义数组时,根据元素类型不同,默认值也有所不同

image-20231115164535979

2.6 举例

案例需求:
    某歌唱比赛,需要开发一个系统:可以录入6名评委的打分,录入完毕后立即输出平均分做
    选手得分
需求分析:
    1.需要录入6名评委的分数,可以用一个数组来保存。
       因为在评委没有录入分数之前,还不确定数组中应该存哪些数据。
       所以可以使用数组的动态初始化
    2.遍历数组中的每一个位置,并录入分数,将分数存入数组中
    3.遍历数组中的每一个元素,对元素求和
// 1、定义一个动态初始化的数组,负责后期存储6个评委的打分。
double[] scores = new double[6];
Scanner sc  = new Scanner(System.in);
// 2、遍历数组中的每个位置,录入评委的分数,存入到数组中去
for (int i = 0; i < scores.length; i++) {
    // i = 0 1 2 3 4 5
    System.out.println("请您输入当前第" + (i + 1) +"个评委的分数:");
    double score = sc.nextDouble();
    scores[i] = score;
}
// 3、遍历数组中的每个元素进行求和
double sum  = 0;
for (int i = 0; i < scores.length; i++) {
    sum += scores[i];
}
System.out.println("选手最终得分是:" + sum / scores.length);

三、数组在计算机中的执行原理

3.1 数组的执行原理,Java程序的执行原理

Java为了便于虚拟机执行Java程序,将虚拟机的内存划分为 方法区、栈、堆、本地方法栈、寄存器 这5块区域。同学们需要重点关注的是 方法区、栈、堆

  • 方法区:字节码文件先加载到这里
  • :方法运行时所进入的内存区域,由于变量在方法中,所以变量也在这一块区域中
  • :存储new出来的东西,并分配地址。由于数组是new 出来的,所以数组也在这块区域。

image-20231115164944530

总结一下int a = 10int[] arr = new int[]{11,22,33}的区别

  • a是一个变量,在栈内存中,a变量中存储的数据就是10这个值。
  • arr也是一个变量,在栈中,存储的是数组对象在堆内存中的地址值
// 这里的int a是一个基本类型变量,存储的是一个数值
int a = 10 ; 
//这里的int[] arr是一个引用类型的变量,存储的是一个地址值
int[] arr = new int[]{44,55,66};

3.2 多个变量指向同一个数组

两个变量指向同一个数组时,两个变量记录的是同一个地址值。

当一个变量修改数组中的元素时,另一个变量去访问数组中的元素,元素已经被修改过了。

四、数组练习

4.1 数组求最值

数组求最大值思路:
    1)先找出数组中0索引的元素,假设为最大值,用max表示【擂主】
    2)遍历后面的每一个元素和max比较,把较大的元素值重新赋值给max(擂主换人)
    3)最后max就是所有元素的最大值(最后站在台上的擂主)
public class Test1 {
    public static void main(String[] args) {
        // 1、把颜值数据拿到程序中来,用数组装起来
        int[] faceScores = {15, 9000, 10000, 20000, 9500, -5};
        // 2、定义一个变量用于最终记住最大值。
        int max = faceScores[0];
        // 3、从数组的第二个位置开始遍历。
        for (int i = 1; i < faceScores.length; i++) {
            // i = 1  2  3  4  5
            // 判断一下当前遍历的这个数据,是否大于最大值变量max存储的数据,
            //如果大于,当前遍历的数据需要赋值给max
            if(faceScores[i] > max ){
                max = faceScores[i];
            }
        }
        System.out.println("最高颜值是:" + max);
    }
}

4.2 数组元素反转

需求:某个数组有5个数据:10,20,30,40,50,请将这个数组中的数据进行反转。
      [10, 20, 30, 40, 50]  反转后 [50, 40, 30, 20, 10]
public class Test2 {
    public static void main(String[] args) {
        // 目标:完成数组反转。
        // 1、准备一个数组
        int[] arr = {10, 20, 30, 40, 50};  
        // 2、定义一个循环,设计2个变量,一个在前,一个在后
        for (int i = 0, j = arr.length - 1; i < j; i++, j--) {
            // arr[i]   arr[j]
            // 交换
            // 1、定义一个临时变量记住后一个位置处的值
            int temp = arr[j];
            // 2、把前一个位置处的值赋值给后一个位置了
            arr[j] = arr[i];
            // 3、把临时变量中记住的后一个位置处的值赋值给前一个位置处
            arr[i] = temp;
        }
        // 3、遍历数组中的每个数据,看是否反转成功了
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
}

4.3 随机排名

需求:某公司开发部5名开发人员,要进行项目进展汇报演讲,现在采取随机排名后进行汇报。请先依次录入5名员工的工号,然后展示出一组随机的排名顺序。
public class Test3 {
    public static void main(String[] args) {
        // 目标:完成随机排名
        // 1、定义一个动态初始化的数组用于存储5名员工的工号
        int[] codes = new int[5];
        // 2、提示用户录入5名员工的工号。
        Scanner sc = new Scanner(System.in);
        for (int i = 0; i < codes.length; i++) {
            // i = 0 1 2 3 4
            System.out.println("请您输入第" + (i + 1) +"个员工的工号:");
            int code = sc.nextInt();
            codes[i] = code;
        }
        // 3、打乱数组中的元素顺序。
        // [12, 33, 54, 26, 8]
        //  i       index
        Random r =  new Random();
        for (int i = 0; i < codes.length; i++) {
            // codes[i]
            // 每遍历到一个数据,都随机一个数组索引范围内的值。
            //然后让当前遍历的数据与该索引位置处的值交换。
            int index = r.nextInt(codes.length); // 0 - 4
            // 定义一个临时变量记住index位置处的值
            int temp = codes[index];
            // 把i位置处的值赋值给index位置处
            codes[index] = codes[i];
            // 把index位置原来的值赋值给i位置处
            codes[i] = temp;
        }
        // 4、遍历数组中的工号输出即可
        for (int i = 0; i < codes.length; i++) {
            System.out.print(codes[i] + " ");
        }
    }
}

第五部分 方法

一、方法概述

1.1 什么是方法

方法是一种语法结构,它可以把一段代码封装成一个功能,以便重复调用

image-20231115171857575

//目标:掌握定义方法的完整格式,搞清楚使用方法的好处。
public class MethodDemo1 {
    public static void main(String[] args) {
        // 需求:假如现在很多程序员都要进行2个整数求和的操作。
        // 1、李工。
        int rs = sum(10, 20);
        System.out.println("和是:" + rs);
        // 2、张工。
        int rs2 = sum(30, 20);
        System.out.println("和是:" + rs2);
    }
    public static int sum(int a,int b) {
        int c = a + b;
        return c;
    }
}

1.2 方法的执行流程

当调用一个方法时,执行流程,按照下图中标注的序号执行。

​ ① 通过sum方法名找到sum方法

​ ② 把10传递给方法中的参数a

​ ③ 把20传递给方法中的参数b;

​ ④ 执行方法中的代码,此时int c=a+b;; 相当于 int c = 10+20; c的值为30

1.3 定义方法的注意点

image-20231115172421393

方法的修饰符:暂时都使用public static 修饰。(目前看做是固定写法,后面是可以改动的)

方法申明了具体的返回值类型,内部必须使用return返回对应类型的数据。

形参列表可以有多个,甚至可以没有; 如果有多个形参,多个形参必须用“,”隔开,且不能给初始化值。

1.4 使用方法的好处

提高了代码的复用性,提高了开发效率。

让程序的逻辑更清晰。

二、方法的其他形式

重点关注下面两点:

  • 方法是否需要接收处理数据
  • 方法是否需要返回数据

image-20231115172935039

1)如果方法不需要返回数据,返回值类型必须申明成void(无返回值申明), 此时方法内部不可以使用return返回数据。

2)方法如果不需要接收外部传递进来的数据,则不需要定义形参,且调用方法时也不可以传数据给方法。

3)没有参数,且没有返回值类型(void)的方法,称为值无参数、无返回值方法。此时调用方法时不能传递数据给方法。

三、常见问题

1)方法在内种没有先后顺序,但是不能把一个方法定义在另一个方法中。

2)方法的返回值类型写void(无返回申明)时,方法内不能使用return返回数据,如果方法的返回值类型写了具体类型,方法内部则必须使用return返回对应类型的数据。

3)return语句的下面,不能编写代码,属于无效的代码,执行不到这儿。

4)方法不调用就不会执行, 调用方法时,传给方法的数据,必须严格匹配方法的参数情况。

5)调用有返回值的方法,有3种方式:
① 可以定义变量接收结果
② 或者直接输出调用,
③ 甚至直接调用;

6)调用无返回值的方法,只有1种方式: 只能直接调用。

四、举例

4.1 计算1-n的和

/*
分析:
    需要求1~n的和,由于n不确定是多少,所以就把n写成形式参数,n的具体值由调用者指定。
    在方法中把n当做一个确定的数据来使用就行。
*/
public static int add(int n){
    int sum = 0;
    for (int i = 1; i <= n; i++) {
        // i = 1 2 3 ... n
        sum += i;
    }
    return sum;
}

public static void main(String[] args) {
    int rs = add(5);
    System.out.println("1-5的和是:" + rs); //15
    int rs = add(6);
    System.out.println("1-6的和是:" + rs); //21
}

4.2 判断奇偶

/*
分析:
    需求中,是要判断一个数是奇数还是偶数,但是并没有明确说,是哪一个数。
    也就是说这个数可能是奇数,也可以能是偶数,是一个能够变化的数。
    把这个数写成方法的形式参数,就可以达到这个目的。因为调用方法时,调用者可以给传递     奇数,也可以传递偶数。
*/
public static void judge(int number){
    if(number % 2 == 0){
        System.out.println(number + "是一个偶数!");
    }else {
        System.out.println(number + "是一个奇数!");
    }
}

public static void main(String[] args) {
    judge(7); //调用后打印:7是一个奇数
    judge(8); //调用后打印:8是一个偶数
}

五、方法执行原理

每次调用方法,方法都会进栈执行;执行完后,又会弹栈出去

假设在main方法中依次调用A方法、B方法、C方法,在内存中的执行流程如下:

1)每次调用方法,方法都会从栈顶压栈执行没执行

2)每个方法执行完后,会从栈顶弹栈出去

image-20231116092255436

5.1 有返回值的内存分析

举例:

public class MethodDemo {
    public static void main(String[] args) {
        int rs = sum(10, 20);
        System.out.println(rs);
    }
    public static int sum(int a, int b ){
        int c = a + b; 
        return c;  
    }
}

image-20231116092439137

5.2 无返回值的内存分析

举例:

public class Demo2Method {
    public static void main(String[] args) {
        study();
    }
    public static void study(){
        eat();
        System.out.println("学习");
        sleep();
    }
    public static void eat(){
        System.out.println("吃饭");
    }

    public static void sleep(){
        System.out.println("睡觉");
    }
}

image-20231116092712389

1)方法的运行区域在哪里?
答:栈内存。
2)栈有什么特点?方法为什么要在栈中运行自己?
答:先进后出。保证一个方法调用完另一个方法后,可以回来继续执行。

六、方法参数的传递机制

Java的参数传递机制都是:值传递:在传递实参给方法的形参的时候,传递的是实参变量中存储的值的副本

6.1 参数传递的是基本类型数据

image-20231116110219508

6.2 参数传递的是引用数据类型

image-20231116144927960

实际上也是值传递,只不过参数传递存储的地址值

七、举例

7.1 举例

需求:输出一个int类型的数组内容,要求输出格式为:[11, 22, 33, 44, 55]。

public class MethodTest3 {
    public static void main(String[] args) {
        // 目标:完成打印int类型的数组内容。
        int[] arr = {10, 30, 50, 70};
        printArray(arr);

        int[] arr2 = null;
        printArray(arr2);

        int[] arr3 = {};
        printArray(arr3);
    }

    /*
        参数:int[] arr表示要被打印元素的数组,需要调用者传递
    */
    public static void printArray(int[] arr){
        if(arr == null){
            System.out.println(arr); // null
            return; // 跳出当前方法
        }

        System.out.print("[");
        // 直接遍历接到的数组元素
        for (int i = 0; i < arr.length; i++) {
            if(i == arr.length - 1){
                System.out.print(arr[i]);
            }else {
                System.out.print(arr[i] + ", ");
            }
        }
        System.out.println("]");
    }

}

7.2 举例

需求:比较两个int类型的数组是否一样,返回true或者false

public class MethodTest4 {
    public static void main(String[] args) {
        // 目标:完成判断两个int类型的数组是否一样。
        int[] arr1 = {10, 20, 30};
        int[] arr2 = {10, 20, 30};
        System.out.println(equals(arr1, arr2));
    }
    /*
        参数:
            int[] arr1, 参与比较的第一个int数组
            int[] arr2  参与比较的第二个int数组
        返回值:
            返回比较的结果true或者false
    */
    public static boolean equals(int[] arr1, int[] arr2){
        // 1、判断arr1和arr2是否都是null.
        if(arr1 == null && arr2 == null){
            return true; // 相等的
        }
        // 2、判断arr1是null,或者arr2是null.
        if(arr1 == null || arr2 == null) {
            return false; // 不相等
        }
        // 3、判断2个数组的长度是否一样,如果长度不一样,直接返回false.
        if(arr1.length != arr2.length){
            return false; // 不相等
        }
        // 4、两个数组的长度是一样的,接着比较它们的内容是否一样。
        // arr1 = [10, 20, 30]
        // arr2 = [10, 20, 30]
        for (int i = 0; i < arr1.length; i++) {
            // 判断当前位置2个数组的元素是否不一样,不一样直接返回false
            if(arr1[i] != arr2[i]){
                return false; // 不相等的
            }
        }
        return true; // 两个数组是一样的。
    }
}

八、方法重载

一个类中,出现多个相同的方法名,但是它们的形参列表是不同的,那么这些方法就称为方法重载

举例:

需求:开发武器系统,功能需求如下:
    可以默认发一枚武器。
    可以指定地区发射一枚武器。
    可以指定地区发射多枚武器。
public class MethodTest2 {
    public static void main(String[] args) {
        // 目标:掌握方法重载的应用场景。
        fire();
        fire("岛国2");
        fire("米国", 999);
    }
    public static void fire(){
        fire("岛国");
    }
    public static void fire(String country){
        fire(country, 1);
    }
    public static void fire(String country, int number){
        System.out.println("发射了" + number + "枚武器给" + country);
    }
}

总结:

1.什么是方法重载?
    答:一个类中,多个方法的名称相同,但它们形参列表不同。
2.方法重载需要注意什么?
    - 一个类中,只要一些方法的名称相同、形参列表不同,那么它们就是方法重载了,
      其它的都不管(如:修饰符,返回值类型是否一样都无所谓)。
    - 形参列表不同指的是:形参的个数、类型、顺序不同,不关心形参的名称。
3、方法重载有啥应用场景?
    答:开发中我们经常需要为处理一类业务,提供多种解决方案,此时用方法重载来设计是很专业的。

九、return单独使用

在方法中单独使用return语句,可以用来提前结束方法的执行

举例:

public class Test {
    public static void main(String[] args) {
        System.out.println("开始");
        chu(10 , 0);
        System.out.println("结束");
    }
    public static void chu(int a , int b){
        if(b == 0){
            System.err.println(“您的数据有误!!不执行!!”);
            return; // 直接跳出并结束当前chu方法的执行
        }
        int c = a / b;
        System.out.println("除法结果是:"+c); 
    }
}

第六部分 编程案例

第七部分 面向对象基础

一、面向对象入门

数据可以放在一起,组合成一个对象,然后让对象提供方法对自己的数据进行处理。这种方式称之为面向对象编程

所谓编写对象编程,就是把要处理的数据交给对象,让对象来处理

二、面向对象编程的好处

2.1 好处

面向对象的开发更符合人类的思维习惯,让编程变得更加简单、更加直观

2.2 对象是什么

对象实质上是一种特殊的数据结构,对象其实就是一张数据表,表当中记录什么数据,对象就处理什么数据

2.3 对象怎么出来的

用什么来设计这张表呢?就是类(class),类可以理解成对象的设计图,或者对象的模板

我们需要按照对象的设计图创造一个对象。设计图中规定有哪些数据,对象中就只能有哪些数据

对象可以理解成一张数据表,而数据表中可以有哪些数据,是由类来设计的

三、对象在计算机中的执行原理

其实Student s1 = new Student();这句话中的原理如下

  • Student s1表示的是在栈内存中,创建了一个Student类型的变量,变量名为s1

  • new Student()会在堆内存中创建一个对象,而对象中包含学生的属性名和属性值

  • 同时系统会为这个Student对象分配一个地址值0x4f3f5b24

  • 接着把对象的地址赋值给栈内存中的变量s1,通过s1记录的地址就可以找到这个对象

  • 当执行s1.name=“播妞”时,其实就是通过s1找到对象的地址,再通过对象找到对象的name属性,再给对象的name属性赋值为播妞;

image-20231117143040670

四、注意事项

image-20231117143213293

第一条:一个代码文件中,可以写多个class类,但是只能有一个是public修饰,且public修饰的类必须和文件名相同

假设文件名为Demo1.java,这个文件中假设有两个类Demo1类和Student类,代码如下

//public修饰的类Demo1,和文件名Demo1相同
public class Demo1{

}

class Student{

}

第二条:对象与对象之间的数据不会相互影响,但是多个变量指向同一个对象会相互影响。

s1和s2两个变量分别记录的是两个对象的地址值,各自修改各自属性值,是互不影响的

image-20231117143447129

s1和s2两个变量记录的是同一个对象的地址值,s1修改对象的属性值,再用s2访问这个属性,会发现已经被修改了

image-20231117143509146

五、this关键字

this就是一个变量,用在方法中,可以拿到当前类的对象

通过this在方法中可以访问本类对象的成员变量

image-20231117143710230

哪一个对象调用方法方法中的this就是哪一个对象

六、构造器

6.1 定义

构造器其实是一种特殊的方法,但是这个方法没有返回值类型,方法名必须和类名相同

6.2 特点

在创建对象时,会调用构造器。

也就是说 new Student()就是在执行构造器,当构造器执行完了,也就意味着对象创建成功。

image-20231117144236694

当执行new Student("播仔",99)创建对象时,就是在执行有参数构造器,当有参数构造器执行完,就意味着对象创建完毕了。

image-20231117144400394

new 对象就是在执行构造方法

6.3 应用场景

其实构造器就是用来创建对象的。可以在创建对象时给对象的属性做一些初始化操作

image-20231117144541102

6.4 注意事项

1.在设计一个类时,如果不写构造器,Java会自动生成一个无参数构造器。
2.一定定义了有参数构造器,Java就不再提供空参数构造器,此时建议自己加一个无参数构造器。

七、封装性

7.1 定义

用类设计对象处理某一个事物的数据时,应该把要处理的数据,以及处理数据的方法,都设计到一个对象中去

封装的设计规范用8个字总结,就是:合理隐藏、合理暴露

7.2 封装在代码中的体现

用到一个修饰符,叫private,被private修饰的变量或者方法,只能在本类中被访问

private double score; 就相当于把score变量封装在了Student对象的内部,且不对外暴露,你想要在其他类中访问score这个变量就,就不能直接访问了;

如果你想给Student对象的score属性赋值,得调用对外暴露的方法setScore(int score),在这个方法中可以对调用者传递过来的数据进行一些控制,更加安全。

image-20231117145322494

当你想获取socre变量的值时,就得调用对外暴露的另一个方法 getScore()

八、实体JavaBean

8.1 什么是实体类

一种特殊的类,它需要满足下面的要求

image-20231117145700038

按照要求,写一个Student实体类:

image-20231117145737935

8.2 应用场景

实体类仅仅只用来封装数据,而对数据的处理交给其他类来完成,以实现数据和数据业务处理相分离。如下图所示

image-20231117145928621

开发中,将类作为一种数据类型使用。如下图所示,在StudentOperator类中,定义一个Student类型的成员变量student,然后使用构造器给student成员变量赋值,然后在Student的printPass()方法中,使用student调用Student对象的方法,对Student对象的数据进行处理

image-20231117150131101

九、面向对象综合案例

需求:

  1. 想要展示系统中全部的电影信息(每部电影:编号、名称、价格)
  2. 允许用户根据电影的编号(id),查询出某个电影的详细信息。

image-20231117151922388

9.1 第一步:定义电影类

首先每一部电影,都包含这部电影的相关信息,比如:电影的编号(id)、电影的名称(name)、电影的价格(price)、电影的分数(score)、电影的导演(director)、电影的主演(actor)、电影的简介(info)。

为了去描述每一部电影,有哪些信息,我们可以设计一个电影类(Movie),电影类仅仅只是为了封装电影的信息,所以按照JavaBean类的标准写法来写就行

public class Movie {
    private int id;
    private String name;
    private double price;
    private double score;
    private String director;
    private String actor;
    private String info;

    public Movie() {
    }

    public Movie(int id, String name, double price, double score, String director, String actor, String info) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.score = score;
        this.director = director;
        this.actor = actor;
        this.info = info;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public double getScore() {
        return score;
    }

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

    public String getDirector() {
        return director;
    }

    public void setDirector(String director) {
        this.director = director;
    }

    public String getActor() {
        return actor;
    }

    public void setActor(String actor) {
        this.actor = actor;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

}

9.2 第二步:定义电影操作类

前面我们定义的Movie类,仅仅只是用来封装每一部电影的信息。为了让电影数据和电影数据的操作相分离,我们还得有一个电影操作类(MovieOperator)。

因为系统中有多部电影,所以电影操作类中MovieOperator,需要有一个Movie[] movies; 用来存储多部电影对象;

同时在MovieOperator类中,提供对外提供,对电影数组进行操作的方法。如printAllMovies()用于打印数组中所有的电影信息,searchMovieById(int id)方法根据id查找一个电影的信息并打印。

public class MovieOperator {
    //因为系统中有多部电影,所以电影操作类中,需要有一个Movie的数组
    private Movie[] movies;
    public MovieOperator(Movie[] movies){
        this.movies = movies;
    }

    /** 1、展示系统全部电影信息 movies = [m1, m2, m3, ...]*/
    public void printAllMovies(){
        System.out.println("-----系统全部电影信息如下:-------");
        for (int i = 0; i < movies.length; i++) {
            Movie m = movies[i];
            System.out.println("编号:" + m.getId());
            System.out.println("名称:" + m.getName());
            System.out.println("价格:" + m.getPrice());
            System.out.println("------------------------");
        }
    }

    /** 2、根据电影的编号查询出该电影的详细信息并展示 */
    public void searchMovieById(int id){
        for (int i = 0; i < movies.length; i++) {
            Movie m = movies[i];
            if(m.getId() == id){
                System.out.println("该电影详情如下:");
                System.out.println("编号:" + m.getId());
                System.out.println("名称:" + m.getName());
                System.out.println("价格:" + m.getPrice());
                System.out.println("得分:" + m.getScore());
                System.out.println("导演:" + m.getDirector());
                System.out.println("主演:" + m.getActor());
                System.out.println("其他信息:" + m.getInfo());
                return; // 已经找到了电影信息,没有必要再执行了
            }
        }
        System.out.println("没有该电影信息~");
    }

}

9.3 第三步:定义测试类

最后,我们需要在测试类中,准备好所有的电影数据,并用一个数组保存起来。每一部电影的数据可以封装成一个对象。然后把对象用数组存起来即可。

public class Test {
    public static void main(String[] args) {
        //创建一个Movie类型的数组
        Movie[] movies = new Movie[4];
        //创建4个电影对象,分别存储到movies数组中
        movies[0] = new Movie(1,"水门桥", 38.9, 9.8, "徐克", "吴京","12万人想看");
        movies[1] = new Movie(2, "出拳吧", 39, 7.8, "唐晓白", "田雨","3.5万人想看");
        movies[2] = new Movie(3,"月球陨落", 42, 7.9, "罗兰", "贝瑞","17.9万人想看");
        movies[3] = new Movie(4,"一点就到家", 35, 8.7, "许宏宇", "刘昊然","10.8万人想看");

    }

}

准备好测试数据之后,接下来就需要对电影数据进行操作。我们已经把对电影操作先关的功能写到了MovieOperator类中,所以接下来,创建MovieOperator类对象,调用方法就可以完成相关功能。

import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        //创建一个Movie类型的数组
        Movie[] movies = new Movie[4];
        //创建4个电影对象,分别存储到movies数组中
        movies[0] = new Movie(1,"水门桥", 38.9, 9.8, "徐克", "吴京","12万人想看");
        movies[1] = new Movie(2, "出拳吧", 39, 7.8, "唐晓白", "田雨","3.5万人想看");
        movies[2] = new Movie(3,"月球陨落", 42, 7.9, "罗兰", "贝瑞","17.9万人想看");
        movies[3] = new Movie(4,"一点就到家", 35, 8.7, "许宏宇", "刘昊然","10.8万人想看");
        MovieOperator operator = new MovieOperator(movies);
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("==电影信息系统==");
            System.out.println("1、查询全部电影信息");
            System.out.println("2、根据id查询某个电影的详细信息展示");
            System.out.println("请您输入操作命令:");
            int command = sc.nextInt();
            switch (command) {
                case 1:
                    // 展示全部电影信息
                    operator.printAllMovies();
                    break;
                case 2:
                    // 根据id查询某个电影的详细信息展示
                    System.out.println("请您输入查询的电影id:");
                    int id = sc.nextInt();
                    operator.searchMovieById(id);
                    break;
                default:
                    System.out.println("您输入的命令有问题~~");
            }
        }
    }

}

十、成员变量和局部变量

image-20231117152244738

成员变量在类中方法外,而局部变量在方法中

image-20231117152301169

面向对象的核心点就是封装,将数据和数据的处理方式,都封装到对象中; 至于对象要封装哪些数据?对数据进行怎样的处理? 需要通过类来设计

第八部分 Java常用API

一、API概述

API(全称是Application Program Interface 应用程序接口),说人话就是:**别人写好的一些程序,给咱们程序员直接拿去调用

比如String类,表示字符串,提供的方法全都是对字符串操作的。

比如ArrayList类,表示一个容器,提供的方法都是对容器中的数据进行操作的

二、包

包其实类似于文件夹,一个包中可以放多个类文件

格式:

//类文件的第一行定义包
package com.itheima.javabean;

public class 类名{

}

注意:

  • 要调用自己所在包下的其他程序,可以直接调用。(同一个包下的类,互相可以直接调用)

  • 要调用其他包下的程序,则必须在当前程序中导包, 才可以访问!

  • 导包格式: import 包名.类名

  • 要调用Java.lang包下的程序,不需要我们导包的,可以直接使用。

  • 要调用多个不同包下的程序,而这些程序名正好一样,此时默认只能导入一个程序,另一个程序必须带包名访问。

三、String类

3.1 概述

Java为了方便我们处理字符串,所以给我们提供了一个String类来代表字符串,这个类就是java.lang包下

按照面向对象的编程思想,对于字符串的操作,只需要创建字符串对象,用字符串对象封装字符串数据,然后调用String类的方法就可以了

3.2 String创建对象

方式一:

String s1 = "abc"; //这里"abc"就是一个字符串对象,用s1变量接收
String s2 = "黑马程序员"; //这里的“黑马程序员”也是一个字符串对象,用s2变量接收

方式二:用String类的构造方法创建String类的对象

image-20231117153057127

// 1、直接双引号得到字符串对象,封装字符串数据
String name = "黑马666";
System.out.println(name);

// 2、new String创建字符串对象,并调用构造器初始化字符串
String rs1 = new String();
System.out.println(rs1); // ""

String rs2 = new String("itheima");
System.out.println(rs2);

char[] chars = {'a', '黑', '马'};
String rs3 = new String(chars);
System.out.println(rs3);

byte[] bytes = {97, 98, 99};
String rs4 = new String(bytes);
System.out.println(rs4);

3.3 String类的常用方法

image-20231117153750563

举例:

public class StringDemo2 {
    public static void main(String[] args) {
        //目标:快速熟悉String提供的处理字符串的常用方法。
        String s = "黑马Java";
        // 1、获取字符串的长度
        System.out.println(s.length());

        // 2、提取字符串中某个索引位置处的字符
        char c = s.charAt(1);
        System.out.println(c);

        // 字符串的遍历
        for (int i = 0; i < s.length(); i++) {
            // i = 0 1 2 3 4 5
            char ch = s.charAt(i);
            System.out.println(ch);
        }

        System.out.println("-------------------");

        // 3、把字符串转换成字符数组,再进行遍历
        char[] chars = s.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            System.out.println(chars[i]);
        }

        // 4、判断字符串内容,内容一样就返回true
        String s1 = new String("黑马");
        String s2 = new String("黑马");
        System.out.println(s1 == s2); // false
        System.out.println(s1.equals(s2)); // true

        // 5、忽略大小写比较字符串内容
        String c1 = "34AeFG";
        String c2 = "34aEfg";
        System.out.println(c1.equals(c2)); // false
        System.out.println(c1.equalsIgnoreCase(c2)); // true

        // 6、截取字符串内容 (包前不包后的)
        String s3 = "Java是最好的编程语言之一";
        String rs = s3.substring(0, 8);
        System.out.println(rs);

        // 7、从当前索引位置一直截取到字符串的末尾
        String rs2 = s3.substring(5);
        System.out.println(rs2);

        // 8、把字符串中的某个内容替换成新内容,并返回新的字符串对象给我们
        String info = "这个电影简直是个垃圾,垃圾电影!!";
        String rs3 = info.replace("垃圾", "**");
        System.out.println(rs3);

        // 9、判断字符串中是否包含某个关键字
        String info2 = "Java是最好的编程语言之一,我爱Java,Java不爱我!";
        System.out.println(info2.contains("Java"));
        System.out.println(info2.contains("java"));
        System.out.println(info2.contains("Java2"));

        // 10、判断字符串是否以某个字符串开头。
        String rs4 = "张三丰";
        System.out.println(rs4.startsWith("张"));
        System.out.println(rs4.startsWith("张三"));
        System.out.println(rs4.startsWith("张三2"));

        // 11、把字符串按照某个指定内容分割成多个字符串,放到一个字符串数组中返回给我们
        String rs5 = "张无忌,周芷若,殷素素,赵敏";
        String[] names = rs5.split(",");
        for (int i = 0; i < names.length; i++) {
            System.out.println(names[i]);
        }
    }

}

3.4 注意事项

3.4.1 事项一

String类的对象是不可变的对象

只要是以“”方式写出的字符串对象,会在堆内存中的字符串常量池中存储

执行第一句话时,会在堆内存的常量池中,创建一个字符串对象“黑马”,然后把“黑马”的地址赋值给String name

image-20231117154602561
当执行第二句话时,又会再堆内存的常量池中创建一个字符串“程序员”,和“黑马”拼接,拼接之后还会产生一个新的字符串对象”黑马程序员“,然后将新产生的“黑马程序员”对象的地址赋值给String name变量。

image-20231117154640050

创建的字符串对象“黑马”内容确实是没有改变的。所以说String的对象是不可变的

3.4.2 事项二

字符串字面量和new出来字符串的区别

只要是以“...”方式写出的字符串对象,会存储到字符串常量池,且相同内容的字符串只存储一份。

image-20231117155046037

但通过new方式创建字符串对象,每new一次都会产生一个新的对象放在堆内存中。

image-20231117155052049

3.5 String案例一:用户登录

需求:

1.首先,从登录界面上可以得出,需要让用户输入登录名和密码
2.设计一个登录方法,对用户名和密码进行校验
3.调用登录方法,根据方法的返回结果,判断登录是否成功。
4.如果登录失败,循环登录3次,结束循环;如果登录成功,跳出循环;
/**
   目标:完成用户的登录案例。
 */
public class StringTest4 {
    public static void main(String[] args) {
        // 1、开发一个登录界面
        for (int i = 0; i < 3; i++) {
            Scanner sc = new Scanner(System.in);
            System.out.println("请您输入登录名称:");
            String loginName = sc.next();
            System.out.println("请您输入登录密码:");
            String passWord = sc.next();

            // 5、开始调用登录方法,判断是否登录成功
            boolean rs = login(loginName, passWord);
            if(rs){
                System.out.println("恭喜您,欢迎进入系统~~");
                break; // 跳出for循环,代表登录完成
            }else {
                System.out.println("登录名或者密码错误,请您确认~~");
            }
        }
    }

    /**
      2、开发一个登录方法,接收用户的登录名和密码,返回认证的结果
     */
    public static boolean login(String loginName, String passWord){
        // 3、准备一份系统正确的登录名和密码
        String okLoginName = "itheima";
        String okPassWord = "123456";

        // 4、开始正式判断用户是否登录成功
        /*if(okLoginName.equals(loginName) && okPassWord.equals(passWord)){
            // 登录成功的
            return true;
        }else {
            return false;
        }*/
        return okLoginName.equals(loginName) && okPassWord.equals(passWord);
    }

}

3.6 String案例二:随机产生验证码

根据需求分析,步骤如下:
    1.首先,设计一个方法,该方法接收一个整型参数,最终要返回对应位数的随机验证码。
    2.方法内定义2个字符串变量:
        1个用来记住生成的验证码,1个用来记住要用到的全部字符。
    3.定义for循环控制生成多少位随机字符
    4.每次得到一个字符范围内的随机索引
    5.根据索引提取该字符,把该字符交给code变量连接起
    6.循环结束后,在循环外返回code即可。
    7.在主方法中调用生成验证码的方法
import java.util.Random;
/**
    目标:完成随机产生验证码,验证码的每位可能是数字、大写字母、小写字母
 */
public class StringTest5 {
    public static void main(String[] args) {
        System.out.println(createCode(4));
        System.out.println(createCode(6));
    }
    /**
       1、设计一个方法,返回指定位数的验证码
     */
    public static String createCode(int n){
        // 2、定义2个变量 
        //一个是记住最终产生的随机验证码 
        //一个是记住可能用到的全部字符
        String code = "";
        String data = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

        Random r = new Random();
        // 3、开始定义一个循环产生每位随机字符
        for (int i = 0; i < n; i++) {
            // 4、随机一个字符范围内的索引。
            int index = r.nextInt(data.length());
            // 5、根据索引去全部字符中提取该字符
            code += data.charAt(index); // code = code + 字符
        }
        // 6、返回code即可
        return code;
    }

}

遇到对字符串进行操作的需求,优先找String类有没有提供对应的方法

四、ArrayList类

4.1 概述

ArrayList表示一种集合,它是一个容器,用来装数据的,类似于数组

而集合是大小可变的,想要存储几个元素就存储几个元素,在实际工作中用得更多。集合有很多种,而ArrayList只是众多集合中的一种

image-20231117160239969

image-20231117160251886

4.2 常用方法

第一步:创建ArrayList容器对象。一般使用空参数构造方法;

第二步:调用ArrayList类的常用方法对容器中的数据进行操作。常用方法如下

image-20231117160415206

举例:

/**
目标:要求同学们掌握如何创建ArrayList集合的对象,并熟悉ArrayList提供的常用方法。
 */
public class ArrayListDemo1 {
    public static void main(String[] args) {
        // 1、创建一个ArrayList的集合对象
        // ArrayList<String> list = new ArrayList<String>();
        // 从jdk 1.7开始才支持的
        ArrayList<String> list = new ArrayList<>();

        list.add("黑马");
        list.add("黑马");
        list.add("Java");
        System.out.println(list);

        // 2、往集合中的某个索引位置处添加一个数据
        list.add(1, "MySQL");
        System.out.println(list);

        // 3、根据索引获取集合中某个索引位置处的值
        String rs = list.get(1);
        System.out.println(rs);

        // 4、获取集合的大小(返回集合中存储的元素个数)
        System.out.println(list.size());

        // 5、根据索引删除集合中的某个元素值,会返回被删除的元素值给我们
        System.out.println(list.remove(1));
        System.out.println(list);

        // 6、直接删除某个元素值,删除成功会返回true,反之
        System.out.println(list.remove("Java"));
        System.out.println(list);

        list.add(1, "html");
        System.out.println(list);

        // 默认删除的是第一次出现的这个黑马的数据的
        System.out.println(list.remove("黑马"));
        System.out.println(list);

        // 7、修改某个索引位置处的数据,修改后会返回原来的值给我们
        System.out.println(list.set(1, "黑马程序员"));
        System.out.println(list);
    }

}

4.3 案例一:从容器中找出数据并删除

1.用户可以选购多个商品,可以创建一个ArrayList集合,存储这些商品
2.按照需求,如果用户选择了"枸杞"批量删除,应该删除包含"枸杞"的所有元素
    1)这时应该遍历集合中每一个String类型的元素
    2)使用String类的方法contains判断字符串中是否包含"枸杞"
    3)包含就把元素删除
3.输出集合中的元素,看是否包含"枸杞"的元素全部删除
import java.util.ArrayList;

public class ArrayListTest2 {
    public static void main(String[] args) {
        // 1、创建一个ArrayList集合对象
        ArrayList<String> list = new ArrayList<>();
        list.add("枸杞");
        list.add("Java入门");
        list.add("宁夏枸杞");
        list.add("黑枸杞");
        list.add("人字拖");
        list.add("特级枸杞");
        list.add("枸杞子");
        System.out.println(list);
        //运行结果如下: [Java入门, 宁夏枸杞, 黑枸杞, 人字拖, 特级枸杞, 枸杞子]

        // 2、开始完成需求:从集合中找出包含枸杞的数据并删除它
        for (int i = list.size() - 1; i >= 0; i--) {
            // 取出当前遍历到的数据
            String ele = list.get(i);
            // 判断这个数据中包含枸杞
            if(ele.contains("枸杞")){
                // 直接从集合中删除该数据
                list.remove(ele);
            }
        }
        System.out.println(list);
        //删除后结果如下:[Java入门, 黑枸杞, 人字拖, 枸杞子]
    }
}

4.4 案例二:集合中存储自定义对象

分析需求发现:

在外卖系统中,每一份菜都包含,菜品的名称、菜品的原价、菜品的优惠价、菜品的其他信息。那我们就可以定义一个菜品类(Food类),用来描述每一个菜品对象要封装那些数据。

接着再写一个菜品管理类(FoodManager类),提供展示操作界面、上架菜品、浏览菜品的功能。

首先我们先定义一个菜品类(Food类),用来描述每一个菜品对象要封装那些数据。

public class Food {
    private String name;    //菜品名称
    private double originalPrice; //菜品原价
    private double specialPrice; //菜品优惠价
    private String info; //菜品其他信息

    public Food() {
    }

    public Food(String name, double originalPrice, double specialPrice, String info) {
        this.name = name;
        this.originalPrice = originalPrice;
        this.specialPrice = specialPrice;
        this.info = info;
    }

    public String getName() {
        return name;
    }

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

    public double getOriginalPrice() {
        return originalPrice;
    }

    public void setOriginalPrice(double originalPrice) {
        this.originalPrice = originalPrice;
    }

    public double getSpecialPrice() {
        return specialPrice;
    }

    public void setSpecialPrice(double specialPrice) {
        this.specialPrice = specialPrice;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

}

接下来写一个菜品管理类,提供**上架菜品的功能、浏览菜品的功能、展示操作界面的功能

public class FoodManager{
    //为了存储多个菜品,预先创建一个ArrayList集合;
    //上架菜品时,其实就是往集合中添加菜品对象
    //浏览菜品时,其实就是遍历集合中的菜品对象,并打印菜品对象的属性信息。
    private ArrayList<Food> foods = new ArrayList<>(); 
    //为了在下面的多个方法中,能够使用键盘录入,提前把Scanner对象创建好;
    private Scanner sc = new Scanner(System.in);

    /**
     1、商家上架菜品
     */
    public void add(){
        System.out.println("===菜品上架==");
        // 2、提前创建一个菜品对象,用于封装用户上架的菜品信息
        Food food = new Food();
        System.out.println("请您输入上架菜品的名称:");
        String name = sc.next();
        food.setName(name);

        System.out.println("请您输入上架菜品的原价:");
        double originalPrice = sc.nextDouble();
        food.setOriginalPrice(originalPrice);

        System.out.println("请您输入上架菜品的优惠价:");
        double specialPrice = sc.nextDouble();
        food.setSpecialPrice(specialPrice);

        System.out.println("请您输入上架菜品的其他信息:");
        String info = sc.next();
        food.setInfo(info);

        // 3、把菜品对象添加到集合容器中去
        foods.add(food);
        System.out.println("恭喜您,上架成功~~~");
    }

    /**
       2、菜品;浏览功能
     */
    public void printAllFoods(){
        System.out.println("==当前菜品信息如下:==");
        for (int i = 0; i < foods.size(); i++) {
            Food food = foods.get(i);
            System.out.println("菜品名称:" + food.getName());
            System.out.println("菜品原价:" + food.getOriginalPrice());
            System.out.println("菜品优惠价:" + food.getSpecialPrice());
            System.out.println("其他描述信息:" + food.getInfo());
            System.out.println("------------------------");
        }
    }
    /**
    3、专门负责展示系统界面的
    */
    public void start(){
        while (true) {
            System.out.println("====欢迎进入商家后台管理系统=====");
            System.out.println("1、上架菜品(add)");
            System.out.println("2、浏览菜品(query)");
            System.out.println("3、退出系统(exit)");
            System.out.println("请您选择操作命令:");
            String command = sc.next();
            switch (command) {
                case "add":
                    add();
                    break;
                case "query":
                    printAllFoods();
                    break;
                case "exit":
                    return; // 结束当前方法!
                default:
                    System.out.println("您输入的操作命令有误~~");
            }
        }
    }

}

最后在写一个测试类Test,在测试类中进行测试。其实测试类,只起到一个启动程序的作用

public class Test {
    public static void main(String[] args) {
        FoodManager manager = new FoodManager();
        manager.start();
    }
}

第九部分 Java基础综合实战

博客内容均系原创,未经允许严禁转载!
您可以通过 RSS 订阅本站文章更新,订阅地址:https://www.sunqizheng1997.com/feed/什么是 RSS ?
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
下一篇