黑马程序员Java笔记

该文章已生成可运行项目,

Java

目录

Java

一、Java入门

1.常见的CMD命令

2.Java三大平台

3.Java作用

4.Java主要特征

5.JDK和JRE

二、Java基础语法

1.注释

2.字面量

3.变量

4.计算机的存储规则

5.数据类型

6.标识符

7.键盘录入

获取随机数

8.运算符

(1).运算符和表达式

算术运算符

自增运算符

赋值运算符

关系运算符

逻辑运算符

三元运算符

运算符的优先级

(2).判断和循环

顺序结构

分支结构

循环结构

9.数组

10.java内存分配

11.方法

12.面向对象

1.类和对象

2.javabean类

3.封装

4.this关键字

5.构造方法

6.标准JavaBean

7.快捷键

8.Static静态

9.API

10.创建String对象的两种方式

11.字符串

1),字符串的比较

2),string

3),StringBuilder

4),StringJoiner

5),字符串原理

6),综合练习

13,集合

学生管理系统

学生管理系统升级版


一、Java入门

1.常见的CMD命令

盘符名称+冒号盘符切换dir查看当前路径下的内容(包括隐藏内容)
CD目录进入目录CD..退出当前目录
cd\目录1\目录2...进入多级目录cd\回退到盘符目录
cls清屏exit退出命令提示窗口

2.Java三大平台

  • Java SE ——Java语言(标准版)。用于左面与应用开发,是其他两个版本的基础。

  • Java ME —— Java语言(小型版),用于嵌入式电子设备或小型移动设备。

  • Java EE ——Java语言(专业版),用于web方向的网站开发。

3.Java作用

  • 桌面应用开发

  • 企业级应用开发

  • 移动应用开发

  • 科学计算(matlab)

  • 大数据开发

  • 游戏开发

4.Java主要特征

  • 面向对象

  • 安全性

  • 多线程

  • 简单易用

  • 开源

  • 跨平台(window、mac、Linux)

    • 跨平台原理

      • 高级语言的编译方式:

        • 编程:Java程序员写.java代码,c语言程序员写.c代码。

        • 编译:机器只认识0011的机器语言,把.Java.c.py的代码转换成机器能认识的过程

          • 编译型:C语言,全部翻译再运行,存在兼容性问题,非跨平台

          • 解释型:py语言,按行翻译,再运行,

          • 混合型:Java语言,混合翻译,在虚拟机内运行

        • 运行:让机器执行编译后的指令

5.JDK和JRE

  1. JDK是Java开发工具包

    1. JVM虚拟机:Java运行的地方

    2. 核心类库:Java已经写好的东西,我们可以直接用

  2. JRE是Java运行环境

    1. 包括JVM、核心类库、运行工具

  3. JDK包含了JRE,JRE包含了JVM

二、Java基础语法

1.注释

  1. 单行 //

  2. 多行 /* */

  3. 文档 /** */


2.字面量

字面量告诉程序员的书写格式

分类:

字面量类型说明举例
整数类型不带小数点的数字888
小数类型带小数的数字13.12
字符串类型双引号引起来的内容,"HelloWorld","六神花露水"
字符类型用单括号引起来的内容,内容个数只能有一个'A'、'0'、'我'
布尔类型布尔值,表示真假只有两个值:true,false
空类型一个特殊的值,空值值为:null

特殊字面量:'\t' '\r' '\n'

  • '\t':制表符——缩进、对齐(字符串长度补齐到8位)、补空格

  • 空类型:null


3.变量

数据类型:限定了变量能存储数据的类型

变量名:存储空间名字

作用:方便使用

idea变量批量修改:shift+f6

定义格式:数据类型 变量名 = 数据值;

输出打印、参与运算、修改记录的值

注意

  • 只能存一个值

  • 变量名不允许重复定义

  • 一条语句可以定义多个变量

  • 变量在使用前一定要先进行赋值

  • 变量的作用域范围


4.计算机的存储规则

在计算机中任意数据都是以二进制存储

存储数据:

  1. Text文本

    1. 数字、字母、汉字

  2. Image图片

    1. 黑白图、灰度图、彩色图

    2. 分辨率、像素、三原色(红绿蓝)

  3. Sound声音

不同进制在代码中的表现形式

  • 二进制:由0,1组成,ob开头

  • 十进制:由0~9组成,无前缀

  • 八进制:0~7组成,以0开头

  • 十六进制:0~9和a~f组成,以0x开头

进制转换:

  1. 任意进制转换成十进制

    1. 公式:系数*基数的权次幂 相加

  2. 十进制转换成任意进制

    1. 除基取余法


5.数据类型

基本数据类型

整数和小数取值的大小范围关系:

double>float>long>int>short>byte

字符串String


6.标识符

标识符命名规则——硬性要求

  1. 必须由数字、字母、下划线(_)和美元符号($)组成

  2. 不能以数字开头

  3. 不能是关键字

  4. 区分大小写

标识符命名规则——软性要求

  1. 小驼峰命名法:方法、变量

    1. 标识符为一个单词时全是小写

    2. 标识符为多个单词组成时,第一个单词首字母小写,其他单词首字母大写

  2. 大驼峰命名法:类名

    1. 标识符是一个单词时首字母大写;

    2. 标识符为多个单词组成时每个单词首字母要大写

  3. 标识符见名知意


7.键盘录入

Java已有一个Scanner类,该类可以接收键盘输入的数字

  1. 导包——

    import java.util.Scanner;
  2. 创建对象——

    Scanner sc = new Scanner(System.in);
    //上面这个格式里面,只有sc是变量名,可以变,其他不能改变
  3. 接收数据——

    int i = sc.nextInt();
    //在这个格式里面只有i是变量名,可以变,其他不能变。

第一套体系

nextInt();接收整数,

nextDouble();接收小数和整数

next;接收字符串

遇到空格、制表符,就停止接收

第二套体系

next Line();按行接收,

可以接收空格、制表符,遇到回车停止接收

获取随机数
  1. 导包——

    import java.util.Random;
  2. 创建对象——

    Random sc = new Random();
    //上面这个格式里面,只有sc是变量名,可以变,其他不能改变
  3. 接收数据——

    int number = sc.nextInt(101);
    //在这个格式里面只有101是随机数的范围,左闭右开范围是0~100,默认从0开始,
    int number = sc.nextInt(50)+5;
    //这个随机数范围是5~54,这是改变随机数最小值的方法

8.运算符

(1).运算符和表达式

运算符:对字面量或者变量进行操作的符号

例如:+/-*

表达式:用运算符把字面量或变量连接起来,符合Java语法的式子

例如:a=b+c

  1. 算术运算符
符号作用
+
-
*
/
%取余

取余 应用场景:

  1. 可以判断A是否被B整除

  2. 可以判断A是否是偶数。为零是偶数,为1是奇数


注意:

  • 整数参与计算,结果只能得到整数。

  • 小数参与运算结果可能不精确。


快速书写主函数:psvm + Tab/Enter

快速写输出函数:sout + Tab/Enter


练习

  • 输入任意数字,返回个位十位百位....

数值拆分:个位:数值%10;十位:数值/10%10;百位:数值/100%10....

  • 数字相加,10+12.3

    隐式转换

    1.将取值范围小的转换成取值范围大的

    int a=10;
    double b=a;//b=10.0

    2.byte short char 三种类型的数据在运算的时候,都会直接先转换成int,再计算。

    byte a = 10;
    byte b = 20; //c=a+b;转换后再相加,则C为int类型

    3.取值范围:byte<short<int<long<float<double

    4.什么时候转换:数据类型不一样,不能计算,需要转换成一样时


    强制转换

    格式

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

    byte a=10;
    int b = (int) a
  • 字符串的“+”操作

    当“+”操作中出现字符串时,这个“+”是字符串的连接符,而不是算数运算符。

    System.out.println(3.1+"abc");//"3.1abc"
    System.out.println("abc"+trun);//"abctrue"
    System.out.println('中'+"abc"+trun);//"中abctrue"
    System.out.println(1+2+"abc"+1+2);//"3abc12"
    System.out.println("a"+1);//"98"——字符加数字即字符对应的ASCII编码加数字

  1. 自增运算符
符号作用说明
++变量加1
--变量减1

++和--无论是放在变量的前面还是变量的后面,单独写一行结果是一样的。

int a=10;
a++; System.out.println(a);//11
++a; System.out.println(a);//12
a--; System.out.println(a);//11
--a; System.out.println(a);//10

++和--参与运算时,放在左边还是右边结果是不一样的

int a=10; int b=a++; //b=10————先用再加
int a=10; int b=++a; //b=11————先加再用
**************************************
int x=10;
int y=x++; System.out.println(y);//10
int z=++x; System.out.println(z);//12
System.out.println(x);//12


  1. 赋值运算符
符号作用说明
=赋值int a=10;将10赋值给变量a
+=加后赋值
-=减后赋值
*=乘后赋值
/=除后赋值
%=取余后赋值

  1. 关系运算符
符号说明
==判断是否相等,等于返回true,不等返回false
!=判断是否不等
>判断是否大于
>=判断是否大于等于
<判断是否小于
<=判断是否小于等于

注意关系运算符的结果都是Boolean类型,要么是true,要么是false


  1. 逻辑运算符
符号作用说明
&并且,两边都为真才是真
|或者,两边都是假才是假
^异或相同为假,不同为真
!取反

  1. 短路逻辑运算符

提升代码运算效率

符号作用说明
&&短路与结果和&相同,但是有短路效果(前面不满足则不执行后面)
||短路或结果和|相同,但是有短路效果(前面满足不执行后面)

#####

  1. 三元运算符

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

int number1 = 10,number2 = 20;
int a = number1>number2 ? number1:number2;
System.out.println(a);

  1. 运算符的优先级
  • 小括号优先于所有

