判断和循环
01.流程控制语句(顺序结构, 分支结构, 循环结构)
顺序结构:
顺序结构语句是Java程序默认的执行流程,按照代码的先后顺序,从上到下依次执行
分支结构(if和switch):
if 语句的第一种格式:
if (关系表达式){ 语句体; }
if的注意点:
大括号的开头可以另起一行书写,但是建议写在第一行的末尾
在语句体中,如果只有一句代码,大括号可以省略不写
如果对一个布尔类型的变量进行判断,不要用==号,直接把变量写在小括号即可
if语句的第二种格式
if (关系表达式){ 语句体1; }else{ 语句体2; }
if语句的第三种格式
if (关系表达式1){ 语句体1; }else if (关系表达式2){ 语句体2; } ... else { 语句体 n + 1; }
switch语句格式:
switch(表达式){ case 值1: 语句体1; break; case 值2: 语句体2; break; ... default: 语句体n+1; break; }
格式说明:
表达式:(将要匹配的值)取值为byte, short, int, char.
case: 后面跟的是要和表达式进行比较的值(被匹配的值)
break:表示中断,结束的意思,用来结束switch语句
default:表示所有情况都不匹配的时候,就执行该处的内容,和if语句的else相似
case后面的值只能是字面量,不能是变量
case给出的值不允许重复
switch的其他知识点:
default的位置和省略
case穿透(没有写break导致的) (如果多个case的语句体重复了,可以考虑利用case穿透简化代码)
switch的新特性( 利用箭头简化代码书写,但JDK12之后的版本才有)
switch和if的第三种格式各自的使用场景 (if 范围 ; switch 有限个数列举)
循环结构:
重复的做某件事情,具有明确的开始和停止标记
循环的分类: for; while; do... while
for循环格式:
for(初始化语句;条件判断语句;条件控制语句){ 循环体语句; }
100.fori 可以快速生成语句: for (int i = 0; i < 100; i++) {
while循环格式:
初始化语句; while(条件判断语句){ 循环体语句; 条件控制语句; } 循环下面的其他语句
for和while的对比:
相同点: 运行规则都是一样的
不同点: for循环中,控制循环的变量,因为归属for循环的语法结构中,在for循环结束后,就不能再次被访问到了,(知道循环次数或者循环的范围);
while循环中,控制循环的变量,对于while循环来说不归属其语法结构中,在while循环结束后,该变量还可以继续使用(不知道循环的次数和范围,只知道循
环的结束条件)
do...while循环格式: (用的比较少)
格式化语句: do{ 循环体语句; 条件控制语句; }while(条件判断语句);
02.循环高级和数组
无限循环
无限循环: 循环一直停不下来, 故其下面不能再写其他的代码了
格式:
for(;;){ while(true){ do{ System.out.println("学习"); System.out.println("学习"); System.out.println("学习"); } } }while(true);
跳转控制语句
跳转控制语句:在循环的过程中,跳到其他语句上执行
continue: 跳过本次循环,继续执行下次循环
break: 结束整个循环
综合练习(获取随机数)
获取随机数(不能写在循环里面否则每一次都会产生一个新的随机数)
1.导包
import java.util.Random
2.创建对象
Random r = new random();
3.生成随机数
int number = r.nextInt(随机数的范围); 这个范围是从0开始,到这个数-1结束 (包头不包尾,包左不包右)
若想获取任意范围的随机数
例:想获取7-15之间的任意数(包含7且包含15) 1.让这个范围头尾都减去一个值 使范围从0开始 即-7 0-8 2.尾巴+1 8+1=9 3.最终的结果 再加上第一步减去的值 int number = r.nextInt(9)+7
数组
数组: 指的是一种容器,可以用来存储同种数据类型的多个值
在存储数据的时候,需要结合隐式转换考虑 建议容器的类型和存储的数据类型保持一致
数组的定义
格式一:(用的比较多) 格式二: 数据类型[] 数组名 数据类型 数组名[] int [] array int array[]
数组的初始化(静态)
数组的静态初始化
初始化:就是在内存中,为数组容器开辟空间,并将数据存入容器中的过程
简化格式: 完整格式: 数据类型[]数组名={元素1,元素2,元素3...}; 数据类型[]数组名 = new 数据类型[]{元素1,元素2 ..}; int[]array = {11, 22, 33}; int[] array = new int[]{11,22,33};
数据的地址值:表示数组在内存中的位置
[D@1b6d3586 : (平时习惯把这个整体叫做数组的地址值)
[ : 表示当前是一个数组
D: 表示当前数组里面的元素都是double类型的
@: 表示一个间隔符号(固定格式)
1b6d3586 : 这才是数组真正的地址值 (十六进制)
数组元素访问
格式: 数组名[索引];
索引:也叫做下标,角标 特点: 从0开始,逐个+1增长,连续不间断
获取数组里面的元素: double[] arr = {1.93,1.75,1.73,1.81}; double number = arr[0]; System.out.println(number); System.out.println(arr[1]);
把数据存储到数组当中: 格式: 数组名[索引] = 具体数据/变量 arr[0] = 100; 一旦覆盖之后 原来的数据就不存在了
数组遍历
数组遍历: 将数组中的所有内容取出来,取出来之后可以(打印,求和,判断...) 遍历指的是取出数据的过程,而不是单纯的打印
在Java当中,关于数组的一个长度属性,length 调用方式: 数组名.length
快捷输入: arr.fori → for (int i = 0; i < arr.length; i++)
i 依次表示数组里面的每一个索引 arr[i] 依次表示数组里面的每一个元素
一个循环尽量只做一件事情 比如在循环里进行了数学运算后 还需要把结果打印出来 最好在循环外再写一个循环用来打印结果 而不是把打印语句直接写在上一个循环中
数组的动态初始化
动态初始化: 初始化时只指定数组长度,由系统为数组分配初始值
格式:数据类型[]数组名 = new 数据类型[数组长度]; 在创建的时候,由我们自己指定数组的长度,由虚拟机给出默认的初始化值 例: int[]arr = new int[3];
数组默认初始化值的规律:
类型: | 默认初始化值 |
---|---|
整数 | 0 |
小数 | 0.0 |
字符 | '/u0000' 打印出来为空格 |
布尔 | false |
引用数据 | null |
数组动态初始化和静态初始化的区别:
动态初始化: 只明确元素个数,不明确具体数值,推荐使用动态初始化
静态初始化:需求中已经明确了要操作的具体数据,直接静态初始化即可
数组内存图
Java内存分配:
栈: 方法运行时使用的内存,比如main方法运行,进入方法栈中执行
堆: 存储对象或者数组,new来创建的,都存储在堆内存
方法区: 存储可以运行的class文件
本地方法栈: JVM在使用操作系统功能的时候使用,和我们开发无关
寄存器: 给CPU使用,和我们开发无关
(从JDK8开始,取消了方法区,新增元空间.把原来方法区的多种功能进行拆分,有的功能放到了堆中,有的功能放到了元空间中)
栈内存: 程序的主入口(main方法) 开始执行时会进栈,代码执行完毕会出栈
堆内存: new出来的东西会在这块内存中开辟空间并产生地址; 如果new了多次,那么在堆里面有多个小空间,每个小空间中都有各自的数据
当两个数组指向同一个小空间时,其中一个数组对小空间中的值发生了改变,那么其他数组再次访问的时候都是修改之后的结果了
数组常见问题
当访问了数组中不存在的索引,就会引发索引越界异常.
(ctrl + z 可在IDEA中实现退回上一步的操作)
数组常见操作
求最值; 求和; 交换数据; 打乱数据
System.out.print(arr[i] + " "); 把println的ln去掉 这样可以将数组中的数都体现在同一行中
System.out.println //表示不打印任何数据,只做换行处理