admin管理员组

文章数量:1598886

01-day-课程介绍、Java概述、IDEA、Java基础语法

1、Java的历史背景

  1. Java是什么?
    • 是一门高级编程语言
  2. Java是哪家公司研发的,现在属于哪家公司?
    • 1995年sun公司推出的一门计算机高级语言,2009年被Oracle公司收购
  3. Java之父是谁?
    • 詹姆斯.高斯林
  4. Java能做什么?
    • 基本上什么都可以干,主要做互联网系统的开发
  5. Java有哪些技术平台?
    • JavaSE(标准版)、JavaEE(企业版)、JavaME(小型版)

2、Java环境搭建:JDK安装、常用命令

  1. 搭建Java开发环境需要安装什么?去哪里下载?

    • JDK(Java Development Kit)开发者工具包,Oracle官网下载
  2. JDK目前发展到哪里了?LTS(long term support)版本有哪些?企业使用的JDK有什么特点?

    • 目前发展到jdk18,LTS版本有jdk8、11、17,很多企业使用jdk8,应为jdk8稳定
  3. 如何校验jdk是否安装成功了?

    • 在命令窗口中,输入java -version、javac -version看版本号
  4. Java开发环境重要的两个命令是什么?

    • javac编译命令、java执行命令
  5. 命令行窗口常用命令

    常用命令作用
    盘符:切换到某个盘符 d:,c:
    dir查看当前路径下的文件信息
    cd进入到单级目录 cd itheima;进入到多级目录 cd E:\BaiduNetdiskDownload\java_heima\day01;回到上一级目录cd…;回到根目录cd \
    cls清屏

3、Java入门HelloWorld

  1. 开发一个Java程序要经历哪些步骤?

    • 编写

      • public class HelloWorld{
        	public static void main(String [] args){
        		System.out.println("HelloWorld java");
        	}
        }
        
    • 编译(javac)

      javac 后面跟的是文件名

      • 编译E:\code>javac HelloWorld.java,会生成一个字节码文件HelloWorld,class
    • 运行(java)

      java 后面跟的是类名

      • 窗口打印出HelloWorld java

  2. java代码编写有什么基本要求?

    • 文件名称的后缀必须是.java结尾
    • 文件名称必须与代码的类名一致
    • 必须使用英文模式下的符号

4、Java程序的执行原理

  • 编程语言发展历程
    • 机器语言 -->汇编语言 -->高级语言
  • Java语言最终如何去控制计算机执行的?
    • Java语言存在编译器和执行器
    • 最终可以编译、解释成计算机可以识别的机器指令

5、JDK、JRE、Java跨平台原理介绍

  1. JDK (Java Development Kit), java 开发者工具包
  2. JRE (Java Runtime Environment), java运行环境
  3. JDK中包含JRE, JDK中有一个名为jre的目录,里面包含两个文件夹bin和lib, bin 就是JVM,lib就是JVM工作所需要的类库
  4. JVM (Java Virtual Machine):java 虚拟机,真正运行Java程序的地方
  • 跨平台原理

6、JDK安装时Path环境变量的注意事项

  • Path环境变量的作用

    path环境变量用来配置命令的路径,这样可以在命令行窗口中的任何位置直接使用这些命令

  • 目前新的JDK 安装时会自动配置javac 、java命令的路径到Path环境变量中去

  • 但是老版本的JDK时没有自动配置

  1. JAVA_HOME:告诉操作系统JDK安装在里哪个位置

    JAVA_HOME D:\java\jdk-1.80

  2. Path:告诉操作系统JDK提供的javac,java命令安装到了哪个位置

    path D:\java\jdk-1.80\bin

    或者

    path %JAVA_HOME%\bin

  3. 新版本的JDK 只是自动配置了Path,没有自动配置JAVA_HOME

7、idea开发第一个入门程序

  1. IDEA的结构都是什么样的?

    • project – module – package – class
    • project中可以创建多个module
    • module中可以创建多个package
    • package中可以创建多个class
  2. 新建都是哪些操作

    new project/module/package/class

  • 先选择空的工程

  • 新建模块

  • 新建包名 cn.whw666.day01

  • 新建类名

  • 对应的文件路径

8、IDEA快捷键

快捷键作用说明
ctrl + d复制当前行数据到下一行
ctrl + y删除所在行,建议使用ctrl + X
ctrl + alt + L格式化代码
alt + shift + 向下键上下移动当前代码

9、字面量

  • 字面量:告诉程序员,数据在程序中的书写格式

  • 字面量的分类

    字面量类型说明示例
    整数不能带小数的数字66,78
    小数带小数的数字3.14
    字符必须使用单引号,有且仅能一个字符‘A’, ‘0’ , ‘你’
    字符串必须使用双引号,内容可有可无“helloworld”, " "
    布尔值布尔值,表示真假,只有两个值:true或 falsetrue 或 false
    空值一个特殊的值null

10、变量定义有哪些特点?

  • 变量就是内存中的存储空间,空间中记录着经常发生改变的数据

  • 数据类型:对存储的数据格式进行限定,范围大小也可以限定

  • 什么类型变量存储什么类型的字面值

  • 同一个范围变量名不能重复

  • 变量在使用时要有初始值

  • 变量存在访问范围

标识符:

  • 只能是字母,数字,下划线,美元符组成
  • 不能以数字开头
  • 不能是特殊字符
  • 不能使用关键字

11、数据类型

  1. 数据类型分为几种?

    • 引用数据类型:例如 String

    • 基本数据类型:4大类8种

      ※ 整型 byte、short、int 、long

      ※ 浮点型 float、 double

      ※ 字符型 char

      ※ 布尔型 boolean

  2. 随便写的整数,小数字面值默认什么类型?

    • 23,默认是 int 类型,加上 L 或者 l 就是long类型的数据了 23L
    • 23.5,默认是double类型,加上F 或 f 就是float数据类型了 23.5F
  • 引用数据类型(除了基本数据类型之外的,如String)
  • 基本数据类型:4大类8种

12、ASCII编码 (American Standard Code For Information Interchange)

  • ASCLL,美国信息交换标准码,就是一套现代英语,数字,和其他西欧字符(不含中文)的编号规则
  • 字符在计算机底层就是存储其编号的二进制形式