(2).判断和循环
  1. 顺序结构

    代码按顺序执行

  2. 分支结构
    1. if语句

      if(关系表达式1){
      
      语句体1;
      
      }ielse if(关系表达式2){
      
      语句体2;
      
      }else(关系表达式3){
      
      语句体3;
      
      }

    2. switch语句

      switch(表达式){
      
      case 值1:
      
      语句体1;
      
      break;
      
      case 值2:
      
      语句体2;
      
      break;
      
      .......
      
      default:
      
      语句体n;
      
      break;
      
      }

      注意:

      1. 表达式:(将要匹配的值)取值为byte、short、int、char。

      2. case:后面跟的是要和表达式进行比较的值,(被匹配的值)。

      3. break:跳出循环,不能缺省,否则会造成case穿透。

      4. default:都不匹配时执行该处内容。

      5. case后面的值只能是字面量,不能是变量。

      6. case后面的值不能重复。

      简化写法

      switch(表达式){
      
      case 值1 ->语句体1
      
      case 值2 ->语句体2
      
      .......
      
      default ->语句体n
      
      }

  3. 循环结构
    1. for循环

      for(初始化语句;条件判断语句;条件控制语句){

      循环提语句;

      }

      • 自增变量后面不能使用

      • 知道循环范围或次数时使用

    2. while循环

      while(条件判断语句){

      循环体语句;

      条件控制语句;

      }

      • 先判断后执行,自增变量后面还可以使用

      • 不知道循环范围和次数时使用

    3. do...while循环

      do{

      循环体语句;

      条件控制语句;

      }while(条件判断语句);

      • 先执行后判断

    4. 循环高级综合练习

      1. 无限循环

      循环条件判断为true。

      1. 跳转循环控制语句

        1. continue:跳出本次循环,执行下次循环。

        2. break:结束整个循环。

      2. 练习

        1.求输入数字的平方根

        Scanner sc = new Scanner(System.in);
        System.out.println("请输入要开方的数字");
        int number = sc.nextInt();
        for (int i = 1; i <= number; i++) {
        int temp = i * i;
        if (temp == number) {
          System.out.println(number + "的平方根是:" + i);
          break;
        } else if (temp < number) {
          continue;
        } else if (temp > number) {
          System.out.println(number + "的平方根整数是:" + (i - 1));
          break;
        }
        }

        2.判断输入整数是否为质数

        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个整数");
        int number = sc.nextInt();
        boolean temp = true;
        for (int i = 2; i < number; i++) {
        if(number%i==0){
          temp=false;
          break;
        }
        }
        if(temp){
        System.out.println(number+"是质数");
        }else {
        System.out.println(number+"不是质数");
        }

        3.猜数字小游戏

        Random sc = new Random();
        int number = sc.nextInt(101);
        Scanner s = new Scanner(System.in);
        while (true){
         System.out.println("猜数字");   //将输入值放入循环内部,所猜的值就会一直变化
         int gusset = s.nextInt();
         if (number>gusset){
             System.out.println("小了");
             continue;
         } else if (number<gusset) {
             System.out.println("大了");
             continue;
         }else {
             System.out.println("猜对了");
             break;
         }


9.数组

1.数组介绍

数组是一种容器,可以用来存储同种数据类型的多个值

  • 数组容器在存储数据时,需要结合隐式转换考虑

  • 建议容器类型和存储的数据类型保持一致

2.数组定义和静态初始化

//定义
1.数据类型【】 数组名
    int [] array;
2.数据类型 数组名【】
    int array[];

数组的静态初始化

- 初始化:就是在内存中,为数据容器开辟空间,并将数据存入容器中的过程
- 简化格式:数据类型【】数组名={元素1,元素2,.....};
//字符串类型String
    string[] array={"zhang","wang","li"};
    string[] array=new string[]{"zhang","wang","li"};//完整格式

数组元素访问

3.数组的地址值表示数组在内存中的位置

int[] array = {1,2,3,4,5};
System.out.println(array);//结果是数组位置

4.数组遍历

int[] array = {1,2,3,4,5};
int len = array.length;  //获取数组长度的函数length,获取字符串长度的函数size()
for (int i = 0; i < len; i++) {
    System.out.println(array[i]);
}

5.数组动态初始化

初始化时只指定数组的长度,由系统为数组分配初始值。

数据类型 【】 数组名=new 数据类型【数组长度】;
int [] arr = new int[3];
arr[0]=1; arr[1]=2; arr[2]=3;

默认初始化类型规律

  • 整数类型:默认初始化为0

  • 小数:0.0

  • 字符:'/u0000' 空格

  • 布尔:false

  • 引用数据类型:null


数组动态初始化和静态初始化的区别

  1. 动态初始化:手动指定数组长度,由系统给出默认初始化值

    只明确数组长度,不知道具体数值

  2. 静态初始化:手动指定数组元素,系统会根据数组元素个数计算出数组长度

    需求明确已经要求操作的具体数据

6.数组内存图

7.数组常见问题

  1. 索引越界异常

8.二维数组

1.二维数组的静态初始化

//格式
数据类型【】【】数组名=new 数据类型【】【】{{元素1,元素2},{元素1,元素2}};
int [][] arr=new int[][]{{1,2},{11,22}};
//简化格式
数据类型【】【】数组名={{元素1,元素2},{元素1,元素2}};
int [][] arr={{1,2},{11,22}};

2.获取元素

arr[i][j]
i:获取二维数组里面的一维数组
j:表示一维数组的索引,获取一维数组的元素

3.二维数组的动态初始化

数据类型【】【】数组名=new 数据类型【n】【m】;
n:表示这个二维数组可以存放多少个一维数组;
m:表示每一个一维数组可以存放多少个元素;

9.数组常见操作

求最值

//已知数组元素为{33,5,22,44,55},求最大最小值
int [] arr = {33,5,22,44,55};
int max = arr[0], min=arr[0];  //初始化值是数组元素就行
for (int i = 1; i < arr.length; i++) {  //循环开始条件为1,提高循环效率
max = arr[i]>=max? arr[i]:max;
min = arr[i]<=min? arr[i]:min;
}
System.out.println(max);
System.out.println(min);

遍历数组求和

Random sc=new Random();
int [] arr =new int[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = sc.nextInt(100)+1;
}
int sum =0,avg=0,count=0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
System.out.println("和"+sum);
avg=sum/10;
System.out.println("平均"+avg);
for (int i = 0; i < arr.length; i++) {
if(arr[i]<avg){
  count++;
}
}
System.out.println(count);//小于平均数的个数

交换数组首尾元素

int [] arr = {1,2,3,4,5};
for (int i = 0,j= arr.length-1; i < j ; i++,j--) {
int temp = arr[i];
arr[i]=arr[j];
arr[j]=temp;
}

打乱数组中的数据

int [] arr = {1,2,3,4,5};
Random sc=new Random();
for (int i = 0; i < arr.length; i++) {
int t=sc.nextInt(5);
int temp=arr[0];
arr[0]=arr[t];
arr[t]=temp;
}


10.java内存分配

方法运行时使用的内存,比如main方法运行,进入方法栈中执行
存储对象或数组,new来创建的,都存储在堆内存
方法区存储可以运行的class文件
本地方法堆JVM在使用操作系统功能时使用,和我们开发无关
寄存器给CPU使用,与我们无关

  • 只要是new出来的一定是在堆里面开辟了一个小空间

  • 如果new了多次,那么在堆里面有多个小空间,每个小空间中都有各自的数据


11.方法

方法:程序当中最小的执行单元

意义:重复代码,具有独立功能的代码抽取到方法中,可以提高代码复用性、和可维护性。

自动抽取方法:CTRL+alt+M

1.方法定义

把一些代码打包在一起,该过程就是方法定义。

//简单定义
public static void 方法名(){
方法体(就是打包起来的代码);
}
//有参数的调用
public static void 方法名(形参1,形参2){
方法体(就是打包起来的代码);
}
//有返回值的调用
public static 返回值类型 方法名(){
方法体(就是打包起来的代码);
return 返回值;
}

形参:全体形式参数,方法定义中的参数

2.方法调用

方法定义后并不是直接运行的,需要手动调用才能执行,该过程称为方法调用。

//简单调用
方法名();
//含参数调用
方法名(实参1,实参2);
//赋值调用
整数类型 变量名 = 方法名(实参);
//输出调用
System.out.print(方法名(实参));

实参:全体实际参数,方法调用中的参数

注意:参数调用时,参数的数量必须与方法定义中小括号里面的变量一一对应,(类型和数量)

注意

  • 方法不调用就不会执行

  • 方法之间是平级关系,不能相互嵌套

  • 方法的执行顺序和编写顺序无关

  • 方法的返回值类型为void时,表明没有返回值,

  • return 语句表示结束方法,无返回值时可以省略,下方不能编写代码

3.方法重载

1.在同一个类中,定义了很多同名的方法,这些方法都有相同的功能

2.每个方法具有不同的参数类型和参数个数,与返回值无关,这些同名的方法,就构成了重载的关系

3.参数不同:个数不同、类型不同、顺序不同。


  • 基本数据类型:变量中存放的是真实的数据

    int a=10;
    int b=a;//b=10

  • 引用数据类型:(基本数据类型以外的)变量中储存的是地址值,数据值存放在其他空间。引用:使用了其他空间中的数据

    int [] arr1 = {1,2,3,4};
    int [] arr2 = arr1;//arr2和arr1共用一个地址

4.方法传递基本数据类型的内存原理

1.传递基本数据类型时,传递的是真实的数据,形参的改变,不影响实际参数的值

2.传递应用数据类型时,传递的是地址值,形参的改变,影响实际参数的值

5.练习

1.卖机票

//旺季(5~10),头等舱折扣9折,经济舱8.5折,淡季(11~4),头等舱7折,经济舱6.5折
Scanner sc = new Scanner(System.in);
System.out.println("请输入机票原价");
int ticke = sc.nextInt();
System.out.println("请输入月份");
int month = sc.nextInt();
System.out.println("请输入座位:头等舱0,经济舱1");
int seat = sc.nextInt();
if (month >= 5 && month <= 10) {
int price = getPrice(ticke, seat, 0.9, 0.85);
System.out.println(price);
} else if ((month <= 4 && month >= 1) || (month <= 12 && month >= 11)) {
int price = getPrice(ticke, seat, 0.7, 0.65);
System.out.println(price);
} else {
System.out.println("月份不对");
}
}
public static int getPrice(int ticke, int seat, double v1, double v2) {
if (seat == 0) {
  ticke = (int) (ticke * v1);
} else {
  ticke = (int) (ticke * v2);
}
return ticke;
}

2,找质数

//判断101~200之间有多少个质数,并打印所有质数
int count = 0;
for (int i = 101; i <= 200; i++) {
boolean flag = true;
for (int j = 2; j < i; j++) {
  if (i % j == 0) {
      flag = false;
      break;
  }
}
if (flag) {
  System.out.println("数字" + i + "是质数");
  count++;
}
}
System.out.println("一共有" + count + "个质数");

3.开发验证码

//定义方法随机生成一个5位的验证码,
// 前四位是大写或小写字母,最后一位是数字
//1.大写字母和小写字母放入一个数组中
char[] arr = new char[52];
for (int i = 0; i < arr.length; i++) {
if (i < 26) {
  arr[i] = (char) (97 + i);
} else {
  arr[i] = (char) (65 + i - 26);
}
}
String result = " ";
//2.随机抽取4次
Random ra = new Random();
for (int i = 0; i < 4; i++) {
int randomIndex = ra.nextInt(52);
result = result + arr[randomIndex];
}
//3.随机抽取0~9数字
int number = ra.nextInt(10);
result += number;
System.out.println(result);

4.数组元素的复制

//把一个数组的元素复制到另一个新数组中去
int [] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int len = arr.length;
int [] copyArr = new int[len];
int index=0;
for (int i = 0; i < arr.length; i++) {
copyArr[index]=arr[i];
index++;
}
for (int i = 0; i < copyArr.length; i++) {
System.out.print(copyArr[i]+" ");
}

5.评委打分

public static void main(String[] args) {
//去掉最高分和最低分,求平均分
int[] arr = getArr();
int max = getMax(arr);
int min = getMin(arr);
int sum=getSum(arr);
int result=(sum-max-min)/4;
System.out.println("平均分是"+result);
​
}
public static int[] getArr() {
Scanner sc = new Scanner(System.in);
int[] arr = new int[6];
for (int i = 0; i < arr.length; ) {
  System.out.println("请输入分数:");
  int number = sc.nextInt();
  if (number >= 0 && number <= 100) {
      arr[i] = number;
      i++;
  } else {
      System.out.println("分数只能在0~100之间,此时数组下标为" + i);
  }
}
return arr;
}
public static int getMax(int[] arr) {
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
  if (max < arr[i]) {
      max = arr[i];
  }
}
return max;
}
public static int getMin(int[] arr) {
int min = arr[0];
for (int i = 1; i < arr.length; i++) {
  if (min > arr[i]) {
      min = arr[i];
  }
}
return min;
}
public static int getSum(int [] arr){
int sum=0;
for (int i = 0; i < arr.length; i++) {
  sum+=arr[i];
}
return sum;
}

6.数字加密

//加密规则:每位数字先加5,再对10取余,最后所有数字进行翻转
int[] arr = {1, 9, 8, 3};
for (int i = 0; i < arr.length; i++) {
arr[i] = arr[i] + 5;
}
for (int i = 0; i < arr.length; i++) {
arr[i] = arr[i] % 10;
}
for (int i = 0, j = arr.length - 1; i < j; i++, j--) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
int number = 0;
for (int i = 0; i < arr.length; i++) {
number = number * 10 + arr[i];
}
System.out.println(number);

7.把整数上的每一位都添加到数组当中

