流程控制与数组
流程控制
分支结构
1.使用switch语句时,两个注意点:
(1)switch语句后的expression表达式的数据类型只能是 byte、short、char、int四种整数类型,String(从Java7开始支持)和枚举类型
(2)如果省略了case后代码块的break;,将引入一个陷阱,代码按顺序执行
循环结构
循环语句可能包含以下4个部分
(1)初始化语句:一条或多条语句,用于完成初始化工作,在循环开始之前执行
(2)循环条件:是一个boolean表达式,决定是否执行循环体
(3)循环体:如果循环条件允许,代码块将被重复执行,如果该代码块只有一行,可以省略花括号
(4)迭代语句:在一次循环体执行结束后,对循环条件求值之前执行,用于控制循环条件中的变量,使得循环在合适的时候结束
1.while循环语句
语法格式如下:
[init_statements]
while (test_expression){
statement;
[iteration_statement]
}
while循环每次执行前,先对test_expression循环条件求值,如果条件为true,运行循环体。从语法格式来看,迭代语句iteration_statement总是位于循环体的最后,因此只有循环体能成功完成时,while才会执行iteration_statement迭代语句。
2.do while循环语句
语法格式如下:
[init_statement]
do
{
statement;
[iteration_statement]
}while (test_expression);
与while的区别在与:while循环是先判断循环条件,成立才执行循环体,do while循环先执行循环体,然后才判断循环条件,条件为真,则执行下一次循环。即使test_expression循环条件的值开始就是假,do while也会执行循环体。do while循环体至少执行一次。
do while 循环的循环条件后必须有一个分号,这个分号表明循环结束。
3.for循环
语法格式如下:
for([init_statement];[test_expression];[iteration_statement]){
statement
}
建议不要在循环体内修改循环变量,否则会增加程序出错的可能性,如果程序需要访问,修改循环变量值,建议重新定义一个临时变量,先将循环变量的值赋给临时变量,然后对临时变量的值进行修改。
嵌套循环:外层循环走一个,内层循环走一圈
控制循环结构
1.使用break结束循环
不管是哪种循环,一旦在循环体中遇到break,系统将完全结束该循环。开始执行循环之后的代码。
break语句不仅可以结束其所在的循环,还可以直接结束其外层循环,此时需要在break后紧跟一个标签,这个标签用于标识一个外层循环。
java中标签就是一个紧跟着英文冒号(:)的标识符,只有放在循环语句之前才有作用。
例子如下:
public class BreakLabel
{
public static void main(String [] args)
{
//外层循环,outer作为标识符
outer:
for(var i = 0;i < 5;i++){
//内层循环
for(var j = 0; j< 3;j++){
System.out.println("i的值为"+i+"j的值为"+j){
if(j == 1){
//跳出outer标签所标识的循环
break outer;
}
}
}
}
}
}
2.使用continue忽略本次循环剩下的语句
continue忽略本次循环剩下语句,接着开始下一次循环,并不会终止循环;而break则是完全终止循环本身。
continue后也可以紧跟一个标签,用于直接跳过标签所表示循环的当次循环的剩下语句,重新开始下一次循环。
3.使用return结束方法
return关键字并不是专门用于结束循环的,return的功能是结束一个方法。一旦在循环体内执行到一个return语句,return语句就会结束该方法,循环自然也随之结束。
数组
数组类型
Java数组要求所有的数组元素具有相同的数据类型,一旦数组的初始化完成,数组在内存中所占的空间将被固定下来,因此数组的长度将不可变,即使把某个数组元素的数据清空,但它所占的空间依然被保留,依然属于该数组,数组长度不变。
数组定义
语法格式:
type[] arrayName;
数组初始化
所谓初始化就是为数组的数组元素分配内存空间。
1.静态初始化
定义:显示指定每个元素的初始值,由系统决定数组长度
语法格式:
arrayName = new type[]{element1,element2,element3}
或者:
type[] arrayName = {element1,element2,element3}
2.动态初始化
定义:动态初始化只指定长度,由系统为每个数组元素指定初始值。
语法格式:
arrayName = new type[length];
不同类型下系统给定的默认值:
整数类型(byte、short、int、long)初值为0
浮点类型(float、double)初值为0.0
字符类型(char)初值为’u\0000’
布尔类型(boolean)初值为false
引用类型(类、接口和数组)初值为null
ps:利用索引来访问数组中的数据,注意不可以访问数组长度的索引。
foreach循环
语法格式:
for(type cariableName : array|collection){
//variableName自动迭代访问每个元素
}
深入数组
数组是一种引用数据类型,数组引用变量只是一个引用,数组匀速和数组变量在内存哪里是分开存放的。
1.内存中的数组
实际的数组对象被存储在堆内存中,如果引用该数组对象的数组引用变量是一个局部变量,那么它被存储在栈内存中。
public class ArrayInRam{
public static void main(String [] args){
int [] a = {5,7,20};
var b = new int[4];
System.out.println("b数组的长度为"+b.length)
b=a
System.out.println("b数组的长度为"+b.length)
}
}
内存中的解析:
当程序定义并初始化了a、b两个数组后,系统内存中实际上产生了4块内存区,其中栈内存中有两个引用变量,a和b;堆内存中也有两块内存区,分别用于存储a和b引用所指向的数组本身。当执行b=a;时系统把a的值赋给b,a和b都是引用类型变量,存储的是地址,所以b指向了a所指向的地址。
2.引用类型数组的初始化
引用类型的数组元素是引用、它指向另一块内存,这块内存里存储了有效数据。
class Person
{
public int age;
public double height;
public void info(){
System.out.println("我的年龄是"+age+",我的身高是:"+height);
}
}
public class ReferenceArrayTest{
public static void main(String[] args){
//定义一个students数组变量,其类型是Person
Person[] students;
//执行动态初始化
students = new Person[2];
//创建一个Person实例,并将这个Person实例赋给zhang变量
var zhang = new Person();
//赋值
zhang.age = 15;
zhang.height = 158;
var lee = new Person();
lee.age = 16;
lee.height = 161;
//将zhang变量赋给第一个数组元素
students[0] = zhang;
students[1] = lee;
lee.info();
students[1].info();
}
}
内存中的解析:
创建两个Person实例后的存储示意图
为数组元素赋值后的存储示意图
程序依次将zhang和lee赋给students数组的第一个和第二个元素后,students数组的两个数组元素将会指向有效的内存区,此时zhang和students[0]指向同一个内存区,而且他们都是引用类型变量,因此通过zhang和students[0]来访问Person实例的实例变量和方法的效果完全一样,无论修改哪个实例变量,所修改的其实是同一个内存区。
来源:CSDN
作者:DIDI___
链接:https://blog.csdn.net/DIDI___/article/details/104076947