ASCII值控制字符ASCII值控制字符ASCII值控制字符ASCII值控制字符
0NUT32(space)64@96
1SOH33!65A97a
2STX34"66B98b
3ETX35#67C99c
4EOT36$68D100d
5ENQ37%69E101e
6ACK38&70F102f
7BEL39,71G103g
8BS40(72H104h
9HT41)73I105i
10LF42*74J106j
11VT43+75K107k
12FF44,76L108l
13CR45-77M109m
14SO46.78N110n
15SI47/79O111o
16DLE48080P112p
17DCI49181Q113q
18DC250282R114r
19DC351383S115s
20DC452484T116t
21NAK53585U117u
22SYN54686V118v
23TB55787W119w
24CAN56888X120x
25EM57989Y121y
26SUB58:90Z122z
27ESC59;91[123{
28FS60<92\124|
29GS61=93]125}
30RS62>94^126`
31US63?95_127DEL

13、类型转换

  1. 自动类型转换

    • 为啥要进行自动类型转换?

      存在不同类型的变量复制给其他类型的变量

    • 自动类型转换是什么样子的?

      类型范围小的变量,可以直接赋值给类型范围大的变量

       byte a = 50;//byte的取值范围-128到127,占用一个字节
       int b =a;//int 占用4个字节
      
  2. 表达式的自动类型提升

    • 表达式的自动类型转换是什么样的?
      • 小范围的类型会自动转换成大范围的类型运算
    • 表达式的最终结果类型是由谁决定的?
      • 最终类型由表达式中的最高类型决定
    • 表达式有哪些类型转换是需要注意的?
      • byte、 short、 char 是直接转换成int类型参与运算的
     byte a = 10;
            char b = 'a';
            int c = 60;
            int d = a+b+c;
            double e =a+b+20.2;
            System.out.println(e);//127.2
    

    面试题

    /**
             * 3、4是字面值常量,值是固定的,编译器有优化,如果这个值在左边的类型范围内 ,就编译通过
             */
            byte b1 = 3;
            byte b2 = 4;
            //byte b3 = b1 + b2;
            // System.out.println(b3); //7
    
            byte b = 3 + 4;  //在编译阶段,会自动将代码转换为 byte b = 7;
    

    字面值常量会先运算再赋值

  3. 强制类型转换

    • 什么是强制类型转换?

      • 可以强行将类型范围大的变量、数据赋值给范围小的变量

      • 数据类型 变量 = (数据类型)变量、数据

        int a =20 ;
        byte b = (byte) a;
        System.out.println(b);//20
        
    • 强制类型转换需要注意哪些?

      • 可能出现数据的丢失

        int a =1500 ;
                byte b = (byte) a;
                System.out.println(b);//-36
        

      • 浮点数强制转换成整数,是直接截断小数保留整数

        float a =59.5f ;
        byte b = (byte) a;
        System.out.println(b);//59
        

14、基本的算术运算符

% 取余,获取两个数相除的余数

% 与第一个符号有关
System.out.println(-8 % 5 );//-3
System.out.println(8 % -5 );//3

14.1、数值拆分

* int  x = 123;

* int bai = x / 100 % 10;  1

* int shi = x / 10 %10;   2

* int ge = x / 1 % 10;    3

int y = 6789;

* int qian = y /1000 %10;    6
* int bai  =  y / 100 % 10;    7
* int shi = y /10 % 10;    8
* int ge = y / 1 % 10;  9

/ 除法

 int a =20;
        int b = 3;
        System.out.println(a/b);//6,整个结果会被转换成int 类型
int a =20;
int b = 3;
System.out.println(a*1.0/b);//6.666666666666667
  • / 需要注意什么?

    如果两个整数做除法,其结果一定是整数,因为最高类型是整数

15、加符号做连接符

    • 与字符串做 + 运算时会被当成连接符,其结果还是字符串
  • 能算则算,不能算就在一起

    int a = 5;
            System.out.println("abc" + 'a');//abca
            System.out.println("abc" + a);//abc5
            System.out.println(5 + a);//10
            System.out.println("abc" + 5 + 'a');//abc5a
            System.out.println(15 + "abc" + 'a');//15abca
            System.out.println('a' + a);//102
            System.out.println('a' + "" + a);//a5
            System.out.println(a + 'a' + "itheima");//102itheima
            System.out.println("itheima" + a + 'a');//itheima5a
            System.out.println("itheima" + (a + 'a'));//itheima102
    

16、自增自减运算符

  • 只能用在变量上面,不能对字面量进行操作
  1. 自增自减运算符是什么?有什么作用?

    • 自增运算符 ++ ;自减运算符 –
    • 作用: 对当前变量值进行 +1 或者 -1
  2. 自增自减运算符在变量前后有区别吗?

    • 如果单独使用,放在前后是没有区别的

    • 非单独使用,在变量前,先对变量进行自增 / 自减,再使用变量

    • 非单独使用,在变量后,先使用变量,再进行变量自增 / 自减

    • int a = 5;
              a++;
              System.out.println(a);//6
              a--;
              System.out.println(a);//5
              int b = ++a;//自增运算符放在变量前,先对变量值 + 1,再赋值给  b
              System.out.println(a);//6
              System.out.println(b);//6
              a=5;
              int c = a++;//自增运算符放在变量后,先赋值给 c 再对变量值 + 1,
              System.out.println(a);//6
              System.out.println(c);//5
      
  • 面试题

    • int c = 10;
            int d = 5;
            int rs3 = c++ + ++c - --d - ++d + 1 + c--;
              /**
               * c     10 11 12 11
               * d     5  4 5
               * rs3   0  10+12-4-5+1+12
               */
            System.out.println(rs3);//26
            System.out.println(c);//11
            System.out.println(d);//5
      

17、赋值运算符

  • 赋值运算符含有强制类型转换
  • 赋值运算符有哪些?

    = 、 += 、 -= 、 *= 、 /= 、 %=

  • 作用是什么?

    基本作用都是赋值

    +=还可以实现数据的累加,把别人的数据加给自己

    a +=b ===> a的数据类型 a = (a的数据类型)a + b

    byte a = 10;

    byte b = 20;

    byte b += a; ====> byte b = (byte) b +a

18、关系运算符

是对数据进行条件判断的符号,最终会返回一个布尔结果(false,true)

符号说明
==a==b, 判断 a 和 b 的值是否相等
!=a != b,判断 a 和 b 的值是否不相等
>a > b,判断 a 的值是否大于 b
>=a >= b,判断 a 的值是否大于等于 b
<a < b,判断 a 的值是否小于 b
<=a <= b,判断 a 的值是否小于等于 b
  • ※※ 在做相等判断时,千万不要把 == 误写成 =

19、逻辑运算符

符号介绍说明
&逻辑与有一个为false,结果时false
&&短路与有一个为false,结果是false,前一个为false,后一个条件就不执行 ※※※
|逻辑或有一个为true,则结果为true
||短路或有一个为true,则结果为true,前一个为true,后一个条件就不执行 ※※※
!逻辑非! false ==true, ! true == false
^逻辑异或相同是false, 不同是 true

20、三元运算符

  • 格式: 条件表达式 ? 值1 :值2;
  • 执行流程: 首先计算关系表达式的值,如果值为true,返回值1 ,如果为false,返回值2
  int score= 85;
      String rs = score >=60? "考试通过" : "挂科";
      System.out.println(rs);//考试通过

21、运算符的优先级

22、键盘录入Scanner

//1、导包
import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        //2、得到一个扫描器对象
        Scanner sc = new Scanner(System.in);
        //调用sc对象的功能等待用户输入数据
        //3、这个代码会等待用户输入数据,直到用户输入完数据并按了回车键就会把数据拿到
        System.out.println("请你输入你的年龄:");
        int age = sc.nextInt();
        System.out.println("你的年龄是" + age);
        System.out.println("请输入你的姓名:");
        String name = sc.next();
        System.out.println("欢迎"+ name);
  • 键盘录入步骤

    1. 导包 import java.util.Scanner;
    2. 创建扫描器对象 Scanner sc = new Scanner(System.in);
    3. 等待用户输入数据 sc.nextInt(); sc.next();
  • sc.next();和sc.nextLine()最好不要同时使用,不然,回车会被nextLine()接收,就会跳过键盘录入

  • sc.next();和sc.nextLine()的区别

02-day-流程控制、random类

  • 流程控制语句用来控制程序的执行顺序
顺序结构程序默认流程
分支结构if 、 switch
循环结构for 、 while 、 do …while

1、分支结构:if、switch、switch穿透性

  1. if分支 适合做区间匹配

    • 根据判定的结果(真或假)决定执行某个分支的代码

      • 格式一

        //格式一
                if (条件表达式){
                    语句体;
                }
        
      • 格式二

         //格式二
                if (条件表达式){
                    语句体1;
                }else{
                    语句体2;
                }
        
      • 格式三

         //格式三
                if (条件表达式1){
                    语句体1;
                }else if (条件表达式2){
                    语句体2;
                }else if (条件表达式3){
                    语句体3;
                }
                ...
                else{
                    语句体  n + 1 ;
                }
        
  2. switch

    switch分支也是匹配条件按执行分支,适合做值匹配的分支选择,结构清晰,格式良好

  switch (表达式){
           case 1:
               语句1 ;
               break;
           case 2:
               语句2 ;
               break;
           case 3:
               语句3 ;
               break;
           ...
           default:
               语句 n
       }
  • 执行流程
    • 先执行表达式的值,拿着这个值去与case后的值进行匹配
    • 匹配哪个case的值为true就执行哪个case下的语句,遇到break就跳出switch分支
    • 如果case后的值都不匹配则执行default后的代码

switch分支注意事项:

  1. 表达式类型只能是byte、short、int、char,JDK5开始支持枚举,JDK7开始支持String,不支持 double、float、 long、布尔
  2. case给出的值不允许重复,且只能是字面量,不能是变量
  3. 不要忘记写break,否则会出现穿透现象

switch穿透性,由于

​ case 1:
​ case 3:
​ case 5:
​ case 7:
​ case 8:
​ case 10:

都没break,则会穿透到case12,利用这个穿透性,可以使代码简洁

 //需求:用户输入月份可以展示该月份的天数
      /*
      1、3、5、7、8、10、12月份是31天
      2月份是闰年为29天,非闰年为30天
      4、6、9、11月份是30天
       */
       int month = 2;
       switch (month){
           case 1:
           case 3:
           case 5:
           case 7:
           case 8:
           case 10:
           case 12:
               System.out.println(month+"月份是31天");
               break;
           case 2:
               System.out.println(month+"月份是闰年为29天,非闰年为30天");
               break;
           case 4:
           case 6:
           case 9:
           case 11:
               System.out.println(month+"月份是30天");
               break;
           default:
               System.out.println("数据有误!");
       }

※ 如果代码执行到没有写break的case块,执行完后将直接进入下一个case代码块执行(而且不会进行任何匹配),直到遇到break才跳出分支,这就是switch的穿透性。

2、for循环语句

for (int i = 0; i < 5; i++) {
            System.out.println("hello world");//会打印五次
        }

  • 使用 for 循环打印 九九乘法表

    for (int i = 1; i < 10; i++) {
                System.out.println();
                for (int j = 1;j <=i;j++){
                    System.out.print(j+"*"+i+"="+j*i+"\t");
                }
            }
    
  • 寻找三位整数的水仙花数(个位的立方+十位的立方+百位的立方=本身)

for (int i =100; i <1000; i++) {
            a = i % 10;//个位
            b = i / 10 % 10;//十位
            c = i / 100;//百位
            if (a*a*a+b*b*b+c*c*c==i){
                System.out.println(i);
            }
        }

3、while循环格式与流程

while (循环条件){
           循环体语句;
           迭代语句;
       }
  • 需求,珠穆朗玛峰的高度是8848860,纸张的厚度是0.1,折叠纸张直到不低于珠穆朗玛峰的高度,求折叠了几次?
      double peakHeight = 8848860;//珠穆朗玛峰的高度
       double paperThickness = 0.1;//纸张的初始厚度
       int count = 0;//记录纸张折叠的次数
        while (paperThickness<peakHeight){//纸张累积的厚度<珠穆朗玛峰的高度
            paperThickness *= 2;//纸张对着 0.2 0.4 0.8 1.6 3.2 6.4 .....
            count++;//计数,对折的次数
        }
        System.out.println("纸张对折的次数是:" + count);//纸张对折的次数是:27
        System.out.println("当前纸张的厚度是:" + paperThickness);//当前纸张的厚度是:1.34217728E7

当不知道循环的次数时,一般使用 while循环

4、do{…}while()循环

初始化语句
do{
    循环体;
    迭代语句;
}while(判断条件);
int i = 0;
       do {
           System.out.println(123456);
           i++;
       }while (i<3);

会第一次先执行 do 循环体中的语句,再进行判断

int i = 10;
       do {
           System.out.println(123456);//执行一次打印
           i++;//i=11
       }while (i<3);

5、死循环、循环嵌套、break、continu

  1. 死循环
for (;;){
            
        }
      //实际开发中使用,经典
      while (true){
          
      };
      
      do {
          
      }while (true);
  • 密码校验案例

  1. 循环嵌套

    场景:假如你上课迟到了,老师罚你把上课时间每天抄写100遍,连续抄写10天,好长记性。

      for (int i = 1; i <=10 ; i++) {
                System.out.println("早上上课时间是,08:30分");//  1
                System.out.println("早上上课时间是,08:30分");//  2
                System.out.println("早上上课时间是,08:30分");//  3
                //   ............
                System.out.println("早上上课时间是,08:30分");//  100
            }
    

    这样每天都要手写打印100遍,于是把重复的100遍,在使用一个循环来执行

    for (int i = 1; i <=10 ; i++) {
                for (int j = 1; j <=100 ; j++) {
                    System.out.println("早上上课时间是,08:30分");
                }
            }
    
  2. break、continue关键字

  • break,指的是结束当前循环,或是结束所在switch分支的执行

  • continue,指的是结束当前循环的当次执行,进入到下一轮循环

    场景:假如你犯错了,你老婆罚你洗五天碗,洗到第三天,心软了,就不用你再洗碗了。

    for (int i = 1; i <=5; i++) {
                
                if (i==3){
                    break;
                }
        System.out.println("第"+i+"天快乐的洗碗~~~");
            }
    

    场景:假如你犯错了,你老婆罚你洗五天碗,洗了三天碗后,心软了,第四天不用你洗,第五天,你又犯贱了,又被罚洗碗了。

    for (int i = 1; i <=5; i++) {
                if (i==4){
                    continue;
                }
                System.out.println("第"+i+"天快乐的洗碗~~~");
            }
    
  • 循环标号 loop,即在循环语句开始,打一个记号,可以从内存循环结束外层循环,loop自己命名

     //循环标号loop
            loop:for (int i = 1; i <= n ; i++) {
                //打印空格
                for (int j = 0; j < n - i; j++) {
                    System.out.print(" ");
                }
                for (int j = 0; j < i * 2 -1; j++) {
                    System.out.print("*");
                    break loop;
                }
                System.out.println();
    
            }
    

6、案例技术:Random类,猜数字游戏

Random随机数,作用:用于在程序中获取随机数的技术

  • 使用步骤

    1. 导包:import java.util.Random
    2. 创建随机数对象:Random r = new Random();
    3. 调用随机数的功能(方法)获取0-9的随机数 int number = r.nextInt(10);
      • nextInt(n)功能只能生成 0至n-1之间的随机数,不包含n
  • Random生成区间随机数的技巧: 减加法

  • 公式:区间随机数(begin,end)

    • r.nextInt(end -begin+1)+begin

假如要生成区间51-87====> -51 =>(87-51+1)+51==>int data = Random().nextInt(37)+51;

  • 猜数字游戏

    /**
             * 生成0-100只内的随机整数,猜大了,提示猜大了,猜小了,提示猜小了,猜对了,提示恭喜你猜中了
             */
            Random rc = new Random();
            Scanner sc = new Scanner(System.in);
            int i,j;
            i = rc.nextInt(100)+1;
            System.out.println("请你猜0-100之间的一个随机整数");
            while (true){
                j = sc.nextInt();
                if (j<i){
                    System.out.println("猜小了~");
                }else if (j>i){
                    System.out.println("猜大了~");
                }else {
                    System.out.println("恭喜你猜中了~");
                    break;
                }
            }
    

03-day-数组、Debug

1、数组定义方式一、访问、注意事项

  • 数组是什么?

    数组就是用来存储一批同种类型数据内存区域(可以理解成容器)


    • 注意:

      • 数组可以存储基本数据类型,也可以存储引用数据类型


      • 集合只能存储引用数据类


1.1、静态初始化数组

  • 定义数组的时候直接给数组赋值

静态初始化数组的格式

  • 完整格式

     /*
              数据类型 [] 数组名 = new 数据类型  [] {元素1,元素2,元素3...};
            */
            int [] ages = new int[]{18,22,24,25,19};
    
  • 简化格式

    /*
              数据类型 [] 数组名 ={元素1,元素2,元素3...};
            */
            int [] ages ={18,22,24,25,19};
    
    • 简化格式的语法,不允许分开定义

    • //需求3:定义一个String类型数组,元素分别是 "张无忌","张三丰","张翠山"
             String[] arr3;
             arr3 = new String[]{"张无忌", "张三丰", "张翠山"};
             String[] arr2;
             arr2= {"张无忌", "张三丰", "张翠山"};//编译报错
      

※ 数组名 ages 保存的是 {元素1,元素2,元素3…} 这个对象的内存地址

  • 数组的访问-------------数组名[索引]

    数组的索引从0开始

    System.out.println(ages[2]);//36

  • 数组的长度属性:length

    System.out.println(arr.length);//3

    • 数组定义好后,它的长度是固定的

    • arr.length = 100;//编译错误
      
  • 数组最大索引可以怎么表示?

    arr.length-1======>arr[arr.length-1]========前提:元素个数大于0

2、数组定义方式二、元素默认值规则

  • 数组的动态化

    定义数组的时候之确定元素的类型和数组的长度,之后再存入具体数据

  • 动态数组的初始化格式

    数据类型 [] 数组名 = new 数据类型 [长度];

    int [] arr = new int [3];

  • 动态数组的元素默认值

    • 数据类型是整形的元素的默认值是 0
    • 数据类型是float、double的元素的默认值是 0.0
    • 数据类型是boolean的元素的默认值是 false
    • 数据类型是引用类型(类、接口、数组、String)的元素的默认值是 null

 byte [] arr1 = new byte[5];
       System.out.println(arr1[0]);//0
       char [] arr2 = new char[5];
       System.out.println((int)arr2[0]);//0
        float [] arr3 = new float[5];
        System.out.println(arr3[0]);//0.0
        boolean [] arr4 = new boolean[5];
        System.out.println(arr4[0]);//false
        String [] arr5 = new String[5];
        System.out.println(arr5[0]);//null
静态数组int [] arr = new int[]{12,10};或者 int [] arr = {12,10};开始就存入元素值,适合一开始就能确定元素的业务场景
动态数组int [] arr = new int [2];只指定数组长度,后期赋值,适合做开始知道数据的数量,但是不确定具体元素值的业务场景
  • 错误混用XXX

    int [] arr = new int [2]{23,43};

  • 数组名和 [] 的位置:

    • int [] arrs ={}; ========> int arrs []={};

3、数组遍历、元素求和

  • 什么是遍历?

    就是一个一个把数组中的元素访问一遍

    • arr.fori idea中是把数组正着遍历
    • arr.forr idea中是把数组倒着遍历
 int[] arr = {15,87,62,32,14,63};
        int arrSum = 0;//数组求和
        //访问每一个数组元素
        for (int i = 0; i < arr.length; i++) {
            System.out.println("数组的第"+i+"个元素是"+arr[i]);
            arrSum += arr[i];//累加
        }
        System.out.println("得到的数组和是:"+arrSum);

4、数组的案例

  1. 求数组中的最大值

       int[] faceScores = {15,9000,10000,20000,9500,-5};
            //定义一个变量用于记录最大值,这个变量建议默认为数组的第一个元素作为参考
            int max= faceScores[0];
            for (int i = 1; i < faceScores.length; i++) {
                if (faceScores[i]>max){
                    max = faceScores[i];
                }
            }
            System.out.println(max);
    
  2. 打乱素组元素顺序

        int[] arr = new int[5];
          Scanner sc = new Scanner(System.in);
            for (int i = 0; i < arr.length; i++) {
                System.out.println("请输入第"+i+"个数组数据");
                arr[i]=sc.nextInt();
            }
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i]+"\t");
            }
            System.out.println();
            Random r = new Random();
            int temp;
            for (int i = 0; i < arr.length; i++) {
                   temp = arr[r.nextInt(arr.length)];
                   arr[r.nextInt(arr.length)] = arr[i];
                   arr[i]=temp;
    
            }
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i]+"\t");
            }
    
    1. 冒泡排序

      for (int i = 0; i < arr.length; i++) {
                  for (int j = 0; j < arr.length - i -1; j++) {
                      if (arr[j] > arr[j+1]){
                          int temp = arr[j+1];
                          arr[j+1] = arr[j];
                          arr[j] = temp;
                      }
                  }
              }
              for (int i = 0; i < arr.length; i++) {
                  System.out.print(arr[i]+"\t");
              }
      
      1. 选择排序

        for (int i = 0; i < arr.length; i++) {
                    int k =i;
                    for (int j = i+1; j < arr.length; j++) {
                        if (arr[k]>arr[j]){
                            k = j;
                        }
                    }
                    if (arr[i] != arr[k]){
                        int temp = arr[i];
                        arr[i] = arr[k];
                        arr[k] = temp;
                    }
                }
                for (int i = 0; i < arr.length; i++) {
                    System.out.print(arr[i]+"\t");
                }
        

5、数组内存图、常见使用问题

  • 数组内存图

  • 数组索引越界

    int [] arr =new int[]{11,22,33};
    System.out.println(arr[3]);
    

    报错:ArrayIndexOutOfBoundsException

  • 空指针

    int [] arr =new int[]{11,22,33};
    arr = null;
    System.out.println(arr[3]);
    

    报错:NullPointerException

6、评委打分案例

i–的巧妙运用

 /**
         * 需求:
         * 在编程竞赛中,有6个评委为参赛选手打分,分数为0 - 100的整数
         * 选手的最后得分为:去掉一个最高分和一个最低分后,4个评委的平均值(不考虑小数部分)
         */
        //1、定义一个数组,用动态初始化完成数组的初始化,长度为6
        //2、键盘录入评委分数
        //3、由于是6个评委打分,所以,接收分数的操作用循环
        //4、求出数组的最大值
        //5、求出数组的最小值
        //6、求出数组总和
        //7、按照计算规则计算平均分
        //8、输出平均分


        //1、定义一个数组,用动态初始化完成数组的初始化,长度为6
        int[] scores = new int[6];
        //创建键盘录入扫描器对象
        Scanner sc = new Scanner(System.in);
        //2、键盘录入评委分数
        for (int i = 0; i < scores.length; i++) {
            System.out.println("请第" + (i + 1) + "位评委打分:");
            int score = sc.nextInt();
            //判断评委打分的数值大小,只能在0 - 100 之间
            if (score >= 0 && score <= 100) {
                scores[i] = score;
            } else {
                System.out.println("您打的分数不合法,请打0 - 100 之间的整数!!!");
                i--;
            }
        }
        //4、求出数组的最大值
        int max = scores[0];
        //4、求出数组的最小值
        int min = scores[0];
        //6、求出数组总和
        int sum = 0;
        for (int i = 0; i < scores.length; i++) {
            if (scores[i] > max) {
                max = scores[i];
            }
            if (scores[i] < min) {
                min = scores[i];
            }
            sum += scores[i];
        }
        //7、按照计算规则计算平均分
        int avg = (sum - max - min) / (scores.length-2);
        System.out.println("6个评委的平均分是:" + avg);

7、debug

  • 可以查看程序的执行流程

04-day-方法

1、方法的概述

为什么要有方法?

解决代码的重复度太高,复用性太差

方法(method),就是一段具有独立功能的代码块,不调用就不执行。

方法的出现,可以提高代码的复用性,实现结构性编程

  • 方法使用前须知
    • 方法必须先创建才可以使用,该过程称为方法定义
    • 方法创建后并不是直接运行的,需要手动使用后才执行,该过程称为方法调用
  • 方法的概念:
    • 一段具有功能的代码块

2、方法的定义和调用

  • 方法的定义格式

    • /*
              public static void 方法名(){
                  语法体
              }
           */
          public static void eat(){
              System.out.println("吃饭");
          }
      
  • 方法的调用

    /*
            方法名();
         */
        public static void main(String[] args) {
            eat();
        }
    
    • 方法与方法是平级关系,不能嵌套定义

3、方法的调用过程

  • 方法没有被调用的时候,都在方法区中的字节码文件(.class)中存储
  • 方法被调用的时候,需要进入到栈内存中运行

栈内存的存储是先进后出,相当与子弹匣,被先压入的最后才被打出

4、方法练习,奇偶数判断

 public static void main(String[] args) {
        /**
         * 从键盘输入一个整数,判断奇偶数,使用方法实现
         */
        getMethod();
    }
    public static void getMethod(){
        Scanner sc = new Scanner(System.in);
        int num;
        while (true){
            System.out.println("请输入一个整数:");
            num = sc.nextInt();
            if (num % 2 ==0){
                System.out.println(num+"是偶数");
            }else {
                System.out.println(num+"是奇数");
            }
            if (num == 0){
                break;
            }
            System.out.println("输入\t0\t可以结束程序");

        }

    }

5、带参方法的定义和调用

  • 格式 public static void 方法名 (参数){…}

  • 格式(单个参数) public static void 方法名 (数据类型 变量名){…}

    • public static void getName(String name){
              System.out.println("该同学的名字是" + name);
          }
      
  • 格式(多个参数) public static void 方法名 (数据类型1 变量名1 ,数据类型2 变量名2,…){…}

    • public Test(String name, int age, char gender, double heigth) {
              this.name = name;
              this.age = age;
              this.gender = gender;
              this.heigth = heigth;
          }
      
  • 注意

    • 定义方法时,参数中的数据类型与变量名都不能缺少,缺少任意一个程序都会报错
    • 方法定义时,多个参数之间使用逗号(参数,参数,,,,)分隔

方法练习,奇偶数判断,使用带有参数的方法练习

public class Test {
    public static void isEvenNumber(int num){
        if (num % 2 == 0){
            System.out.println("偶数");
        }else{
            System.out.println("奇数");
        }
    }

    public static void main(String[] args) {
        isEvenNumber(7);
    }
}

6、形参和实参

  • 形参:形式参数,是指方法定义中的参数
  • 实参:实际参数,方法调用中的参数

7、带参数方法的练习

package cn.whw666;

import java.util.Scanner;

public class Test {
    /**
     * 需求:设计一个方法(print)用于打印 n 到 m 之间所有的奇数
     */
    /*
        1、定义方法,print()
        2、为方法添加两个 Int 类型的形参,准备接收调用者传递过来的实参
        3、方法中设计for循环,循环从 n 开始,到 m 结束
        4、循环中加入 if 判断,是奇数,则打印
        5、main方法中调用 print()方法,传入两个实际参数
     */
      //1、定义方法,print()

    public static void print(int n,int m){
        // n-m应该是一个区间,含有隐藏条件,m>n
        int count = 0;//定义一个变量控制换行
        if (m > n){
            for (int i = n; i <= m; i++) {
                if (i % 2 == 1){
                    System.out.print(i+"是奇数\t");
                    count++;
                }
                //打印五个奇数后就换一行
                if (count % 5 ==0){
                    System.out.println();
                }
            }
        }else {
            System.out.println("区间不合法");
        }
    }

    public static void main(String[] args) {
        print(60,23);
    }
}


8、带返回值的方法定义和调用

带返回值方法的定义格式
*  public static 数据类型 方法名 (参数) {
*      return 数据;
*  }
*  方法定义时,return后面的返回值与定义上的数据类型要匹配,否则程序将报错
*  带返回值方法的调用格式
*      数据类型 变量名 = 方法名(参数);
*  通常方法的返回值用变量接收,用常量接收这个方法的返回值没有意义
  • 案例:两个整数求和
   public static int sum(int num1,int num2){
        int sum = num1 + num2;
        return  sum;
    }

    public static void main(String[] args) {
        int sum = sum(19,21);
        System.out.println("两个数字的和是:" + sum );
    }

9、带返回值的方法的练习

  • 比较两个数的最大值
public static int getMax(int num1,int num2){
        if (num1 > num2){
            return num1;
        }else {
            return num2;
        }
    }

    public static void main(String[] args) {
        //输出调用,(不推荐)
//        System.out.println(getMax(5, 6));
        int result = getMax(5,6);
        System.out.println(result);
    }

10、方法通用格式

  • 格式:public static 返回值类型 方法名 ( 参数 ){

    ​ 方法体;

    ​ return 数据;

    }

  • 定义方法时,要做到两个明确

    • 明确参数:主要是明确参数的类型和数量
    • 明确返回值类型:主要明确方法操作完毕之后是否右数据返回,如果没有,写void;如果有,写对应的数据类型

11、方法的注意事项

  • 方法定义不能嵌套
  • void声明的方法,一般默认没有return语句。如果有return,return后面不能跟任何数据

return 可以用于结束方法,也就是说将方法从栈内存中弹出去,该过程称之为弹栈

找出区间 n - m之间的偶数,区间 m > n

判断条件,

if ( n> m ){
    return;
}

这样可以提高代码的健壮性

12、方法重载

  • 概述
    • 在同一个类中,定义了多个同名方法,但每个方法具有不同的参数类型或参数个数,这些同名的方法,就构成了重载关系
    • 简单记
      • 同一个类中,方法名相同,参数不同的方法
      • 参数不同 : 个数不同,类型不同,顺序不同
  • 识别方法是否重载,只要看方法名和参数,跟返回值无关

假如没有方法重载

13、方法重载练习

public static void main(String[] args) {
        /**
         * 需求:使用方法重载的思想,设计比较两个整数是否相同的方法
         * 兼容全整数类型(byte,short,int,long)
         */
        byte a = 1;
        byte b = 2;
        System.out.println(compare(a,b));
        short a1 = 127;
        short b1 = -32600;
        System.out.println(compare(a1,b1));
        int a2 = 123456;
        int b2 = 795463;
        System.out.println(compare(a2,b2));
        long a3 = 10000000;
        long b3 = 10000000;
        System.out.println(compare(a3,b3));
    }
    public static boolean compare(byte a,byte b){
        return a == b;
    }
    public static boolean compare(short a,short b){
        return a == b;
    }
    public static boolean compare(int a,int b){
        return a == b;
    }
    public static boolean compare(long a,long b){
        return a == b;
    }

14、方法参数传递基本数据类型

  • 方法参数传递基本数据类型,传入方法中的是,具体的数值

  • public static void main(String[] args) {
           int number = 100;
           System.out.println(number);//100
           changeNumber(number);
           System.out.println(number);//100
       }
       public static void changeNumber(int number){
           number = 200;
       }
    

15、方法参数传递引用数据类型

  • 方法参数传递引用数据类型,传入方法中的是内存地址

     public static void main(String[] args) {
            int [] arr = {15,87,69};
            System.out.println("调用change()方法之前"+arr[1]);//87
            change(arr);
            System.out.println("调用change()方法之后"+arr[1]);//100
        }
        public static void change (int[] arr){
            arr[1] = 100;
        }
    

16、数组遍历

17、获取数组最大值

/**
     * 需求:求数组的最大值
     */
    public static void main(String[] args) {

        //1、定义一个数组,用于静态化完成数组元素初始化
        int [] arr ={11,22,33,44,55};
        System.out.println(getMax(arr));
    }
    public static int getMax(int [] arr){
        int max =arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max){
                max = arr[i];
            }
        }
        return max;
    }

18、方法同时获取数组最大值和最小值

  • return只能带回一个结果,不能return max,min;
  /**
     * 需求:求数组的最大值和最小值
     */
    public static void main(String[] args) {

        //1、定义一个数组,用于静态化完成数组元素初始化
        int [] arr ={11,22,33,44,55};
        int[] minAndMax = minAndMax(arr);
        System.out.println(minAndMax[0]);
        System.out.println(minAndMax[1]);
    }
    public static int[] minAndMax(int [] arr){
        int max = arr[0];
        int min = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max){
                max = arr[i];
            }
            if (arr[i] < min){
                min = arr[i];
            }
        }
        int[] minAndMax ={min,max};
        return minAndMax;
    }

05-day-进制

1、进制介绍与书写格式

  • 进制:指进位制,是人们规定的一种进位方式,表示某一位置的数,运算时是逢X进一位

    十进制是逢十进一,借一当十;二进制是逢二进一,借一当二;八进制是逢八进一,借一当八;

    十六进制是逢十六进一;借一当十六

  • 在java中

    • 十进制:默认数值都是10进制,不需要加任何修饰
    • 二进制:数值前面以 0b 开头,b 大小写都可以
    • 八进制: 数值前面以 0 开头
    • 十六进制: 数值前面以 0x 开头,x 大小写都可以

    ※ 注意:书写的时候,虽然加入了进制的标识,但打印在控制台展示的都是十进制数据

// 以十进制  10  为例,java默认位十进制
        System.out.println("二进制数0b10为:"+ 0b10);//2
        System.out.println("八进制数为:010"+ 010);//0108
        System.out.println("十进制数10为:"+ 10);//10
        System.out.println("十六进制数0x10为:"+ 0x10);//16

2、任意进制到十进制的转换

  • 二进制到十进制的转换
  • 公式:系数 * 基数的权次幂,相加
    • 系数:每一位上的数
    • 基数:几进制,就是几
    • 权:从数值的右侧,以0开始,逐个+1增加

  • 十进制到任意进制的转换

  • 十进制到二进制转换:除以2,反向取余数,直到商为0终止。

  • 十进制到十六进制转换:除以16,反向取余数,直到商为0终止。

    • 公式:除基取余
      • 使用源数据,不断的除以基数(几进制,基数就是几)得到余数,直到商为0,再将余数倒着拼起来即可

3、快速进制转换法

  • 8421码

在这种编码方式中,每一位进制值的1都是代表一个固定数值,把每一位的1代表的十进制数加起来的结果就是它所代表的十进制数

4、原码反码补码

  • 原码反码补码介绍

    • 计算机中的数据,都是以二进制补码的形式在运算,而补码则是通过反码和原码推算出来的
  • 原码:可直观看出数据大小

    • 就是二进制定点表示法,即最高位为符号位,0表示正,1表示负,其余位表示数值的大小
    • 通过一个字节表示,+7和-7,代码 byte b1 =7; byte b2 = -7;
    • 一个字节表示8个比特位,也就是8个二进制位,00000111
  • 反码:中转数据,正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外

  • 补码:数据以该状态进行运算,正数的补码与其原码相同,负数的补码是在其反码的末位+1

  • 正数的原码反码补码都是一样

  • 通过补码求原码

5、位运算

  • 位运算符介绍
    • 位运算指的是二进制位的运算,先将十进制数转成二进制后再进行运算
    • 在二进制位运算中,1 表示 true,0 表示 false
符号简介说明
&位与遇到 false 则 false,遇到 0 则 0
|位或遇到 true 则 true,遇到 1 则 1
^位异或相同位false,不同为true
~取反全部取反,0 变 1,1 变 0,(包括符号位)
System.out.println( 6&2 );//2

  • 一个数被另一个数位异或两次,其结果不变

    • System.out.println( 30 ^ 5 ^ 5 );//30
      System.out.println( 30 ^ 5 ^ 30 );//5
      
  • 使用位异或进行数据交换

int a =58;
       int b =6;
       a = a ^ b;//  a= 58 ^ 6
       b = a ^ b;//  b = 58 ^ 6 ^ 6    b = 58
       a = a ^ b;//  a = 58 ^ 6 ^ 58    a = 6
        System.out.println(a);//6
        System.out.println(b);//58

*数组反转案例

//数组反转
int[] arr = {11,22,33,44,55,66,77};
        for (int i = 0; i < arr.length / 2; i++) {
            for (int j = arr.length-1 - i; j >=arr.length / 2; j--) {
                arr[i] = arr[j] ^ arr[i];
                arr[j] = arr[j] ^ arr[i];
                arr[i] = arr[j] ^ arr[i];
                break;
            }
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+"\t");
        }
  • //数组反转
            int[] arr = {11, 22, 33, 44, 55, 66, 77};
    
            int start = 0;//首指针
            int end = arr.length - 1;//末指针
            
            //for(int start =0, end =  arr.length -1 ; start < end; start++,end--)
            
            for (; start < end; start++, end--) {
                int temp = arr[start];
                arr[start] = arr[end];
                arr[end] = temp;
            }
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i] + "\t");
            }
    

6、位移运算

<<有符号左位移,二进制位向左位移,左边符号丢弃,右边补齐0。
>>有符号位右移,二进制位向右移动,使用符号位进制补齐
>>>无符号右移运算,无论符号位是 0 ,还是1,都补0.(开发用的比较少)
  • << 有符号左移运算,运算规律:向左移动几位,就是乘以2的几次幂

    • 12<<2 结果 48

    • System.out.println( 12 << 2 );//48
      
  • .>>有符号右移运算,运算规律,向右移动几位,就是除以2的几次幂

  • System.out.println(17>>2);//4
    

06-day-二维数组

1、二维数组动态初始化

  • 二维数组概述:

    • 二维数组也是一种容器,不同于一维数组,该容器存储的都是一维数组。
  • 二维数组定义格式

    • 格式1:
      • 数据类型 [] [] 变量名 = new 数据类型 [m] [n]; int [] [] arr = new int [2] [3];
    • 格式二:
      • 数据类型 变量名 [] [] = new 数据类型 [m] [n];
    • 格式三:
      • 数据类型 [] 变量名 []= new 数据类型 [m] [n];
  • m: 表示这个二维数组,可以存放多少个一维数组

  • n:表示每一个一维数组,可以存放多少个元素

    • int [] [] arr = new int [2] [3];
    • 该数组可以存放两个一维数组,每一个二维数组可以存放3个int类型的元素
 int[][] arr = new int[2][3];
        System.out.println(arr);//打印的是二维数组的内存地址: [[I@119d7047
        /**
         *   [[  代表二维数组
         *   I   代表int数据类型
         *   @   分隔符
         *   119d7047: 16进制内存地址
         */
        System.out.println(arr[0]);//打印的是二维数组中第一个数组的内存地址:[I@776ec8df
        System.out.println(arr[0][0]);//打印的是二维数组中第一个数组的第一个数据的值,int类型默认值是 0
        arr[1][0] = 99;
        System.out.println(arr[1][0]);//99

2、二维数组元素访问细节问题

      int [][] arr = new int[3][3];
//      arr[2][3] = 100;//  .ArrayIndexOutOfBoundsException
//      System.out.println(arr[2][3]);
      int[] arr1 = {11,22,33,44};
        arr[2] = arr1;
        System.out.println(arr[2][3]);

  • 二维数组中,存储的是一维数组,可以存储已经创建好的一维数组

3、二维数组静态初始化

/**
       * 完整格式:
       *  数据类型  [][] 数组名 = new 数据类型[][]{{数组1},{数组2},{数组3},...};
       */
        int [][] arr = new int[][]{{11,22,33},{44,55,66}};
        System.out.println(arr[1][1]);//55
        /**
         * 简写格式
         * 数据类型 [][] 数组名 ={{数组1},{数组2},{数组3},...};
         * int [][] arr1 = {{11,22,33},{44,55,66}};
         */
        int [][] arr1 = {{11,22,33},{44,55,66}};
        System.out.println(arr1[1][1]);//55
        
        int [] array1 ={12,13,14};
        int [] array2 ={22,23,24};
        
        int [][] array = {array1,array2};

4、二维数组的遍历

//二维数组的遍历
        int [][] arr = {{11,22,33,44},{55,66,77,88}};
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                System.out.println(arr[i][j]);
            }
        }

5、二维数组求和

//二维数组的求和
        int[][] arr = {{11, 22, 33, 44}, {55, 66, 77, 88}};
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                sum += arr[i][j];
            }
        }
        System.out.println(sum);

07-day-面向对象基础


01-面向对象和面向过程思想对比

  • 面向过程编程(Procedure Oriented Programming)
    • 是一种以过程为中心的编程思想,实现功能的每一步,都是自己去实现的
  • 面向对象编程(Object Oriented Programming)
    • 是一种以对象为中心的编程思想,通过指挥对象实现具体的功能

比如:洗衣服

  • 面向过程思想:

    • 倒水到盆子里

    • 到洗衣粉

    • 狠狠的搓衣服,使劲的洗干净

    • 漂洗泡沫

    • 拧干衣服

    • 晾衣服

    这些都是要自己亲自动手的,自己的衣服自己洗

  • 面向对象思想

    • 把衣服放进洗衣机,完事了。
      • 洗衣机会把本来需要我们自己动手做的事给做了,面向对象思想是基于面向过程思想实现的

    对象:指客观存在的事物, 万物皆对象洗衣机就是我们指挥的对象,让洗衣机洗衣服,实现洗衣功能

  • 面向对象思想小结:

    • 客观存在的任何一种事物,都可以看做为程序中的对象
    • 使用面向对象可以将复杂的问题简单化
    • 将我们从执行者的位置,变成了指挥者
    • 面向对象是基于面向过程实现的

02-类和对象的关系

  1. 什么是类?

    • 类:是对现实生活中一类具有共同属性和行为的事物的抽象,类也是一种数据类型,是引用类型

      对事物(对象)的一种描述,可以将类理解为一张设计图,根据设计图,可以创建出具体的事物(根据类去创建对象)

    • 类的组成

      • 属性

      • 行为

        举例:人类

        • 属性:有鼻子,有眼,有嘴,有手有脚
        • 行为:能说会道,站立行走。。。

        举例:笔记本电脑

        • 属性:有键盘,有屏幕,有CPU
        • 行为:能上网,能听music,能写Java程序

    2.什么是对象?

    • 是能够看得到摸得着的真实存在的具体事物,比如,法外狂徒张三,抽他一巴掌,他会疼,张三就是真实存在的具体事物
    • 类是对象的描述
  • 对象是类的实体

    • 类是对象的模板,对象是类的实体

    • 类是抽象的,对象是具体的

03-类的定义

  • 类的组成:属性和行为

    • 属性:在代码中通过成员变量来实现(类中方法外的变量)
    • 行为:在代码中通过成员方法来实现(和前面的方法相比去掉static关键字即可)
  • 比如:定义一个学生类

public class Student {
    /**
     * 属性:姓名,年龄
     */
    //成员变量  类中方法外
    String name;
    int age;

    /**
     * 行为:学习
     */
    //成员方法   去掉了static关键字
    public void study(){
        System.out.println("学习使我快乐~~~~");
    }
}

04-对象的创建和使用

  • 创建对象的格式:
    • 类名 对象名 = new 类名();
  • 调用成员变量格式:
    • 对象名.方法名
  • 调用成员方法的格式
    • 对象名.方法名();
public static void main(String[] args) {

        // 创建对象格式  类名  对象名  = new  类名();
        Student stu = new Student();

        System.out.println(stu);//cn.whw666.Student@776ec8df

        /**
         * cn.whw666.Student@776ec8df
         * 拆分:
         * 全类名(包名 + 类名):cn.whw666.Student
         * 分隔符:@
         * 十六进制内存地址:776ec8df
         */
        // stu 保存的是内存地址,new Student()会在堆内存中开辟空间

        //默认初始值
        System.out.println(stu.name);//null
        System.out.println(stu.age);//0

        //对象名.变量名
        stu.name = "张飞";
        stu.age = 18;
        System.out.println(stu.name);//张飞
        System.out.println(stu.age);//18

        //对象名.方法名();
        stu.study();//学习使我快乐~~~~
    }

05-案例-手机类的创建和使用

06-单个对象内存图

  • 堆内存中只保存了成员方法的地址值,栈内存调用类的成员方法的时候,会区堆内存找到地址,然后从方法区再加载到栈内存执行

07-两个对象内存图

  • 创建了两个对象,但是类的字节码文件只加载一次。对象会调用类的成员方法,都指向同一个地址值访问成员方法
  • 两个对象,在堆内存中,独自开辟自己的空间,有自己的地址值,有自己的成员变量

08-两个引用指向同一个对象内存图

  • 垃圾回收

    • 注意:当堆内存中,对象或数组产生的地址,通过任何方式都不能被找到后,就会判定为内存中的“垃圾”

    • 垃圾会被java垃圾回收器,空闲的时候自动进行清理

    • stu1 = null;
      stu2 = null;
      //堆中的new Student()的内存,就会被java回收机制进行回收
      

09-成员变量和局部变量的区别

  • 成员变量 类中方法外

    • 在堆内存,随着对象的存在而存在,随着对象的消失而消失,有默认的初始化值
  • 局部变量 方法中或者方法的声明上(形参)

    • 在栈内存,随着方法的调用而存在,随着方法的调用完毕而消失

10-private关键字

  • private 是一个权限修饰符,可以把类中的成员变量和成员方法私有化,外部不能通过 类名.属性名访问
  • 可以修饰成员变量和成员方法
  • 被 private修饰的成员只能在本类中访问
  • 针对private修饰的成员变量,如果需要被其他类使用,提供相应的操作
    • 提供"get变量名()"方法,用于获取成员变量的值,方法用public修饰
    • 提供“set变量名(参数)” 方法,用于设置成员变量的值,方法用public修饰

11-private关键字的使用

public class Student {
    private String name;
    private int age;

    public void setName(String n) {
        name = n;
    }

    public String getName() {
        return name;
    }

    public void setAge(int a) {
        age = a;
    }

    public int getAge() {
        return age;
    }

    public void show() {
        System.out.println(name + "......" + age);
    }
}
public class Test {

    public static void main(String[] args) {
        Student stu = new Student();
//        stu.name = "小明";
        stu.setName("小明");
        stu.setAge(18);
        String name = stu.getName();
        int age =stu.getAge();
        System.out.println(name);
        stu.show();
        for (int i = 0; i < age; i++) {
            System.out.println("happy birthday~~~");
        }

    }
}

12-this关键字

  • 局部变量和成员变量重名的时候Java使用的是就近原则

  • this关键字的作用:可以调用本类的成员(变量,方法),解决局部变量和成员变量的重名问题

  • this:代表所在类的对象引用

    • 记住:方法被哪个对象调用,this就代表哪个对象

13-this内存原理

14-封装

  • 面向对象三大特征之一(封装,继承,多态)
  • 隐藏实现细节,仅对外暴露公共的访问方式
  • 封装常见的体现:
    1. 私有成员变量,提供get和set方法
    2. 将代码抽取到方法中,这是对代码的一种封装
    3. 将属性抽取到类当中,这是对数据的一种封装
  • 封装的好处:
    1. 提高了代码的安全性
    2. 提高了代码的复用性
  • 现实生活中的封装,比如汽车,我们不知道发动机的构造,但是只要考个驾驶证,知道怎么开就行了。

15-构造方法的格式和执行时机

  • 构建、创造对象的时候,所调用的方法

  • 格式:

    1. 方法名与类名相同,大小写也要一致
    2. 没有返回值类型,连 void 都没有
    3. 没有具体的返回值(不能由 return 带回结果数据)
  • 创建时机

    1. 创建对象的时候自动调用,每次创建对象,就会执行一次构造方法
    2. 构造方法不能手动调用。
  • 构造方法的作用

    • 创建对象
    • 给成员变量赋初始值

16-构造方法的使用

  • 给对象的数据(属性,成员变量)进行赋值

  • public class Student {
    
        private int age;
    
        public int getAge() {
            return age;
        }
    
        public Student(int age) {
            this.age = age;
        }
    
  • public static void main(String[] args) {
            Student stu1 = new Student(18);
            Student stu2 = new Student(38);
            Student stu3 = new Student(48);
            System.out.println(stu1.getAge());//18
            System.out.println(stu2.getAge());//38
            System.out.println(stu3.getAge());//48
    
        }
    

17-构造方法的注意事项

  1. 构造方法的创建
    • 如果没有定义构造方法,系统将给出一个默认的无参数构造方法public Student(){}
    • 如果定义了构造方法,系统将不再提供默认的构造方法
  2. 构造方法的重载
    • 如果自定义了带参数的构造方法,还要使用无参数构造方法,就必须写一个无参构造方法
  3. 推荐使用方式
    • 无论是否使用,都动手书写无参数构造方法,和带参数构造方法

18-标准类的代码编写和使用

  1. 成员变量
    • 使用private修饰
  2. 构造方法
    • 提供一个无参构造方法
    • 提供一个带多个参数的构造方法
  3. 成员方法
    • 提供每一个成员变量对应的set和get方法
    • 提供一个显示对象信息的show()方法
  4. 创建对象并为其成员变量赋值的两种方式
    • 无参构造方法创建对象后使用setXxx()方法赋值
    • 使用带参数的构造方法直接创建带有属性值的对象

  • 像Student这种类提供默认无参和有参构造方法,还提供getXxx和setXxx方法,是专门封装数据,也称之为封装数据类,或是javaBeen类

08-day-String概述

00、API

  • API 应用程序接口(Application Programmin Interface)
    • java api, 别人写好的一些类,我们直接使用即可
  • API 文档(类的说明文档)

01、String概述

  • String类在java.lang包下,所以使用的时候不需要导包

  • String类代表字符串,java程序中的所有字符串文字(例如"abc")都被实现为此类的实例,

  • 也就是说,Java程序中所有的双引号字符串,都是String类的对象

  • 字符串不可变,他们的值在创建后不能被更改

  • 因为String对象是不可变的,所以可以共享 当使用new String(),会在堆内存开辟空间,不能共享

  • String str1 = "abc";
    str1 = "123";//这一步是让str1这个字符串类型的变量,记录了一个新的对象
    
 String s = null;
        int length = s.length();//获取字符串的长度(字符个数)
        //NullPointerException  没有创建对象,调用对象的任何方法,都会抛出此异常
        System.out.println(length);//NullPointerException

02、 String类常见构造方法

  • String类常见的构造方法
    • public String(); 创建一个空白字符串对象,不含有任何内容
    • public String(char [] ch);根据字符数组的内容,来创建字符串对象
    • public String(String original); 根据传入字符串内容,来创建字符串对象
    • String str = “abc”; 直接赋值的方式创建字符串对象,内容就是abc
  • 注意
    • String这个类比较特殊,打印其对象名的时候,不会出现内存地址,而是该对象所记录的真实内容
 String str1 = new String();
        System.out.println(str1);//空的字符串
        char[] ch = {'a','b','c'};
        String str2 = new String(ch);
        System.out.println(str2);//abc
        String str3 = new String("123");
        System.out.println(str3);//123
        String str4 = "张三";
        System.out.println(str4);//张三

03、创建字符串对象的区别对比

  • 通过"abc",双引号创建的字符串对象,系统会检查字符串常量池中是否存在,不存在,则创建;存在,直接复用,不再创建

  • 通过new 创建的字符串对象,每一次new 都会申请一个内存空间,虽然内容相同,但是地址不同。

  • JDK7一下,字符串常量池存在方法去中,JDK7以上,字符串常量池被挪到了堆内存中

char[] ch = {'a','b','c'};
      String str1 = new String(ch);
      String str2 = new String(ch);
      System.out.println(str1 == str2);//false

      String str3 = "abc";
      String str4 = "abc";
      System.out.println(str3 == str4);//true

04、String特点-常见面试题

  • String str1 = "abc";
            String str2 = new String("abc");
            System.out.println(str1 == str2);//false
    
  • 在栈内存中,他们的引用地址是不同的

  • 当字符串之间使用 + 号拼接的时候,系统底层会自动创建一个StringBuilder对象,然后再调用其append()方法完成拼接

    拼接后,再调用toString()方法转换为String 类型

 String str1 = "abc";
  
        String str2 = "a" + "b" + "c";

        System.out.println(str1 == str2);//true
  • java存在常量优化机制,在编译的时候,会将"a" + “b” + “c” 拼接为 “abc”

    比如:

byte a = 10;
        byte b = 20;

        //byte c = a + b;//报错

        byte c = 10+20;
        //字面值常量,值是固定的,编译器有优化,如果这个值在左边的类型范围内 ,就编译通过byte c = 30;

05、字符串的比较

  • 字符串的内容作比较,public boolean equals(Object anObject)
  • str1不能为null,不能编译报错,空指针**
 String str1 = "abc";
      String str2 = "ABC";
      String str3 = "abc";
        System.out.println(str1.equals(str2));//false,str1不能为null,不能编译报错,空指针
        System.out.println(str1.equals(str3));//true
        System.out.println(str1.equalsIgnoreCase(str3));//true,忽略大小写
        System.out.println(str1 == str2);//false
        System.out.println(str1 == str3);//true
        System.out.println(str2 == str3);//false
  • 字符串内容作比较,忽略大小写 public boolean equalsIgnoreCase(String anotherString)

06、用户登录案例

    public static void main(String[] args) {

        String userName = "admin";
        String password = "123456";
        Scanner sc = new Scanner(System.in);
        for (int i = 1; i <= 3; i++) {
            System.out.println("请输入用户名:");
            String inputName = sc.next();
            System.out.println("请输入密码:");
            String inputPassword = sc.next();
            if (userName.equals(inputName) && password.equals(inputPassword)) {
                System.out.println("欢迎" + userName + "进入系统~~~");
                break;
            } else {
                if (i == 3) {
                    System.out.println("登录次数已达上限,请明天在登录!!!");
                } else {
                    System.out.println("登录失败!您还有" + (3 - i) + "次登录的机会!");
                }
            }
        }

    }

07、字符串的遍历

  • public int length()
    • 返回此字符串的长度。 长度等于字符串中的数字Unicode code units
  • public char charAt(int index)
    • 返回char指定索引处的值。 指数范围为0至length() - 1 。 该序列的第一个char值在索引0 ,下一个索引为1 ,依此类推,与数组索引一样。
  • public char[] toCharArray()
    • 将此字符串转换为新的字符数组。
      结果
      一个新分配的字符数组,其长度是该字符串的长度,其内容被初始化为包含由该字符串表示的字符序列。
  • 求字符串长度,再通过charAt方法
String str = "abcdefghijk";
        String str1 = "";
        int strLength = str.length();
        for (int i = 0; i < strLength; i++) {
            System.out.println(str.charAt(i));
        }
  • 字符串转为字符数组,遍历数组
  String str = "abcdefghijk";
        char[] chArray = str.toCharArray();

        for (int i = 0; i < chArray.length; i++) {
            System.out.println(chArray[i]);
        }

08、统计字符字数

/**
         * 统计一个字符串中,大写字母,小写自摸,数字出现的次数
         */

        String str = "abcDEFGH9876";

        char[] chArr = str.toCharArray();

        int bigCount = 0;//统计大写字母

        int smallCount = 0;//统计小写字母

        int numCount = 0;//统计数字

        for (int i = 0; i < chArr.length; i++) {
            char ch = chArr[i];
            if (ch >= 'A' && ch <= 'Z'){
                bigCount++;
            } else if (ch >= 'a' && ch <= 'z') {
                smallCount++;
            } else if (ch >= '0' && ch <= '9') {
                numCount++;
            }
        }
        System.out.println("大写字母"+bigCount);
        System.out.println("小写字母"+smallCount);
        System.out.println("数字"+numCount);

09、手机号屏蔽-字符串截取

  • public String substring(int beginIndex)

    • 返回一个字符串,该字符串是此字符串的子字符串。 子字符串以指定索引处的字符开头,并扩展到该字符串的末尾
    • 参数:beginIndex - 开始索引(含)。
    • 异常:IndexOutOfBoundsException - 如果 beginIndex为负或大于此 String对象的长度。
  • public String substring(int beginIndex,int endIndex)

    • 返回一个字符串,该字符串是此字符串的子字符串。 子串开始于指定beginIndex并延伸到字符索引endIndex - 1 。 因此,子串的长度为endIndex-beginIndex 。
    • 参数
      • beginIndex - 开始索引,包括。
      • endIndex - 结束索引,不包括。
  • substring():异常:IndexOutOfBoundsException - 如果 beginIndex为负或大于此 String对象的长度。

手机号:15312347896 ====>屏蔽后 153****7896

String str = "15312347896";

        String str1 = str.substring(0,3);
        System.out.println(str1);//153

        String str2 = str.substring(7);
        System.out.println(str2);//7896

        System.out.println(str1+"****"+str2);//153****7896

10、敏感词替换-字符串替换

  • public String replace(char oldChar,char newChar)

    • 返回从替换所有出现的导致一个字符串oldChar在此字符串newChar

      String oldStr = "abbccc123_dddd123abc";
              
              //把oldStr字符串中的出现的  c 替换成  C
              String newStr = oldStr.replace('c','C');
              System.out.println(newStr);//abbCCC123_dddd123abC
      
    • String oldStr = "abbccc123_dddd123abc";
       		String newStr = oldStr.replace('Z','K');
             System.out.println(newStr);//abbccc123_dddd123abc
             System.out.println(newStr == oldStr); // true
      
  • public String replace(CharSequence target,CharSequence replacement)

    • 将与字面目标序列匹配的字符串的每个子字符串替换为指定的字面替换序列。 替换从字符串开始到结束.

    • String oldStr = "abbccc123_dddd123abc";
       
             String newStr = oldStr.replace("123","***");
             System.out.println(newStr);//abbccc***_dddd***abc
      

11、切割字符串

public static void main(String[] args) {
        String oldStr = "boo:and:foo      ";
        //使用 : 分隔字符串,会返回一个字符串数组
        String[] split = oldStr.split(":");
        System.out.println(split[0]);//boo
        System.out.println(split[1]);//and
        System.out.println(split[2]);//foo

        
        //不是很理解
       // public String[] split(String regex,int limit)
        /**
         *limit参数控制应用模式的次数,因此影响生成的数组的长度。
         * 如果极限n大于0,则模式最多应用n -1次,数组的长度不大于n ,
         * 数组的最后一个条目将包含超出最后一个匹配分隔符的所有输入。
         * 如果n是非正的,那么模式将被应用到尽可能多的次数,并且数组可以有任何长度。
         * 如果n为0,则模式将被应用尽可能多次,数组可以有任何长度,并且尾随的空字符串将被丢弃。
         */

        /**
         * Regex Limit Result
         * : 2 { "boo", "and:foo" }
         * : 5 { "boo", "and", "foo" }
         * : -2 { "boo", "and", "foo" }
         * o 5 { "b", "", ":and:f", "", "" }
         * o -2 { "b", "", ":and:f", "", "" }
         * o 0 { "b", "", ":and:f" }
         */
        String[] split1 = oldStr.split(":", 3);
        System.out.println(split1[0]);
        System.out.println(split1[1]);
        System.out.println(split1[2]);


    }
  • 当匹配不到的时候,返回字符串本身,split[0] = “hello-world-java”

      String s = "hello-world-java";
            //按照"-"进行切割
            String[] split = s.split(",");
            System.out.println(split.length);//1
            for (int i = 0; i < split.length; i++) {
                System.out.println(split[i]);//hello-world-java
            }
    
  • 当分隔的字符是特殊字符,在正则表达式中含有特殊含义,需要转义

    String s = "hello?world?java";
            //按照"-"进行切割
            String[] split = s.split("\\?");
            System.out.println(split.length);//1
            for (int i = 0; i < split.length; i++) {
                System.out.println(split[i]);//hello-world-java
            }
    

12、String方法小结

方法名说明
public int indexOf(String str)获取字符串中参数字符的索引,没有找到返回-1
public boolean startsWith(String str)判断字符串以什么开头
poblic boolean endsWith(String str)判断字符串以什么结束
public boolean equals(Object anObject)比较字符串内容,严格区分大小写
public boolean equalsIgnoreCase(String anotherString)比较字符串的内容,忽略大小写
public int length()返回此字符串的长度
public char charAt(int index)返回指定索引处的char值
public char[] toCharArray()将字符串拆分为字符数组返回
public String substring(int beginIndex,int endIndex)根据开始和结束索引进行截取,得到新的字符串(包含头,不包含尾)
public String substring(int beginIndex)从传入的索引处截取,截取到末尾,得到新的字符串
public String replace(CharSequence target,CharSequence replacement)使用新值,将字符串中的旧值替换,得到新的字符串
public String split(String regex)根据传入的规则切割字符串,得到字符串数组
public boolean contains(String str)判断字符串是否包含str字符串
public int compareTo(String anotherString)按字典顺序比较两个字符串。该比较基于字符串中各个字符的 Unicode 值
public String trim()返回字符串的副本,忽略前导空白和尾部空白。
  • 链式编程

    String s = "你会不会玩呀,你大爷的,卧靠,他娘的";
            String replaceAll = s.replaceAll("大爷", "***").replaceAll("卧靠", "***").replaceAll("娘的", "***");
            System.out.println(replaceAll);//你会不会玩呀,你***的,***,他***
    
            System.out.println("------------------");
            String str = "你会不会玩呀,你大爷的...你妹的...你NMD的!!!";
            //把"大爷","妹的","NMD"替换为“****”
            String replace = str.replace("大爷", "***").replace("NMD", "***");
            System.out.println(replace);//你会不会玩呀,你***的...你妹的...你***的!!!
    

12-01、public int compareTo(String anotherString)

  • 比较字符串大小
    • 按照字典顺序比较两个字符串的大小
    • 参数:被比较的另一个字符串
    • 返回值:1 、 - 1 、0
    • 返回1 的时候,按字典顺序此 String 对象位于参数字符串之后
    • 返回-1 的时候,String 对象位于参数字符串之前,则比较结果为一个负整数
    • 返回0的时候,如果这两个字符串相等,则结果为 0

String 方法归纳

  1. 获取功能

    • 根据索引获取字符 str.charAt(0);
    • 根据字符获取字符索引 str.indexOf(‘a’); 没有查到该字符,返回 - 1
    • 字符串的长度 str.length()
  2. 判断功能

    • str.equals(“abc”) 比较两个字符串的内容是否相同
    • str.equalsIgnoreCase(“AbC0”) 比较两个字符串的内容是否相同, 忽略大小写
  3. 截取功能

    • str.substring(5) 从自定位置截取,一直到末尾
    • str.substring(2,5); 从指定的开始索引截取到指定的结束索引
  4. 切割功能

    • str.split(regex); 通过传入的正则表达式,对字符串进行分割
  5. 替换功能

    • str.replace(“TMD”,“***”); 对字符串中的词进行替换
  6. 转换功能

    • str.toLowerCase() 对字符串的英文字母转小写
    • str.toUpperCase() 对字符串的英文字母转大写
    • str.toCharArray() 把字符串转换成字符数组
    • str.getBytes() 把字符串转换成byte数组

13、StringBuilder概述

  • StringBuilder 是一个可变的字符串类,我们可以把它看作是一个容器
  • 作用:提高字符串的操作效率

14、StringBuilder的构造方法

  1. public StringBuilder() 创建一个空白可变字符串对象,不含有任何内容

    //空参构造方法  public StringBuilder()
            StringBuilder stringBuilder1 = new StringBuilder();
            System.out.println(stringBuilder1);//没有任何内容打印输出
    
  2. public StringBuilder(String str) 根据字符串的内容,来创建可变的字符串对象

    //空参构造方法  public StringBuilder()
            StringBuilder stringBuilder1 = new StringBuilder();
            System.out.println(stringBuilder1);//没有任何内容打印输出
    

15、StringBuilder常用的成员方法

成员方法说明
public StringBuilder append(任意类型)添加数据,并返回对象本身
public StringBuilder reverse();返回相反的字符串序列
public int length()返回长度(字符出现的个数)
public String toString()通过toString()就可以实现把StringBuilder转换为String
  • public StringBuilder append(任意类型)

      //创建一个空参构造  StringBuilder
            StringBuilder sb = new StringBuilder();
            //添加元素
            StringBuilder str1 = sb.append("毛蛋");
    
            System.out.println(sb);//毛蛋
            System.out.println(str1);//毛蛋
            System.out.println(sb == str1);//true
    
            //append()方法返回的是StringBuilder对象本身
    
            StringBuilder str2 = str1.append("二狗");
            System.out.println(sb);//毛蛋二狗
            System.out.println(str1);//毛蛋二狗
            System.out.println(str2);//毛蛋二狗
            System.out.println(str2 == str1);//true
    
            //链式编程
    
            sb.append("张三").append("李四").append("王五");
            System.out.println(sb);//毛蛋二狗张三李四王五
    
  • public StringBuilder reverse();

    //创建带参的构造方法
            StringBuilder sb = new StringBuilder("abcdefg");
    
            // reverse(),可StringBuilder的字符串反转
    
            StringBuilder reverse = sb.reverse();
    
            System.out.println(reverse);//gfedcba
    
  • public int length()

    //创建带参的构造方法
            StringBuilder sb = new StringBuilder();
    
            sb.append("0123456789");
            
            //求字符串的长度
            int length = sb.length();
    
            System.out.println(length);//10
    
  • public String toString()

 //创建带参的构造方法
        StringBuilder sb = new StringBuilder();

        sb.append("0123456789");

        String str = "0123456789";

//        System.out.println(sb == str);
        //需要把StringBuilder转换为String再进行比较
        String s = sb.toString();

        System.out.println(s == str);//false,因为地址不同,一个在字符串常量池,一个在堆内存

        System.out.println(str.equals(s));//true,equals()进行的是内容比较,区分大小写

16、StringBuilder提高效率的原理

  • + 符号做拼接字符串的,底层都会创建一个StringBuilder类,再调用StringBuilder类的toString()方法返回字符串

  • 使用StringBuilder类的append()方法添加字符串,只会创建一个StringBuilder类的对象

17、对称字符串案例-String和StringBuilder之间的转换

String s = "abc123321cba";

        StringBuilder sb = new StringBuilder(s);

        //字符串反转
        sb.reverse();

        //StringBuilder再转换为String
        String s1 = sb.toString();

        //调用String类的equals()方法判断内容是否相同

        //System.out.println(s.equals(s1));
        if (s.equals(s1)){
            System.out.println("字符串"+s+"是对称字符串");
        }else {
            System.out.println("字符串不是对称字符串");
        }

18、StringBuilder拼接字符串案例

public static void main(String[] args) {

        /**
         * 需求:定义一个方法,把int数组中的数据按照指定的格式拼接成
         *      一个字符串返回,调用该方法,并在控制台输出结果
         *      例如:数组 int[] arr ={1,2,3,4},打印结果 [1,2,3,4]
         */

        /**
         * 思路
         *      1、定义一个int类型的数组,用静态初始化完成数组元素的初始化
         *      2、定义一个方法,用于把int数组中的数据按照指定格式拼接成一个字符串返回,返回值类型String,参数列表int[] arr
         *      3、在方法中调用StringBuilder按照要求进行拼接,并把结果转成String返回
         *      4、调用方法,用一个变量接收结果
         *      5、输出结果
         */

        //1、定义一个int类型的数组,用静态初始化完成数组元素的初始化
        int[] arr ={1,2,3,4};
        //4、调用方法,用一个变量接收结果
        String s = returnArrayToString(arr);
        // 5、输出结果
        System.out.println(s);//[1, 2, 3, 4]

    }
    //2、定义一个方法,用于把int数组中的数据按照指定格式拼接成一个字符串返回,返回值类型String,参数列表int[] arr
    public static String returnArrayToString(int[] arr){
        //3、在方法中调用StringBuilder按照要求进行拼接,并把结果转成String返回
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i = 0; i < arr.length; i++) {
            //处理最后一个元素
            if (i == arr.length-1){
                sb.append(arr[i]);
            }else {
                sb.append(arr[i]+", ");
            }
        }
        sb.append("]");
        return sb.toString();
    }

09-day-学生管理系统

01、集合和数组的区别对比

  • 集合类的特点:提供一种存储空间可变的存储模型,存储的数据容量可以发生改变

  • 集合和数组的区别:

    • 共同点:都是存储数据的容器
  • 不同点:

    • 数组

      • 长度是固定,元素存储有序,有索引,元素可以重复
      • 能存储基本数据类型,也能存储引用数据类型

    • 集合

    • 可以动态扩容,针对Set和Map集合,元素存储无序(LinkedHashSet和LinkedHashMap除外),没有索引,元素不能重复

    • 只能存储引用数据类型的数据


    如果存储的数据经常发生改变,推荐使用集合

  • ArrayList list 这个对象list 是引用数据类型,但是打印 list 输出的不是它的地址值
  • 数组和集合适合的场景
    1. 数组适合用于数据个数和类型都确定的场景
    2. 集合适合用于数据个数不确定,且要动态进行增删的场景

02、ArrayList的构造方法和添加方法

方法名说明
public ArrayList()创建一个空的集合对象
public boolean add(element)将指定的元素追加到集合的末尾
public void add(int index,element)在此集合中的指定位置插入指定的元素

ArrayList: 是一种特殊的数据类型 ,泛型

举例: ArrayList , ArrayList

  • 指定位置处插入一个元素

    //new ArrayList<>();JDK7以上,后一个泛型可以不写类型,会自动匹配
        ArrayList<Integer> list = new ArrayList<>();
        list.add(111);
        list.add(222);
        //在第 0 个索引处插入一个元素
        list.add(0,666);
        System.out.println(list);//[666, 111, 222]
    
  • ArrayList没有泛型限定的时候,什么数据类型都能存储

    //无参构造创建
        ArrayList list = new ArrayList<>();
        //在集合末尾追加元素
        list.add(123);
        list.add("abc");
        list.add(true);
        System.out.println(list);//[123, abc, true]
    
  • ArrayList有泛型限定的时候,只能存储被限定的数据类型,泛型不能是基本数据类型,只能是引用类型或是包装类

     ArrayList<String> list = new ArrayList<String>();
        //在集合末尾追加元素
        //list.add(123);//编译报错
        list.add("abc");
        //list.add(true);//编译报错
    

03、ArrayList常用成员方法

方法名说明
public boolean remove(Object o)删除指定的元素,返回被删除的元素
public E remove(int index)删除指定索引处的元素,返回被删除的元素
public E set(int index,E element)修改指定索引处的元素,返回被修改的元素
public E get(int index)返回指定索引处的元素
public int size()返回集合中的元素个数
ArrayList <String> list = new ArrayList<>();

    list.add("aaa");
    list.add("bbb");
    list.add("ccc");
    list.add("ddd");
    list.add("eee");
    list.add("fff");
    list.add("ggg");
    list.add("hhh");
    System.out.println(list);//[aaa, bbb, ccc, ddd, eee, fff, ggg, hhh]

    //根据传入的元素删除集合list 中的元素,返回值布尔,删除成功返回true,失败返回false
    boolean bl = list.remove("zzz");// bl = false
    boolean b2 = list.remove("aaa");// b2 = true
    System.out.println(list);//[bbb, ccc, ddd, eee, fff, ggg, hhh]

    //  根据索引删除集合中的元素,
    String remove = list.remove(0);
    System.out.println(remove);//bbb
    System.out.println(list);//[ccc, ddd, eee, fff, ggg, hhh]

    //修改集合中的元素
    String str = list.set(0, "AAA");
    System.out.println(str);//ccc,返回被修改的元素
    System.out.println(list);//[AAA, ddd, eee, fff, ggg, hhh]

    //查询集合中的元素
    String str1 = list.get(0);
    String str2 = list.get(1);
    String str3 = list.get(2);
    System.out.println(str1);//AAA
    System.out.println(str2);//ddd
    System.out.println(str3);//eee

    //获取集合的长度
    int listLength = list.size();
    System.out.println(listLength);//6

04、集合存储字符串并遍历

ArrayList <String> list = new ArrayList<String>();
    list.add("aaa");
    list.add("bbb");
    list.add("ccc");
    //使用for循环
    for (int i = 0; i < list.size(); i++) {
      System.out.println(list.get(i));
    }
    
    //使用Iterator迭代器,进行遍历
    Iterator iterator = list.iterator();

    while (iterator.hasNext()){
      System.out.println(iterator.next());
    }

05、集合存储学生对象并遍历

06、键盘录入学生成绩信息到集合

 public static void main(String[] args) {
        System.out.println("请输入第一个学生的信息:");
        Student stu1 = getStudent();
        System.out.println("请输入第二个学生的信息:");
        Student stu2 = getStudent();
        System.out.println("请输入第三个学生的信息:");
        Student stu3 = getStudent();
        //使用集合进行遍历
        ArrayList <Student> list = new ArrayList<>();
        list.add(stu1);
        list.add(stu2);
        list.add(stu3);
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i).getName()+"...."+list.get(i).getAge());
        }
    }
    //键盘录入学生的信息
    public static Student getStudent(){
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入学生的姓名:");
        String name = sc.next();
        System.out.println("请输入学生的年龄:");
        int age = sc.nextInt();
        Student stu = new Student(name,age);
        return stu;
    }

07、集合删除元素

  • list.get(i).equals(“666”),当list.get(i) 为null 的时候,会报错,空指针
ArrayList list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("666");
        list.add("ddd");
        list.add("666");
        list.add("666");
        list.add("aaa");
        //把集合中666给删除
        /*//只会删除第一个被匹配到的元素
        boolean bl = list.remove("666");
        System.out.println(list);//[aaa, bbb, ddd, 666, 666, aaa]*/

     /*   for (int i = 0; i < list.size(); i++) {
            if ("666".equals(list.get(i))){
                list.remove(i);
            }
        }
        System.out.println(list);//[aaa, bbb, ddd, 666, aaa]*/

        //[aaa, bbb, ddd, 666, aaa]  由于删除过集合中的元素,list.size()会减小,而i++不断增长,会跳过某个元素
        for (int i = 0; i < list.size(); i++) {
            if ("666".equals(list.get(i))){
                list.remove(i);
                i--;
            }
        }
        System.out.println(list);//[aaa, bbb, ddd, aaa]

08、集合数据筛选

public static void main(String[] args) {
        //需求:定义一个方法,方法接收一个集合对象(泛型为Student),
        // 方法内部将年龄低于18的学生对象找出并存入新集合
        //对象,方法返回新集合

        //创建一个集合对象
        ArrayList<Student> list = new ArrayList<>();
        //创建学生对象
        Student stu1 = new Student("张三", 23);
        Student stu2 = new Student("李四", 17);
        Student stu3 = new Student("王五", 35);
        Student stu4 = new Student("赵六", 16);
        Student stu5 = new Student("钱七", 18);
        list.add(stu1);
        list.add(stu2);
        list.add(stu3);
        list.add(stu4);
        list.add(stu5);
        System.out.println(returnStudent(list));//[Student{name='李四', age=17}, Student{name='赵六', age=16}]
    }

    //定义一个方法,接收集合对象
    public static ArrayList<Student> returnStudent(ArrayList<Student> students) {
        //方法内部将年龄低于18的学生对象找出并存入新集合
        ArrayList<Student> list = new ArrayList<>();
        for (int i = 0; i < students.size(); i++) {
            if (students.get(i).getAge() < 18){
                list.add(students.get(i));
            }
        }
        return list;
    }
--------------------榆木脑袋,炼气期一层--------------------2024-03-25 23:1820

本文标签: 基础Java