//加密规则:每位数字先加5,再对10取余,最后所有数字进行翻转
int number = 12345;
int temp = number;
int count = 0;
while (number > 0) {
number = number / 10;
count++;
}
int[] arr = new int[count];
int index = arr.length-1;
while (temp != 0) {
int ge = temp % 10;
temp = temp / 10;
arr[index] = ge;
index--;
}
for (int j : arr) {
System.out.print(j + " ");
}

8.将加密的数据解密出来

//按照加密规则进行解密,加密规则:每位数字先加5,再对10取余,最后所有数字进行翻转
//先反转,5~9不变0~4+10,减5
int [] arr ={8,3,4,6};
for (int i = 0,j=arr.length-1; i < j; i++,j--) {
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
for (int i = 0; i < arr.length; i++) {
if(arr[i]>=0&&arr[i]<=4){
  arr[i]=arr[i]+10;
}
}
for (int i = 0; i < arr.length; i++) {
arr[i]=arr[i]-5;
}
int number=0;
for (int i = 0; i < arr.length; i++) {
number=number*10+arr[i];
}
System.out.println(number);

9.抢红包

public static void main(String[] args) {
//5个奖项,被抽过的不能再抽
int []  arr={2,588,888,1000,10000};
int [] newArr=new int[arr.length];
Random r=new Random();
for (int i = 0; i < 5; i++) {
  int index= r.nextInt(arr.length);
  int price=arr[index];
  if(!contains(newArr,price)){
      newArr[i]=price;
      i++;ss
  }
}
for (int i = 0; i < newArr.length; i++) {
  System.out.print(newArr[i]+" ");
}
}
public static boolean contains(int [] arr, int price){
for (int i = 0; i < arr.length; i++) {
  if(arr[i]==price){
      return true;
  }
}
return false;
}

////改进
int [] arr={2,588,888,1000,10000};
Random r=new Random();
for (int i = 0; i < arr.length; i++) {
 int randomIndex=r.nextInt(arr.length);
 int temp=arr[i];
 arr[i]=arr[randomIndex];
 arr[randomIndex]=temp;
}
for (int i = 0; i < arr.length; i++) {
 System.out.println(arr[i]);
}

12.面向对象

1.类和对象
  • 类:是对象共同特征的描述;

  • 对象:是真实存在的事物;

//类定义
public class 类名(){
    	1.成员变量(代表属性,一般是名词)
        2.成员方法(代表行为,一般是动词)
        3.构造器
        4.代码块
        5.内部类
 }           
//得到类对象
 类名 对象名=new 类名();
//使用对象
 访问属性: 对象名.成员变量
 访问行为: 对象名.访问方法(...)

2.javabean类

1.用来描述一类事物的类,专业叫javabean类,在javabean类中无main方法。

2.以前编写main方法的类,叫做测试类。可以在测试类中创建JavaBean类的对象并进行赋值调用。

3.类名首字母大写,见名知意,驼峰模式。

4.一个java中可以定义多个class类,且只能一个类是public修饰。public修饰的类名必须是Java代码的文件名。实际开发中,建议一个文件一个class类

5.成员变量的完整定义是:修饰符 数据类型 变量名 = 初始化值;一般无需初始化,存在默认值。

对象成员变量的默认值规则

  • 基本类型

    • byte、short、int、long :0

    • floa、double :0.0

    • Boolean :false

  • 引用数据类型:

    • 类、接口、数组、String :null

3.封装

定义:对象代表什么,就得封装对应的数据,并提供数据对应的行为

1.private

  • private关键字是一个权限修饰符

  • 可以修饰成员(成员变量和成员方法)

  • 被private修饰的成员变量,如果需要被其他类使用,提供相应的操作

  • 提供“setXxx(参数)”方法,用于给成员变量赋值,方法用public修饰。

  • 提供“getXxx(参数)”方法,用于获取成员变量值,方法用public修饰。

4.this关键字

成员变量:定义在方法外的变量

局部变量:定义在方法内的变量

就近原则:当局部变量和成员变量一样时,谁近用谁

加上this关键字则使用成员变量

privat int age = 20;
public void getAge(){
 int age=10;
  System.out.println(age);//10
  System.out.println(this.age);//20
}
private  String name;
public void  setName(String name){
 //左边表示成员变量的位置
 //右边局部变量表示测试类中调用方法传递过来的数据
 this.name=name;
}

5.构造方法

定义:构造方法也叫构造器、构造函数

作用:在创建对象的时候给成员函数变量进行赋值的,虚拟机自动调用,给成员变量进行初始化的。

public  class Student{
     修饰符   类名(参数){
         方法体;
 }

特点:

  • 方法名与类名相同,大小写也要一致

  • 没有返回值类型,连void也没有

  • 没有具体的返回值(不能由return带回结果数据)

注意:

  • 如果没有定义构造方法,系统将给出一个默认的无参构造方法

  • 如果定义了构造方法,系统将不再提供默认的构造方法

重载:

  • 带参构造方法,和无参构造方法两着方法名相同,但是参数不同,这叫做构造方法的重载

无论是否使用,都需要手写无参构造方法和有参构造方法

6.标准JavaBean

1.类名见名知意

2.成员变量用private修饰

3.提供至少两个构造方法,无参和带全部参数

4.成员方法

  • 提供每一个成员变量对应的setXxx()/getXxx()

  • 如果还有其他行为要写上

7.快捷键

快速生成构造函数、setXxx()/getXxx()、

  • alt+insert

  • alt+fn+insert

  • 插件PTG 1秒生成标准JavaBean:ctrl+shift+逗号

8.Static静态

静态成员被所有类的对象共享,不属于对象属于类,优先于对象存在

静态方法只能访问静态,非静态方法可以访问静态,静态方法无this关键字

调用方法:类名调用,对象名调用

9.API

API:应用程序编程接口

简单理解:API就是别人已经写好的东西,我们不需要自己编写,直接使用

java API:是指JDK中提供的各种功能的java类

10.创建String对象的两种方式

1.直接赋值

String name = "黑马程序员";

2.new

构造方法说明
public String()创建空白字符串,不含任何内容
public String(String original)根据传入的字符串,创建字符串对象
public String(char[] chs)根据字符数组,创建字符串对象
public String(byte[] chs)根据字节数组,创建字符串对象
String s1=new String();
String s2=new String("店面");
byte[] bytes={97,98,99,100};
String s4=new String(bytes);
char[] chars={'a','b','c'};
String s5= new String(chars);

11.字符串
1),字符串的比较
Boolean equals 方法(要比较的字符串)完全一样结果才是true,否则为false
Boolean equalsgnoreCase(要比较的字符串)忽略大小写比较
2),string

概述:表示字符串的类,定义了许多操作字符串的方法

构造方法+成员方法

方法说明
String()初始化新创建的 String对象,使其表示空字符序列。
String(byte[] bytes)通过使用平台的默认字符集解码指定的字节数组来构造新的 String
String(byte[] bytes, Charset charset)构造一个新的String由指定用指定的字节的数组解码charset 。
String(byte[] bytes, int offset, int length)通过使用平台的默认字符集解码指定的字节子阵列来构造新的 String

//==号比较
基本数据类型:比的是数据值.
引用数据类型:比的是地址值
String s1=new String("abc");
String s2="abc";
String s3="Abc";
System.out.println(s1==s2);//false
boolean result=s1.equals(s2);
System.out.println(result);//true
boolean result1=s1.equals(s2);
System.out.println(result1);//true
boolean result2=s1.equals(s3);
System.out.println(result2);//false
boolean result3=s1.equalsIgnoreCase(s3);
System.out.println(result3);//true
//练习1,已有账号密码,登录
String name="admin";
String KeyWord="123456";
Scanner sc =new Scanner(System.in);
​
int count=3;
while(true){
    System.out.println("请输入用户名");
    String username=sc.next();
    System.out.println("请输入密码");
    String userkeyword=sc.next();
    if(name.equals(username)&&KeyWord.equals(userkeyword)){
        System.out.println("登陆成功");
        break;
    }else {
        count--;
        if(count==0){
            System.out.println("账号被锁定,请联系管理员");
            break;
        }
        System.out.println("登录失败,还剩"+count+"次机会");
​
​
    }
​
}

//练习2,遍历字符串

  • public char charAt(int index):根据索引返回字符

  • public int length():返回此字符串的长度

  • 数组长度:数组名.length

  • 字符串长度:字符串对象.length()

Scanner sc=new Scanner(System.in);
System.out.println("请输入一个字符串");
String str = sc.next();
for (int i = 0; i < str.length(); i++) {
    char c = str.charAt(i);
    System.out.println(c);
}

//统计字符个数

键盘录入一个字符串,统计该字符串中大写字母字符,小写字母字符,数字字符出现的个数(不考虑其他字符)

Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串");
String str = sc.next();
int bigcount=0,smallcount=0,numbercount=0;
for (int i = 0; i < str.length(); i++) {
 char c = str.charAt(i);
 if(c>='a'&&c<='z'){
     smallcount++;
 } else if (c>='A'&&c<='Z') {
     bigcount++;
 } else if (c>='0'&&c<='9') {
     numbercount++;
 }

}
System.out.println("大写"+bigcount+"个,小写"+smallcount+"个,数字"+numbercount+"个");

//拼接字符串

把数组变成字符串再返回

public static void main(String[] args) {
    int [] arr = {1,2,3};
    String pin = pin(arr);
    System.out.println(pin);
}
public static String pin(int[] arr){
    if(arr==null){
        return "";
    }else if (arr.length==0){
        return "[ ]";
    }
    String result="[";
    for (int i = 0; i < arr.length; i++) {
        result+=arr[i];
    }
    result+="]";
    return result;

}

//字符串的反转

public static void main(String[] args) {
 Scanner sc=new Scanner(System.in);
 System.out.println("请输入字符串");
 String next = sc.next();
 String fan = fan(next);
 System.out.println(fan);
}
public static String fan(String str){
 String temp="";
 for (int i = str.length()-1; i >=0 ; i--) {
     temp+=str.charAt(i);
 }
 return temp;
}

//金额转换

将阿拉伯数字转换成中文带单位

public static void main(String[] args) {
 Scanner sc=new Scanner(System.in);
 int money=0;
 while (true){
     System.out.println("请输入数字");
     money = sc.nextInt();
     if(money>=0&&money<9999999){
         break;
     }else {
         System.out.println("金额无效");
     }
 }
 //转换成大写
 String moneyStr="";
 while (true){
     int ge = money%10;
     String capitalNumber = getCapitalNumber(ge);
     moneyStr=capitalNumber+moneyStr;  //让拼接顺序与数字原顺序一致
     money=money/10;
     if(money==0){
         break;
     }
 }
 //前面补零,补齐7位
 int count =7-moneyStr.length();
 for (int i = 0; i < count; i++) {
     moneyStr="0"+moneyStr;
 }
 //插入单位
 //定义一个数组表示单位
 String[] arr = {"佰","拾","万","仟","佰","拾","元",};
 String result="";
 for (int i = 0; i < moneyStr.length(); i++) {
     char c = moneyStr.charAt(i);
     result = result+c+arr[i];
 }
 System.out.println(result);
}
public  static  String getCapitalNumber(int number){
 String [] str={"零","壹","贰","叁","肆","伍","陆","柒","捌","玖",};
 return str[number];
}

//手机号屏蔽

String str="12345678910";
String start = str.substring(0, 3);
String end = str.substring(7);
String result=start+"****"+end;
System.out.println(result);

//身份证查看

根据身份证判断男女和出生年月日

String id = "479027201405102125";
String year = id.substring(6, 10);
String month = id.substring(10, 12);
String day = id.substring(12, 14);
System.out.println("出生:"+year+"年"+month+"月"+day+"日");
char gender = id.charAt(16);
int num = gender - 48;
if(num%2==0){
System.out.println("女");
}else {
System.out.println("男");
}

//敏感词替换

Scanner sc= new Scanner(System.in);
System.out.println("你说");
String talk = sc.next();
//定义一个敏感词库
String [] arr = {"TMD","CNM","SB","NC"};
for (int i = 0; i < arr.length; i++) {
talk = talk.replace(arr[i],"***");
}
System.out.println(talk);

3),StringBuilder

概述:可以看成一个容器,创建之后内容可变

作用:提高字符串的操作效率

构造方法2+成员方法4:

方法名说明
public StringBuilder()创建一个空白可变的字符串对象,不包含有任何内容
public StringBuilder(string str)根据字符串的内容,来创建可变字符串对象
public StringBuilder append ( 任意类型)添加数据,并返回对象本身
public StringBuilder reverse ()反转容器中的内容
public int length()返回字符串长度
public String toString()通过toString可以把StringBuilder 转化成String

打印StringBuilder 是打印属性值,非地址值。

StringBuilder sb = new StringBuilder();
sb.append(1);  //添加字符串内容
sb.append(2.3);
sb.append("abc");
System.out.println(sb);//12.3abc
sb.reverse();
System.out.println(sb);//cba3.21
System.out.println(sb.length());
String temp = sb.toString();
System.out.println(temp);
public static void main(String[] args) {
//链式编程,调用一个方法时,不用接收返回结果,可以继续调用其他方法
int temp = getString().replace("a","w").length();
System.out.println(temp);
}
public static String getString(){
Scanner sc = new Scanner(System.in);
System.out.println("输入");
String t = sc.next();
return t;
}
//以上添加字符串内容可以用链式编程
sb.append(1).append(2.3).append("abc");

//对称字符串

//键盘接收字符串,判断是否是对称字符串
Scanner sc = new Scanner(System.in);
System.out.println("请输入");
String str = sc.next();
String result = new StringBuilder(str).reverse().toString();
if (str.equals(result)) {
    System.out.println("对称");
}else {
    System.out.println("不对称");
}

//定义方法,把int数组按照指定格式拼接成字符串

public static void main(String[] args) {
    int [] str = {1,3,4,5};
    String t = reverse(str);
    System.out.println(t);
}
public static String reverse(int [] str){
    StringBuilder sb=new StringBuilder();
    sb.append('[');
    for (int i = 0; i < str.length; i++) {
        sb.append(str[i]);
    }
    sb.append(']');
    return sb.toString();
}

4),StringJoiner

概述:跟StringBuilder一样可以看成容器,创建之后里面的内容是可变的。

作用:提高字符串的操作效率,而且代码编写特别简洁,但是目前市场上很少有人用

构造方法2+成员方法3:

方法名说明
public StringJoiner(间隔符号)创建一个StringJoiner对象,指定拼接时的间隔符号
public StringJoiner(间隔符号,开始符号,结束符号)创建一个StringJoiner对象,指定拼接时的间隔符号,开始符号,结束符号
public StringJoiner add(添加的内容)添加数据,并返回对象本身
public int length()返回长度(字符出现的个数)
public String toString()返回字符串(该字符串就是拼接成的)
StringJoiner sj = new StringJoiner(",","[","]");
sj.add("aaa").add("bbb").add("ccc"); 
System.out.println(sj);             //[aaa,bbb,ccc]
System.out.println(sj.length());    //13
System.out.println(sj.toString());  //[aaa,bbb,ccc]

5),字符串原理
  1. 内存原理

    1. 直接赋值会复用字符串常量池中的·

    2. new出来不会复用,而是开辟一个新的空间

  2. ==号比较什么

    1. 基本数据类型比较数据值

    2. 引用数据类型比较地址值

  3. 字符串拼接原理

    1. 拼接无变量 ,编译后就是拼接后的结果,会复用串池里的字符串

    2. 拼接有变量 , 每一行拼接的代码,都会在内存中创建心得字符串,浪费空间资源

  4. StringBuilder提高效率原理

    1. 所有要拼接的内容都会放入StringBuilder中,不会创建很多无用的空间,节约成本,节约内存

6),综合练习
//1,录入字符串0~9,转成罗马数字
//I-1,II-2,III-3,IV-4,V-5,VI-6,VII-8,IX-9
import java.util.Scanner;
import java.util.StringJoiner;

public class StringDemo1 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        StringBuilder sb = new StringBuilder();
        String str = "";
        while (true) {
            System.out.println("请输入字符串");
            str = sc.next();
            boolean flag = checkStr(str);
            if (!flag) {
                System.out.println("该字符串不符合要求,请重新输入!");
                continue;
            } else {
                break;
            }
        }
        for (int i = 0; i < str.length(); i++) {
            char a = str.charAt(i);
            String s = result((a - 48));
            sb.append(s);
        }
        StringJoiner sj = new StringJoiner(",","[","]");
        sj.add(sb);
        System.out.println(sj);
        sb.toString();
        System.out.println(sb);
    }

    public static boolean checkStr(String str) {
        if (str.length() > 9) {
            return false;
        }
        for (int i = 0; i < str.length(); i++) {
            char a = str.charAt(i);
            if (a < '0' || a > '9') {
                return false;
            }
        }
        return true;
    }
    public static String result(int number){
        String[] str = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
        return str[number];
    }

}
//2.调整字符串
//给定两个字符串,A和B,将A最左边字符移到最右边,在若干操作后,A变成B返回true,否则返回false。
public class main {
    public static void main(String[] args) {
       String str1= "abcde";
       String str2= "cdeab";
        System.out.println(check(str1,str2));
    }
    /*//法1
    public static String rotate(String str){
        char a = str.charAt(0);
        String b = str.substring(1);
        return b+a;
    }*/
    //法2:
    public static String rotate(String str){
        char [] arr = str.toCharArray();
        char a = arr[0];
        for (int i = 1; i < arr.length; i++) {
            arr[i-1] = arr[i];
        }
        arr[arr.length-1] = a;
        String st = new String(arr);
        return st;
    }
    public static boolean check(String str1,String str2){
        for (int i = 0; i < str1.length(); i++) {
            str1 = rotate(str1);
            if(str1.equals(str2)){
                return true;
            }
        }
        return false;
    }
}

修改字符串内容:

  1. 用subString进行截取,再进行修改

  2. 把字符串变成数组toCharArray(),再进行修改

//键盘输入任意字符串,打乱其中内容
Scanner sc = new Scanner(System.in);
System.out.println("请输入字符串:");
String str = sc.next();
Random rd = new Random();
char [] arr = str.toCharArray();
for (int i = 0; i < arr.length; i++) {
    int j = rd.nextInt(arr.length);
    char temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}
String result = new String(arr);
System.out.println(result);
//生成验证码
//大小写字母、数字、长度5。4位字母,1位数字,数字位置任意。
char[] arr = new char[52];
for (int i = 0; i < arr.length; i++) {
    if (i < 26) {
        arr[i] = (char) (97 + i);
    } else {
        arr[i] = (char) (65 + i - 26);
    }
}
String result = " ";
//2.随机抽取4次
Random ra = new Random();
for (int i = 0; i < 4; i++) {
    int randomIndex = ra.nextInt(52);
    result = result + arr[randomIndex];
}
//3.随机抽取0~9数字
int number = ra.nextInt(10);
result += number;
System.out.println(result);
//4.打乱
char[] charArray = result.toCharArray();
for (int i = 0; i < charArray.length; i++) {
    int index = ra.nextInt(charArray.length);
    char temp = charArray[i];
    charArray[i] = charArray[index];
    charArray[index] = temp;
}
String re = new String(charArray);
System.out.println(re);
//给出两个字符串非负整数num1和num2,得出它们的乘积也是字符串。
String num1 = "1234";
String num2 = "10000";
//字符串变成整数
int num11 = become(num1);
int num22 = become(num2);
//相乘
int result = num11*num22;
//整数变成字符串
String str = Integer.toString(result);
System.out.println(str);
}
public static int become(String str){
    char [] ch = str.toCharArray();
    int result = 0;
    for (int i = 0; i < ch.length; i++) {
        result = result*10+(ch[i]-48);
    }
    System.out.println(result);
    return result;
}
//给出字符串S,由单词组成,单词前后用空格隔开。
//返回最后一个单词的长度。
Scanner sc = new Scanner(System.in);
System.out.println("请输入字符串,单词用空格隔开");
String s = sc.nextLine();
char [] ch = s.toCharArray();
int count = 0;
System.out.println(ch.length);
for (int i = ch.length-1; i >=0; i--) {
    if(ch[i] == ' '){
        break;
    }
    count++;
}
System.out.println(count);


13,集合

在Java中,集合(Collection)是一组对象的容器,用于存储、操作和传输数据。Java集合框架提供了一组类和接口,用于表示和操作不同类型的集合对象。集合框架主要包括以下接口和类:

  1. Collection 接口:是所有集合类的根接口,定义了集合的基本操作,如添加、删除、遍历等。

  2. List 接口:继承自 Collection 接口,表示有序的集合,允许重复元素,常见的实现类有 ArrayList、LinkedList。

  3. Set 接口:继承自 Collection 接口,表示不允许重复元素的集合,常见的实现类有 HashSet、TreeSet。

  4. Map 接口:不属于 Collection 接口的一部分,用于表示键值对的映射关系,常见的实现类有 HashMap、TreeMap。

集合存储数据类型的特点:

  • 不能存储基本数据类型,需要变成包装类

  • 可存储引用数据类型

集合和数组对比

  • 长度

    • 数组长度固定

    • 集合长度可变

  • 存储类型

    • 数组可以存基本数据类型和引用数据类型

    • 集合可存引用数据类型,和保证类

构造方法和成员方法

方法名说明
ArrayList<String> 集合名 =new ArrayList<>();创建一个空集合
boolean add(E e)添加元素,返回值表示是否添加成功
boolean remove(E e)删除元素,返回值表示是否删除成功
E remove(int index)删除指定索引的元素,返回被删除元素
E set(int index,E e)修改指定索引的元素,返回原来的元素
E get(int index)获取指定索引元素
int size()集合的长度,也就是集合中元素的个数
ArrayList<String> list =new ArrayList<>();
boolean re = list.add("aaa");
list.add("bb");
list.add("ccc");
list.add("aaa");
System.out.println("添加"+re);         //添加true
System.out.println("添加后"+list);     //添加后[aaa, bb, ccc, aaa]
boolean aaaa = list.remove("aaa");      
System.out.println("删除"+aaaa);       //删除true
String remove = list.remove(1);  
System.out.println("删除指定下标的元素,被删除元素:"+remove);  //删除指定下标的元素,被删除元素:ccc
String set = list.set(1,"bbbb");
System.out.println("修改指定下标元素,被修改元素:"+set);       //修改指定下标元素,被修改元素:aaa
String get = list.get(0);
System.out.println("获取指定下标元素:"+get);                //获取指定下标元素:bb
int len = list.size();
System.out.println("集合长度"+len);  //集合长度2
System.out.println(list);           //[bb, bbbb]

//练习

1,集合的遍历方式

ArrayList<String> list = new ArrayList<>();
list.add("你吃了吗?");
list.add("你喝了吗?");
list.add("你睡了吗?");
list.add("你想我了吗?");
System.out.print("[");
for (int i = 0; i < list.size(); i++) {
if(i==list.size()-1){
System.out.print(list.get(i));
}else {
System.out.print(list.get(i)+",");
}
}
System.out.println("]");

2,添加数字并遍历

//不能添加基本数据类型,应该添加基本数据类型对应的包装类
ArrayList<Integer> list = new ArrayList<>();
list.add(123);
list.add(234);
list.add(345);
list.add(456);
//其他同上
基本数据类型所对应的包装类
byteByte
shortShort
charCharacter
intInteger
longLong
floatFloat
doubleDouble
booleanBoolean

3,添加学生对象并遍历

//先创建学生类
public class Student {
private String name;
private String xuehao;
private int age;
private String gender;
​
public Student() {
}
​
public Student(String name, String xuehao, int age, String gender) {
this.name = name;
this.xuehao = xuehao;
this.age = age;
this.gender = gender;
}
​
public String getName() {
return name;
}
​
public void setName(String name) {
this.name = name;
}
​
public String getXuehao() {
return xuehao;
}
​
public void setXuehao(String xuehao) {
this.xuehao = xuehao;
}
​
public int getAge() {
return age;
}
​
public void setAge(int age) {
this.age = age;
}
​
public String getGender() {
return gender;
}
​
public void setGender(String gender) {
this.gender = gender;
}
}
//测试类
//创建集合
ArrayList<Student> list = new ArrayList<>();
//创建学生对象
Student s1 = new Student("zhangsan", "123", 20, "女");
Student s2 = new Student("lisi", "124", 20, "男");
Student s3 = new Student("wangpin", "125", 20, "女");
//添加元素
list.add(s1);
list.add(s2);
list.add(s3);
//遍历
for (int i = 0; i < list.size(); i++) {
Student stu = list.get(i);
System.out.println(stu.getName() + "," + stu.getXuehao() + "," + stu.getAge() + ","+stu.getGender());
}

//以上练习改进成键盘录入学生信息

//创建集合
ArrayList<Student> list = new ArrayList<>();
//键盘录入学生
Scanner sc = new Scanner(System.in);
for (int i = 0; i < 3; i++) {
Student s = new Student();   //创建学生对象
//输入信息
System.out.println("请输入第"+i+"个学生的姓名,学号,年龄,性别(按顺序输入)!");
String name = sc.next();
String xuehao = sc.next();
int age = sc.nextInt();
String gender = sc.next();
//添加到学生对象
s.setName(name);
s.setXuehao(xuehao);
s.setAge(age);
s.setGender(gender);
//学生对象添加到集合
list.add(s);
}
//遍历
for (int i = 0; i < list.size(); i++) {
Student stu = list.get(i);
System.out.println(stu.getName() + "," + stu.getXuehao() + "," + stu.getAge() + ","+stu.getGender());
}

4,添加学生对象并且判断用户是否存在

//创建集合
ArrayList<Student> list = new ArrayList<>();
//创建学生对象
Student s1 = new Student("zhangsan", "123", 20, "女");
Student s2 = new Student("lisi", "124", 20, "男");
Student s3 = new Student("wangpin", "125", 20, "女");
list.add(s1);
list.add(s2);
list.add(s3);
//键盘录入学生
Scanner sc = new Scanner(System.in);
while (true) {
Student s = new Student();   //创建学生对象
//输入信息
System.out.println("请输入学生的姓名,学号,年龄,性别(按顺序输入)!");
String name = sc.next();
String xuehao = sc.next();
int age = sc.nextInt();
String gender = sc.next();
//判断对象是否存在
boolean t = panduan(list,xuehao);//将学号的字符串类型改成整型
System.out.println(t);
break;
}
​
}
public static  boolean panduan(ArrayList<Student> list,String xuehao){
Student stu = new Student();
for (int i = 0; i < list.size(); i++) {
stu = list.get(i);
if(stu.getXuehao().equals(xuehao)){
return true;
}
}
return false;
}

5,创建手机对象,定义一个方法返回小于3000的手机

public static void main(String[] args) {
        ArrayList<Phone> list = new ArrayList<>();
        //添加手机对象元素
        Phone p1= new Phone("华为", 8999);
        Phone p2= new Phone("荣耀", 2999);
        Phone p3= new Phone("三星", 1999);
        list.add(p1);
        list.add(p2);
        list.add(p3);
        //调用方法
        ArrayList<Phone> resultePhone = test(list);
        for (int i = 0; i < resultePhone.size(); i++) {
            Phone p = resultePhone.get(i);
            System.out.println(p.getName()+p.getPrice());
        }
    }
    public static ArrayList<Phone> test(ArrayList<Phone> list){
        ArrayList<Phone>  resultPhone = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            Phone phone = list.get(i);
            if(phone.getPrice()<3000){
                resultPhone.add(phone);
            }
        }
        return resultPhone;
    }

学生管理系统

需求:采取控制台的方式书写学生管理系统

分析:

初始菜单:

"__________学生管理系统__________"
 "1:添加学生"
 "2:删除学生"
 "3:修改学生"
 "4:查询学生"
 "5:退出"
 "请输入您的选择:"
  • 学生类:属性:ID、姓名、年龄、家庭住址

  • 添加功能:键盘录入每一个学生信息并添加,需要满足ID唯一

  • 删除功能:id存在,删除,不存在提示不存在并返回初始菜单

  • 修改功能:id存在,继续录入其他信息,不存在返回初始菜单

  • 查询功能:打印所有学生信息,没有则提示

//学生类
public class Student {
    private String name;
    private String id;
    private int age;
    private String address;
​
    public Student() {
    }
​
    public Student(String name, String id, int age, String address) {
        this.name = name;
        this.id = id;
        this.age = age;
        this.address = address;
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
​
    public String getId() {
        return id;
    }
​
    public void setId(String id) {
        this.id = id;
    }
​
    public int getAge() {
        return age;
    }
​
    public void setAge(int age) {
        this.age = age;
    }
​
    public String getAddress() {
        return address;
    }
​
    public void setAddress(String address) {
        this.address = address;
    }
}
import java.util.ArrayList;
import java.util.Scanner;
​
public class main {
    public static void main(String[] args) {
        Student s1 = new Student("张三", "a201201", 16, "四川成都");
        Student s2 = new Student("李四", "a201202", 17, "四川绵阳");
        Student s3 = new Student("王五", "a201203", 18, "四川乐山");
        Student s4 = new Student("陈陆", "a201204", 19, "四川成都");
        ArrayList<Student> list = new ArrayList<>();
        list.add(s1);
        list.add(s2);
        list.add(s3);
        list.add(s4);
        loop:
        while (true) {
            System.out.println("__________学生管理系统__________");
            System.out.println("1:添加学生");
            System.out.println("2:删除学生");
            System.out.println("3:修改学生");
            System.out.println("4:查询学生");
            System.out.println("5:退出学生");
            System.out.println("请输入您的选择");
            Scanner sc = new Scanner(System.in);
            String choose = sc.next();
            switch (choose) {
                case "1" -> AddStudent(list);
                case "2" -> deleteStudent(list);
                case "3" -> updateStudent(list);
                case "4" -> queryStudent(list);
                case "5" -> {
                    System.out.println("退出!");
                    break loop;
                }
                default -> System.out.println("没有这个功能");
            }
        }
​
    }
​
    //添加功能
    public static void AddStudent(ArrayList<Student> list) {
        //利用空参创建学生对象
        Student stu = new Student();
        //添加信息
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入要添加的学生姓名!");
        String name = sc.next();
        stu.setName(name);
​
        while (true) {
            System.out.println("请输入要添加的学生学号!");
            String id = sc.next();
            boolean flag = contains(list, id);
            if (flag) {
                stu.setId(id);
                break;
            } else {
                System.out.println("学号不能重复,请重新录入!");
            }
        }
​
        System.out.println("请输入要添加的学生年龄!");
        int age = sc.nextInt();
        stu.setAge(age);
​
        System.out.println("请输入要添加的学生地址!");
        String address = sc.next();
        stu.setAddress(address);
        //添加到集合中
        list.add(stu);
        //提示
        System.out.println("学生信息添加成功");
    }
​
    //删除功能
    public static void deleteStudent(ArrayList<Student> list) {
        System.out.println("请输入要删除的学生学号:");
        Scanner sc = new Scanner(System.in);
        String Id = sc.next();
        int index = getindex(list, Id);
        if(index>=0){
            list.remove(index);
        }else {
            System.out.println("ID不存在,删除失败!");
        }
​
    }
​
    //修改功能
    public static void updateStudent(ArrayList<Student> list) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入要修改的学生学号:");
        String id = sc.next();
        int index = getindex(list,id);
        if(index>=0){
            Student stu = new Student();
            stu = list.get(index);
            System.out.println("请输入要修改的学生姓名:");
            String name = sc.next();
            stu.setName(name);
            System.out.println("请输入要修改的学生年龄:");
            int age = sc.nextInt();
            stu.setAge(age);
            System.out.println("请输入要修改的学生地址:");
            String address = sc.next();
            stu.setAddress(address);
        }else {
            System.out.println("这个ID不存在,返回失败!");
        }
    }
​
    //查询功能
    public static void queryStudent(ArrayList<Student> list) {
        if (list.size() == 0) {
            System.out.println("当前无学生信息,请添加后再查找");
            return; //结束方法
        }
        System.out.println("学号\t\t姓名\t年龄\t家庭地址");
        for (int i = 0; i < list.size(); i++) {
            Student stu = new Student();
            stu = list.get(i);
            System.out.println(stu.getId() + "\t\t" + stu.getName() + "\t" + stu.getAge() + "\t\t" + stu.getAddress());
        }
    }
​
    //判断id是否存在
    public static boolean contains(ArrayList<Student> list, String id) {
        return getindex(list, id) < 0;
    }
​
    //通过id获取索引
    public static int getindex(ArrayList<Student> list, String id) {
        for (int i = 0; i < list.size(); i++) {
            Student stu = list.get(i);
            if (stu.getId().equals(id)) {
                return i;
            }
        }
        return -1;
    }
}
​

学生管理系统升级版

需求

  1. 为学生管理系统写一个登录、注册、忘记密码的功能。

  2. 只有用户成功登陆后,才能进入到学生管理系统中

分析

登录:

System.out.println("欢迎来到学生管理系统!");
System.out.println("请选择操作:1登录2注册3忘记密码");

初始菜单:

"欢迎来到学生管理系统"
"请选择操作:1登录  2注册  3忘记密码"
  • 学生类:用户名、密码、身份证号、手机号码

  • 注册

    • 用户名唯一、长度3~15、字母加数字组合

  • 密码输入两次,两次一致才可注册

  • 身份证长度18,不以0开头,前17位必须为数字,最后一位是数字或是大小写x。

  • 手机号11位,不以0开头

  • 登录

    • 显示未注册,结束方法,提示用户名未注册请先注册

    • 判断验证码是否正确,如果不正确重新输入

    • 判断用户名和密码是否正确,3次机会

  • 忘记密码

    • 输入用户名,不存在提示用户不存在请先注册

    • 键盘输入手机号和身份证号

    • 判断当前用户手机号和身份证号是否一致

      • 一致:提示输入密码,进行修改

      • 不一致:提示账号信息不匹配,修改失败

//User
package StudentAPP;
​
public class User {
    public String userName;
    public String password;
    public String userID;
    public String phoneNumber;
​
    public User() {
​
    }
​
    public User(String userName, String password, String userID, String phoneNumber) {
        this.userName = userName;
        this.password = password;
        this.userID = userID;
        this.phoneNumber = phoneNumber;
    }
​
    public String getUserName() {
        return userName;
    }
​
    public void setUserName(String userName) {
        this.userName = userName;
    }
​
    public String getPassword() {
        return password;
    }
​
    public void setPassword(String password) {
        this.password = password;
    }
​
    public String getUserID() {
        return userID;
    }
​
    public void setUserID(String userID) {
        this.userID = userID;
    }
​
    public String getPhoneNumber() {
        return phoneNumber;
    }
​
    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }
}
​
//student
package StudentAPP;
​
public class Student {
    private String name;
    private String id;
    private int age;
    private String address;
​
    public Student() {
    }
​
    public Student(String name, String id, int age, String address) {
        this.name = name;
        this.id = id;
        this.age = age;
        this.address = address;
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
​
    public String getId() {
        return id;
    }
​
    public void setId(String id) {
        this.id = id;
    }
​
    public int getAge() {
        return age;
    }
​
    public void setAge(int age) {
        this.age = age;
    }
​
    public String getAddress() {
        return address;
    }
​
    public void setAddress(String address) {
        this.address = address;
    }
}
​
//studenSystem
package StudentAPP;
​
import java.util.ArrayList;
import java.util.Scanner;
​
public class studenSystem {
    public static void startStudenSystem() {
        Student s1 = new Student("张三", "a201201", 16, "四川成都");
        Student s2 = new Student("李四", "a201202", 17, "四川绵阳");
        Student s3 = new Student("王五", "a201203", 18, "四川乐山");
        Student s4 = new Student("陈陆", "a201204", 19, "四川成都");
        ArrayList<Student> list = new ArrayList<>();
        list.add(s1);
        list.add(s2);
        list.add(s3);
        list.add(s4);
        loop:
        while (true) {
            System.out.println("__________学生管理系统__________");
            System.out.println("1:添加学生");
            System.out.println("2:删除学生");
            System.out.println("3:修改学生");
            System.out.println("4:查询学生");
            System.out.println("5:退出学生");
            System.out.println("请输入您的选择");
            Scanner sc = new Scanner(System.in);
            String choose = sc.next();
            switch (choose) {
                case "1" -> AddStudent(list);
                case "2" -> deleteStudent(list);
                case "3" -> updateStudent(list);
                case "4" -> queryStudent(list);
                case "5" -> {
                    System.out.println("退出!");
                    break loop;
                }
                default -> System.out.println("没有这个功能");
            }
        }
​
    }
​
    //添加功能
    public static void AddStudent(ArrayList<Student> list) {
        //利用空参创建学生对象
        Student stu = new Student();
        //添加信息
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入要添加的学生姓名!");
        String name = sc.next();
        stu.setName(name);
​
        while (true) {
            System.out.println("请输入要添加的学生学号!");
            String id = sc.next();
            boolean flag = contains(list, id);
            if (flag) {
                stu.setId(id);
                break;
            } else {
                System.out.println("学号不能重复,请重新录入!");
            }
        }
​
        System.out.println("请输入要添加的学生年龄!");
        int age = sc.nextInt();
        stu.setAge(age);
​
        System.out.println("请输入要添加的学生地址!");
        String address = sc.next();
        stu.setAddress(address);
        //添加到集合中
        list.add(stu);
        //提示
        System.out.println("学生信息添加成功");
    }
​
    //删除功能
    public static void deleteStudent(ArrayList<Student> list) {
        System.out.println("请输入要删除的学生学号:");
        Scanner sc = new Scanner(System.in);
        String Id = sc.next();
        int index = getindex(list, Id);
        if(index>=0){
            list.remove(index);
        }else {
            System.out.println("ID不存在,删除失败!");
        }
​
    }
​
    //修改功能
    public static void updateStudent(ArrayList<Student> list) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入要修改的学生学号:");
        String id = sc.next();
        int index = getindex(list,id);
        if(index>=0){
            Student stu = new Student();
            stu = list.get(index);
            System.out.println("请输入要修改的学生姓名:");
            String name = sc.next();
            stu.setName(name);
            System.out.println("请输入要修改的学生年龄:");
            int age = sc.nextInt();
            stu.setAge(age);
            System.out.println("请输入要修改的学生地址:");
            String address = sc.next();
            stu.setAddress(address);
        }else {
            System.out.println("这个ID不存在,返回失败!");
        }
    }
​
    //查询功能
    public static void queryStudent(ArrayList<Student> list) {
        if (list.size() == 0) {
            System.out.println("当前无学生信息,请添加后再查找");
            return; //结束方法
        }
        System.out.println("学号\t\t姓名\t年龄\t家庭地址");
        for (int i = 0; i < list.size(); i++) {
            Student stu = new Student();
            stu = list.get(i);
            System.out.println(stu.getId() + "\t\t" + stu.getName() + "\t" + stu.getAge() + "\t\t" + stu.getAddress());
        }
    }
​
    //判断id是否存在
    public static boolean contains(ArrayList<Student> list, String id) {
        return getindex(list, id) < 0;
    }
​
    //通过id获取索引
    public static int getindex(ArrayList<Student> list, String id) {
        for (int i = 0; i < list.size(); i++) {
            Student stu = list.get(i);
            if (stu.getId().equals(id)) {
                return i;
            }
        }
        return -1;
    }
}
​
//app
package StudentAPP;
​
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
​
public class APP {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        ArrayList<User> list = new ArrayList<>();
        System.out.println("欢迎来到学生管理系统!");
        while (true) {
            System.out.println("请选择操作:1登录  2注册  3忘记密码");
            int order = sc.nextInt();
            switch (order) {
                case 1 -> land(list);
                case 2 -> login(list);
                case 3 -> forgetPassword(list);
                default -> System.out.println("没有这个选项,请重新输入!");
            }
        }
​
    }
​
    private static void forgetPassword(ArrayList<User> list) {
        Scanner sc = new Scanner(System.in);
        String userName;
        System.out.println("请输入用户名:");
        userName = sc.next();
        boolean flag = checkUserName(list, userName);
        if (flag) {
            System.out.println("用户未" + userName + "注册,请先注册!");
            return;
        }
​
        System.out.println("请输入手机号码");
        String phoneNumber = sc.next();
        System.out.println("请输入身份证号码");
        String personID = sc.next();
        User u = new User();
        for (int i = 0; i < list.size(); i++) {
            u = list.get(i);
            if (!(u.getPhoneNumber().equals(phoneNumber) && u.getUserID().equals(personID))) {
                System.out.println("账号信息不匹配,修改失败!");
            } else {
                break;
            }
        }
        System.out.println("请输入密码:");
        String password = sc.next();
        System.out.println("请再一次输入密码:");
        String againPassWord = sc.next();
        if (!password.equals(againPassWord)) {
            System.out.println("两次密码输入不一致,请重新输入");
        } else {
            u.setPassword(password);
            System.out.println("修改密码成功,请重新登录!");
            getPrintList(list);
        }
    }
​
    private static void login(ArrayList<User> list) {
        Scanner sc = new Scanner(System.in);
        User u1 = new User();
        String userName;
        while (true) {
            System.out.println("请输入用户名:");
            userName = sc.next();
            boolean flag = checkUserName(list, userName);
            if (!flag) {
                System.out.println("用户名已存在,请重新输入");
                continue;
            }
            boolean flag1 = CheckUserNameSuper(userName);
            if (!flag1) {
                System.out.println("用户名长度必须在3~15之间,字母加数字组合,请重新输入");
                continue;
            } else {
                u1.setUserName(userName);
                break;
            }
        }
        String passWord;
        while (true) {
            System.out.println("请输入密码:");
            passWord = sc.next();
            System.out.println("请再一次输入密码:");
            String againPassWord = sc.next();
            boolean flag2 = isCheckPassWord(passWord, againPassWord);
            if (!flag2) {
                System.out.println("两次密码输入不一致,请重新输入!");
                continue;
            } else {
                u1.setPassword(passWord);
                break;
            }
        }
        String userId;
        while (true) {
            System.out.println("请输入身份证号码:");
            userId = sc.next();
            boolean flag = checkUserId(userId);
            if (flag) {
                u1.setUserID(userId);
                break;
            } else {
                System.out.println("身份证格式错误,请重新输入!");
                continue;
            }
        }
        String userPhoneNumber;
        while (true) {
            System.out.println("请输入手机号码:");
            userPhoneNumber = sc.next();
            boolean flag = checkUserPhoneNumber(userPhoneNumber);
            if (!flag) {
                System.out.println("手机号码格式错误,请重新输入!");
                continue;
            } else {
                u1.setPhoneNumber(userPhoneNumber);
                break;
            }
​
        }
        u1.setUserName(userName);
        list.add(u1);
        System.out.println("注册成功!");
        getPrintList(list);
    }
​
    private static void getPrintList(ArrayList<User> list) {
        for (int i = 0; i < list.size(); i++) {
            User u = list.get(i);
            System.out.println(u.getUserName() + "," + u.getPassword() + ","
                    + u.getUserID() + "," + u.getPhoneNumber());
        }
    }
​
    private static boolean checkUserPhoneNumber(String userPhoneNumber) {
        if (!(userPhoneNumber.length() == 11)) {
            return false;
        }
        char[] c = userPhoneNumber.toCharArray();
        if (c[0] == 0) {
            return false;
        }
        return true;
    }
​
    private static boolean checkUserId(String userId) {
        if (userId.length() != 18) {
            return false;
        }
        if (userId.startsWith("0")) {
            return false;
        }
        for (int i = 0; i < userId.length() - 1; i++) {
            char c = userId.charAt(i);
            if (!(c >= '0' && c <= '9')) {
                return false;
            }
        }
        char endID = userId.charAt(userId.length() - 1);
        if ((endID >= '0' && endID <= '9') || (endID == 'x') || (endID == 'X')) {
            return true;
        } else {
            return false;
        }
    }
​
    private static boolean isCheckPassWord(String passWord, String againPassWord) {
        if (passWord.equals(againPassWord)) {
            return true;
        }
        return false;
    }
​
    private static boolean CheckUserNameSuper(String userName) {
        int len = userName.length();
        if (len < 3 || len > 15) {
            return false;
        }
        for (int i = 0; i < len; i++) {
            char c = userName.charAt(i);
            if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'))) {
                return false;
            }
        }
        int count = 0;
        for (int i = 0; i < len; i++) {
            char c = userName.charAt(i);
            if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
                count++;
            }
        }
        return count > 0;
​
    }
​
    private static void land(ArrayList<User> list) {
        Scanner sc = new Scanner(System.in);
        String userName;
        while (true) {
            System.out.println("请输入用户名:");
            userName = sc.next();
            boolean flag = checkUserName(list, userName);
            if (!flag) {
                break;
            } else {
                System.out.println("用户未" + userName + "注册,请先注册!");
                return;
            }
        }
        //生成验证码
        while (true) {
            System.out.println("当前验证码为:");
            String captcha = getCaptcha();
            System.out.println(captcha);
            System.out.println("请输入验证码");
            String code = sc.next();
            if (!(captcha.equalsIgnoreCase(code))) {
                System.out.println("验证码输入错误,请重新输入!");
                continue;
            } else {
                break;
            }
        }
        //判断用户名和密码是否正确,3次机会。
        for (int i = 0; i < 3; i++) {
            boolean flag = checkUserNamePassword(list, userName);
            if (flag) {
                System.out.println("登录成功,欢迎使用学生管理系统!");
                //创建对象调用方法,启用学生管理系统
                studenSystem ss = new studenSystem();
                ss.startStudenSystem();
                break;
            }
            if (i == 2) {
                System.out.println("账号被锁定,请联系管理员!");
            } else {
                System.out.println("账户" + userName + "还有" + (2 - i) + "次机会");
            }
        }
    
​
​
    }
​
    private static boolean checkUserNamePassword(ArrayList<User> list, String userName) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入密码:");
        String passWord = sc.next();
        for (int i = 0; i < list.size(); i++) {
            User u = list.get(i);
            if ((u.getUserName().equals(userName)) && (u.getPassword().equals(passWord))) {
                return true;
            }
        }
        return false;
    }
​
    private static String getCaptcha() {
        ArrayList<Character> arr = new ArrayList<>();
        for (int i = 0; i < 26; i++) {
            arr.add((char) ('a' + i));
            arr.add((char) ('A' + i));
        }
        StringBuilder sb = new StringBuilder();
        Random rd = new Random();
        for (int i = 0; i < 4; i++) {
            int index = rd.nextInt(52);
            char c = arr.get(index);
            sb.append(c);
        }
        int c = rd.nextInt(10);
        sb.append(c);
        char[] list = sb.toString().toCharArray();
        int maxIndex = rd.nextInt(list.length);
        char temp = list[maxIndex];
        list[maxIndex] = list[list.length - 1];
        list[list.length - 1] = temp;
        return new String(list);
    }
​
    private static boolean checkUserName(ArrayList<User> list, String userName) {
        for (int i = 0; i < list.size(); i++) {
            User u1 = list.get(i);
            if (u1.getUserName().equals(userName)) {
                return false;
            }
        }
        return true;
    }
​
}
​

13,static静态变量

(1)static

static表示静态,是java中的一个修饰符,可以修饰成员方法,成员变量

  1. 被static修饰的成员变量,成为静态变量

    特点:该类被所有类共享、不属于对象,属于类、随着类的加载而加载,优于对象存在

    调用方法:类名调用、对象名调用

  2. 被static修饰的成员方法,成为静态方法

    特点:多用在测试类和工具类中、JavaBean类中很少用

    调用方法:类名调用、对象名调用

JavaBean类:用来描述一些事物的类,比如Student、Teacher、Dog、Cat等

测试类:用来检查其他类是否书写正确,带有main方法的类,是程序的入口

工具类:帮助我们做一些事情,但是不描述任何事物的类

工具类:

  • 见名知意、私有化的构造方法、方法定义为静态

public class ArrUtil {
    private ArrUtil(){}
    public static int getMax(){}
    public static int getMin(){}
    public static int getSun(){}
    public static int getAvg(){}
}

练习

//定义数组工具类
//需求:1,prinArr方法返回整数数组内容.2,getAvg方法返回平均分。
package Test;
​
public class ArrUtil {
    //私有化构造方法,为了不让外界创建它的对象
    private ArrUtil(){}
    public static int getSun(int [] arr){
        int Sun = arr[0];
        for (int i = 1; i < arr.length; i++) {
            Sun +=arr[i];
        }
        return Sun;
    }
    public static int getAvg(int [] arr){
        int sun = getSun(arr);
        return sun/arr.length;
    }
    public static void printArr(int [] arr){
        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("]");
    }
}
//定义测试类调用该工具类的方法,并返回结果。
package Test;
​
public class test {
    public static void main(String[] args) {
        int [] arr = {3,4,5,6,9,12,33,18,8,4,7};
        System.out.print("遍历数组:");
        ArrUtil.printArr(arr);
        int sun = ArrUtil.getSun(arr);
        System.out.println("数组和:"+sun);
        int avg = ArrUtil.getAvg(arr);
        System.out.println("平均数:"+avg);
​
    }
}

重新认识mian方法

  • public:被jvm(虚拟机)调用,访问权限足够大

  • static:被jvm调用,不用创建对象,直接类名访问

    因为main方法是静态的,所以测试类中其他方法也需要是静态的

  • void:被jvm调用,不需要给jvm返回值

  • main:一个通用的名称,虽然不是关键字,但是被jvm识别

  • String[] args: 以前用于接收键盘录入数据的,现在没用

注意

  • 静态方法只能访问静态变量和静态方法

  • 非静态方法可以访问所有(静态\非静态的(成员)变量\方法)

  • 静态方法是没有this关键字

总结:

  • 静态方法中,只能访问静态

  • 非静态方法可以访问所有

  • 静态方法无this关键字

(2)继承

面向对象三大特性:封装、继承、多态。

  • 封装:对象代表说明,就得封装对应的数据,并提供数据对应的行为

  • 继承:java提供的一个关键字extends,可以让一个类和另一个类建立起继承关系。public class Student extends Person{}

    • 子类可以在父类的基础上添加新功能,继承父类方法和变量

当类与类之间,存在相同(共性)的内容,并满足子类是父类中的一种,就可以考虑使用继承,来优化代码。子类只能访问父类中非私有的成员


继承的特点:java只支持单继承,不支持多继承,但支持多层继承

每一个类都直接或间接的继承于Object类。


练习:设计一个继承体系

布偶猫(吃饭喝水抓老鼠)、狸花猫(吃饭喝水抓老鼠)、哈士奇(吃饭喝水看家拆家)、泰迪(吃饭喝水看家蹭蹭) 画图法:画出父类子类之间的关系。共性内容网上抽取、子类是父类的一种。

  • 动物(吃饭喝水)

    • 猫(吃饭喝水抓老鼠)

      • 布偶

      • 狸花

    • 狗(看家)

      • 哈士奇(拆家)

      • 泰迪(蹭蹭)


能否继承
成员变量非私有 能private 能
成员方法非私有 能private 不能
构造方法非私有 不能private 不能

继承中:成员变量的访问特点:

  • 就近原则(谁近用谁)

  • super调用,到父类查找


方法重写:当父类的方法不能满足子类现在的需求时,需要进行方法重写

书写格式:继承体系中子类和父类中一摸一样的方法声明,我们就称子类这个方法是重写的方法。

@Override重写注释:放在重写后的方法上,校验子类重写的语法是否正确。语法错误会出现红色波浪线。

如果子类的方法重回写,虚方法表会被覆盖。


继承中:成员方法的特点:

  • 重写方法名称、行式与父类保持一致

  • 访问权限子类大于等于父类

  • 返回值类型小于等于父类

  • 重写方法尽量与父类保持一致

  • 只有被添加到虚方法表中的方法才能被重写。


继承中:构造方法的访问特点:

  • 子类不能继承父类的构造方法,但是可以通过super调用

  • 子类构造方法地第一行,有一个默认super()。

  • 子类中所有的构造方法默认先访问父类的无参构造,再执行自己。

  • 如果想要调用父类的有参构造,必须手动书写。


this、super方法:

  • this:理解为一个变量,表示当前方法调用者的地址值。

  • super:代表父类存储空间。

(3)多态
  • 多态:同类型的对象,表现出不同形态。对象的多种形态。

  • 表现行式:父类类型 对象名称 = 子类对象;

  • 多态前提: Fu f = new Zi();

    • 有继承关系

    • 有父类引用指向子类

    • 有方法重写

  • 好处:使用父类型作为参数,可以接收所有子类对象。体现了多态的扩展性与遍历。

  • 多态的应用场景

    • 继承与派生、接口实现、泛型等。

//简单运用
//____________________Persion类_______________________
package Test1;
​
public class Person {
    private String name;
    private int age;
..........标准JavaBean
    public void show(){
        System.out.println(name+","+age);
    }
}
//____________________Student类_______________________
package Test1;
​
public class Student extends Person{
    @Override
    public void show(){
        System.out.println("学生的信息为"+getName()+","+getAge());
    }
}
//____________________Teacher类_______________________
package Test1;
​
public class Teacher extends Person{
    @Override
    public void show(){
        System.out.println("老师的信息为"+getName()+","+getAge());
    }
}
//_________________Administrator类____________________
package Test1;
​
public class Administrator extends Person{
    @Override
    public void show(){
        System.out.println("管理员的信息为"+getName()+","+getAge());
    }
}
//_______________________测试类________________________
package Test1;
​
public class Test {
    public static void main(String[] args) {
        Student s = new Student();
        s.setName("张三");
        s.setAge(18);
        Teacher t = new Teacher();
        t.setName("王志成");
        t.setAge(30);
        Administrator a = new Administrator();
        a.setName("陈建国");
        a.setAge(45);
        //调用rigister函数
        rigister(s);
        rigister(t);
        rigister(a);
    }
    //这个方法能接收老师、学生、管理员信息
    //可以把参数写成这三个类型的父类
    public static void rigister(Person p){
        p.show();
    }
}
​
  • 多态调用成员的特点

    • 变量调用:编译看左边,运行也看左边。

      • javac编译代码时先看左边父类有没有这个变量,有则成功,无则失败。

      • java运行代码的时候,实际获取的时左边父类中成员变量的值。

    • 方法调用:编译看左边,运行看右边。

      • javac编译代码时先看左边父类有没有这个方法,有则成功,无则失败。

      • java运行代码的时候,实际获取的时右边子类中的方法。

    Animal a = new Dog();
    //对象是Animal类型的,用a调用变量和方法时默认调用父类的方法和变量。

    成员变量:在子类的对象中,会把父类的成员变量也继承下的。 成员方法:如果子类对方法进行了重写,那么在虚方法表中是会把父类的方法进行覆盖的。

    简单举例

    //____________________Animal类_______________________
    public class Animal {
        String name = "花花";
        int age = 5;
    .............标准JavaBean
        public void show(){
            System.out.println("动物");
        }
    }
    //____________________Dog类_______________________
    public class Dog extends Animal{
        String name = "朵朵";
        int age = 2;
        @Override
        public void show(){
            System.out.println("狗狗");
        }
    }
    //____________________test类_______________________
    public class test {
        public static void main(String[] args) {
            Animal a = new Dog();
            System.out.println(a.getName()+","+ a.getAge());
            a.show();
        }
    }
    //____________________输出结果_______________________
    花花,5
    狗狗

多态优势

  • 方法中,使用父类作为参数,可以接收所有子类对象

  • 在多态形势下,右边对象可以实现解耦合,便于扩展和维护。

  • 定义方法的时候,使用父类型作为参数,可以接收所有的子类对象,体现多态的扩展性与遍历。

StringBuilder和集合类型的变量可以添加任意类型。

多态弊端

  • 不能调用子类的特有功能

    • 解决方案:Dog d = (Dog)a; //变回子类类型

    • 细节:转换时候不瞎转,先判断 a instanceof Dog(如果a是Dog类型返回true,否则返回false)

    • Java新特性:判断和强转结合 。 a instanceof Dog d (如果是则强转成Dog类型,转换之后变量为d,如果不是不强转,结果false)

//练习
package Test2;
​
public class test {
    public static void main(String[] args) {
        Person p1 = new Person("老王",30);
        Dog d = new Dog("黑色",2);
        Cat c = new Cat("橘黄色",3);
        p1.keepPet(d,"狗粮");
        Person p2 = new Person("老李",34);
        p2.keepPet(c,"鱼");
    }
}
    class Animal{
        private String color;
        private int age;
        public void eat(String somgthing){
            System.out.println("吃"+somgthing);
        }
​
        public Animal() {
        }
​
        public Animal(String color, int age) {
            this.color = color;
            this.age = age;
        }
​
        public String getColor() {
            return color;
        }
​
        public void setColor(String color) {
            this.color = color;
        }
​
        public int getAge() {
            return age;
        }
​
        public void setAge(int age) {
            this.age = age;
        }
    }
     class Dog extends Animal{
         String color ;
         int age ;
        @Override
         public void eat(String somgthing){
             System.out.println(getAge()+"岁的"+getColor()+"的狗狗吃狗粮");
         }
         public void lookHome(){
             System.out.println("看家");
         }
​
         public Dog(String color, int age) {
            super(color,age);
             this.color = color;
             this.age = age;
         }
​
         @Override
         public String getColor() {
             return color;
         }
​
         @Override
         public void setColor(String color) {
             this.color = color;
         }
​
         @Override
         public int getAge() {
             return age;
         }
​
         @Override
         public void setAge(int age) {
             this.age = age;
         }
     }
    class Cat extends Animal{
        String color;
        int age;
​
        public Cat(String color, int age) {
            super(color,age);
            this.color = color;
            this.age = age;
        }
​
        @Override
        public String getColor() {
            return color;
        }
​
        @Override
        public void setColor(String color) {
            this.color = color;
        }
​
        @Override
        public int getAge() {
            return age;
        }
​
        @Override
        public void setAge(int age) {
            this.age = age;
        }
​
        @Override
        public void eat(String somgthing){
            System.out.println(getAge()+"岁的"+getColor()+"的猫猫吃猫粮");
        }
        public void catchMouse(){
            System.out.println("抓老鼠");
        }
    }
    class Person {
        String name;
        int age;
​
        public Person() {
        }
​
        public Person(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 keepPet(Animal animal, String somgthing){
            if(animal instanceof Dog d){
                System.out.println("年龄为"+getAge()+"的"+getName()+"用"+somgthing+"喂养"+d.getAge()+"岁的"+d.getColor()+"的狗");
                d.eat(somgthing);
            }else if(animal instanceof Cat c){
                System.out.println("年龄为"+getAge()+"的"+getName()+"用"+somgthing+"喂养"+c.getAge()+"岁的"+c.getColor()+"的狗");
                c.eat(somgthing);
            }
        }
    }
​
​

(4)包、final、权限修饰符、代码块
  • 就是文件夹。用来管理各种不同功能的java类,方便代码后期维护。

    • 包的命名规则:公司域名反写+包的作用,需要全部英文小写,见名知意。

    • 使用其他类的规则

      • 使用同一个包中的类时,不需要导包。

      • 使用java.lang包(Java的核心包)中的类时,不需要导包。

      • 其他情况都需要导包。

      • 如果同时使用两个包中的同名类,需要用全名类。

    • 全类名:包名+类名

  • final 修饰方法、类、变量。被修饰后不能发生改变

    • 方法不能重写

    • 类不能被继承

    • 表示常量,只能赋值一次

      • 常量:实际开发当中,常量一般作为系统的配置信息,方便维护,提高可读性。命名规则:单个单词全大写;多个单词全大写,单词间用下划线隔开。

      • 细节:修饰基本数据类型时,记录的值不能发生改变。修饰引用数据类型时,内部的属性值可以改变,地址值不能改变(不能new)。

      • 核心:常量记录的数据不能变。

  • 权限修饰符

    • 用来控制一个成员能够被访问的范围。

    • 可以修饰成员变量、方法、构造方法、内部类。

修饰符同一个类中同一个包其他类不同包下的子类不同包下的无关类
private私有的可访问
空着不写,只能本包使用
protected受保护的
public公共的

权限修饰符的使用规则:

实际开发中,一般只用private和public。成员变量私有,方法公开。

如果方法中的代码时抽取其他方法中的共性代码,这个方阿飞一般也私有。

  • 代码块

    • 局部代码块:写在方法里面的代码块,目的节省空间,现已淘汰。

    public class Test{
        public static void main(String[] args){
            {
                int a = 10;
                System.out.println(a);
            }//代码执行到这里,a消失。
        }
    }
    • 构造代码块:写在成员位置的代码块,作用是把构造方法中重复代码抽取出来。优先于构造方法执行。不够灵活。

    public class Student{
        private String name;
        private int age;
        {
            System.out.println("开始创建对象了!");
        }
        public Student(){}
        public Student(String name,int age){
            this.name = name;
            this.age = age;
        }
    }
    • 静态代码块:就是在构造代码块前加上static关键字修饰。随着类的加载而加载,并且自动触发、只执行一次。

(5)抽象类和抽象方法
  • 抽象方法:将共性行为(方法)抽取到父类之后。

    由于每一个子类执行的内容是不一样的,所有在父类中不能确定具体的方法体。该方法就可以定义为抽象方法。

    • 定义格式:

      public abstract 返回值类型 方法名(参数列表);
  • 抽象类:拥有抽象方法的类叫抽象类。

    • 定义格式:

      public abstract class类名{}

注意事项:

  • 抽象类不能实例化,不能创建对象。

  • 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类。

  • 可以有构造方法,当创建子类对象时,给属性进行赋值。

  • 抽象类的子类

    • 要么重写抽象类中所有的抽象方法,(鼠标点击红色波浪线Alt+enter,选择第一个....methods)

    • 要么是抽象类。

//_________________Animal类____________________
public abstract class Animal {
    private String name;
    private int age;
​
    public Animal() {
    }
​
    public Animal(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 abstract void eat();
}
//_________________frog类____________________
package test;
​
public class Frog extends Animal{
    public Frog() {
    }
​
    public Frog(String name, int age) {
        super(name, age);
    }
​
    @Override
    public void eat() {
        System.out.println("青蛙在吃虫子");
    }
}
//_________________test类____________________
public static void main(String[] args) {
    Frog f = new Frog("小鹿",2);
    System.out.println(f.getName()+","+f.getAge());
    f.eat();
}

(6)接口

将具体实现细节从类中抽取出来。

  • 接口使用关键字interface来定义

    public interface 接口名{}
  • 接口不能实例化

  • 接口和类之间时实现关系,通过implements关键字表示

    public class 类名 implements 接口名{}
  • 接口的子类(实现类)

    • 要么重写接口中所有抽象方法

    • 要么时抽象类


注意

  • 接口和类的实现关系,可以单实现,也可以多实现。

    public class 类名 implements接口名1,接口名2{}
  • 实现类还可以在继承一个类的同时实现多个接口。

    public class 类名 extends 父类 implements接口名1,接口名2{}

练习

//Animal类同上
//Swin接口
package test;
​
public interface Swim {
    public abstract void swim();
}
​
//_________________frog类____________________
package test;
​
public class Frog extends Animal  implements Swim{
    public Frog() {
    }
​
    public Frog(String name, int age) {
        super(name, age);
    }
​
    @Override
    public void eat() {
        System.out.println("青蛙在吃虫子");
    }
    @Override
    public void swim() {
        System.out.println("青蛙会游泳");
    }
}
//_________________test类____________________
package test;
​
public class test {
    public static void main(String[] args) {
        Frog f = new Frog("小鹿",2);
        System.out.println(f.getName()+","+f.getAge());
        f.eat();
        f.swim();
        Rabbit r = new Rabbit();
        r.eat();
    }
}
​

接口中成员的特点

  • 成员变量

    • 只能时常量。默认修饰符:public static final

  • 构造方法

    • 没有

  • 成员方法

    • 只能时抽象方法。默认修饰符:public abstract


接口和类之间的关系

  • 类和类

    • 继承关系,只能单继承,但可以多层继承

  • 类和接口

    • 实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口。

  • 接口和接口

    • 继承关系,可以单继承,也可以多继承。如果实现类实现最下面的子接口,所有的抽象方法都要重写。


综合案例

package test1;
public class Person {
    private String name;
    private int age;
​
    public Person() {
    }
​
    public Person(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;
    }
}
package test1;
​
public abstract class Sporter extends Person{
    public abstract void study();
​
    public Sporter() {
    }
​
    public Sporter(String name, int age) {
        super(name, age);
    }
}
package test1;
​
public abstract class Coach extends Person{
    public abstract void teach();
​
    public Coach() {
    }
​
    public Coach(String name, int age) {
        super(name, age);
    }
}
package test1;
​
import javax.xml.transform.Source;
​
public class Basketball extends Sporter{
    public Basketball() {
    }
​
    public Basketball(String name, int age) {
        super(name, age);
    }
​
    @Override
    public void study() {
        System.out.println("篮球运动员在学篮球");
    }
}
​
package test1;
​
public class Pingpong extends Sporter implements Speakenglish{
    public Pingpong() {
    }
​
    public Pingpong(String name, int age) {
        super(name, age);
    }
​
    @Override
    public void study() {
        System.out.println("乒乓球运动员在学乒乓球");
    }
​
    @Override
    public void speak() {
        System.out.println("乒乓球运动员在说英语");
    }
}
package test1;
​
public class Bcoach extends Coach {
    public Bcoach() {
    }
​
    public Bcoach(String name, int age) {
        super(name, age);
    }
​
    @Override
    public void teach() {
        System.out.println("篮球教练在教篮球");
    }
}
package test1;
​
public class Pcoach extends Coach implements Speakenglish{
    @Override
    public void teach() {
        System.out.println("乒乓球教练在教乒乓球");
    }
​
    public Pcoach() {
    }
​
    public Pcoach(String name, int age) {
        super(name, age);
    }
​
    @Override
    public void speak() {
        System.out.println("乒乓球教练在说英语");
    }
}
package test1;
​
public interface Speakenglish {
    public abstract  void speak();
}
package test1;
​
public class test {
    public static void main(String[] args) {
        Pingpong p1 = new Pingpong("马冬梅",20);
        System.out.println(p1.getName()+","+p1);
        p1.speak();
        p1.study();
    }
}
​

JDK8以后接口中新增的方法

  • 允许在接口中定义默认方法,需要使用关键字default修饰。

    • 解决接口升级问题。

  • 接口中默认方法的定义格式:

    • 格式及范例

      public default 返回值类型 方法名(参数表){}
      public default void show(){}
  • 接口中默认方法的注意事项:

    • 默认方法不是抽象方法,所以不强制被重写。但是如果被重写,重写时候去掉default关键字。

    • public可以省略·,default不能省略·

    • 如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该对方进行重写。

  • 允许在接口中定义静态方法,需要用static修饰。

  • 接口中静态方法的定义格式:

    public static 返回值类型 方法名(参数列表){}
    public static void show(){}

  • 接口中静态方法的注意事项:

    • 静态方法只能通过接口名调用,不能通过实现类名或对象名调用

    • public可以省略·,static不能省略


JDK8以后接口中新增的方法

private不想为给外界提供

  • 接口中私有方法的定义格式:

    • //为默认方法服务
      private 返回值类型 方法名(参数列表){}
      private void show(){}
      //给静态方法服务
      private static 返回值类型 方法名(参数列表){}
      private static void show(){}


接口的应用

  • 接口代表规则,时行为的抽象。想要让哪个类拥有一个行为,就让这个类实现对应的接口就可以了。

  • 当一个方法的参数时接口实,可以传递接口所有实现类的对象,这个方式称之为接口多态。


适配器设计模式

设计模式就是解决各种问题的各种套路。

  • 当一个接口中抽象方法过多,但只需要其中一小部分时,就可以用适配器。

  • 实现步骤:

    • 编写中间类XXXAdapter,实现对应的接口。

    • 对接口中的抽象放大进行空实现。

    • 让真正的实现类继承中间类,并重写需要用到的方法。

(7)内部类
  1. 写在一个类里面的类。

  2. 类的五大成员:属性、方法、构造方法、代码块、内部类

  3. 内部类

    1. 内部类表示的事物是外部类的一部分

    2. 内部类单独出现没有任何意义

    3. 特点:可以访问外部类的成员,包括私有。外部类要访问内部类的成员,必须创建对象。

package test3;
​
public class Car {
    String carName;
    String carColor;
    int carAge;
    class Engine{
        String engineName;
        int engineAge;
    }
    public void show(){
        System.out.println(carName);
        Engine a = new Engine();
        System.out.println(a.engineName);
    }
}
/////////////////////////////////////////////////
package test3;
public class test {
    public static void main(String[] args) {
        Car c = new Car();
        c.carName = "小米";
        c.carAge = 2;
        c.carColor = "橘黄色";
        Car.Engine e = new Car().new Engine();
        e.engineName = "xiaomi";
        e.engineAge  = 2;
        c.show();
​
    }
}
​

  • 成员内部类

    • 写在成员位置的,属于外部类的成员。

    • 成员内部类可以被一些修饰符所修饰,比如:private,默认,protected,public,static等。

    • 如果内部类private修饰,测试类无法创建内部类对象

      • 解决方案1:将private改成public

      • 解决方案2:在外部类创建一个获取内部类对象的方法

      public Inner getInstance(){
          return new Inner();
      }
    • 外部类成员变量和内部类成员变量重名时,在内部类访问:

      System.out.println(Outer.this.变量名);  


  • 静态内部类

    • 用static修饰的内部类。

    • 静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态的需要创建对象。

    • 直接创建静态内部类对象的方式

      Outer.Inter oi = new Outer.Inner();
    • 如何调用静态内部类中的方法

      • 非静态方法:先创建对象,再用对象调用

      • 静态方法:外部类名.内部类名.方法名();


  • 局部内部类

    • 定义在方法里面类叫局部类,类似于方法里面的局部变量。

    • 外部无法直接使用,需要在方法内部创建对象并使用。

    • 该类可以直接访问外部类的成员,也可以访问方法内的局部变量。


  • 匿名内部类

    • 隐藏了名字的内部类。可以写在成员位置,也可以写在局部位置。

    • new 类名或接口名(){
      重写方法
      };
    • 使用场景

      • 当方法的参数时接口或者类时

      • 以接口为例,可以传递这个接口的实现类对象,

      • 如果实现类只使用一次,就可以用匿名内部类简化代码。


四、阶段项目

本文章已经生成可运行项目
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值