流程控制与数组

流程控制与数组

  • 流程控制
  • 分支结构
  • 分支结构的两种形式
  • 循环结构
  • 循环结构的4种形式
  • 循环结构
  • 循环结构的4种形式
  • 数组类型与数组用法

流程控制分为3种结构

  • 顺序结构
  • 分支结构
  • 循环结构

循环结构

  1. 循环结构就是程序从上到下一行到下一行一行地执行,中间没有做任何判断和跳转
  2. 如果main方法多行代码之间没有任何流程控制,则程序总是从上向下执行,排在前面的代码先执行,排在后面的代码后执行。

分支结构

  • Java提供了两种常见的分支控制结构:
    —if语句:使用布尔表达式或者布尔值作为分支条件来进行分支控制

    —switch语句:用于对多个整型值进行匹配,从而实现分支控制

if条件语句

  • if条件语句的3种形式:
  1. if(logic expression){statements…}
  2. if(logic expression){statements} else{statements…}
  3. if(logic expression){statements} else if(logic expression){statements…}

//可以有0个或者多个else if语句

注意:if,else,else if后条件执行体要么是一个花括号括起来的语句块,则这个语句块整体作为条件执行题;要么是以分号为结束符的一行语句,甚至可能是一个空语句(空语句就是一个分号)

if语句常见的错误

  • 如果if、else、else if后的执行体只有一行语句时,则可以省略花括号,但我们最好不要省略花括号,因为保留花括号会有更好的可读性,且还可以减少发生错误的可能
  • 对于if语句,还有一个很容易出现的逻辑错误,这个逻辑错误并不属于语法问题,但引起错误的可能性更大。如下面程序TesIfError.java我们想要打印的是中年人,但打印出来的结果是青年人
  • 对于任何的if else 语句,表面上看起来else后没有任何条件,或者else if后只有一个台哦见,但这不是真相:因为else的含义是“否则”,else本身就是一个条件!else的隐含条件就是对前面条件取反。

switch分支语句

  • 可以省略case后代码块的花括号

    使用break;语句,防止case穿透

    default可以省略,但不推荐省略

    switch语句中控制表达式的类型只能式

    byte、short、char、int、String和枚举

Switch语句容易导致的错误

  • switch语句后的expression表达式的数据类型只能是byte、short、char、int、String类型和枚举
  • 小心省略了case后代码块的break;时所引入的陷阱

基本的循环语句

  • Java支持的3种基本的循环语句:

    —while循环语句

    —do while循环语句

    —for 循环语句

while&do while 循环语句

while 循环的语法格式如下:

[init_statements]
while(test_expression)
{     statements
    [iteration_statements]
}

执行过程:先判断逻辑表达式的值,若为true则执行其后面的语句,然后再次判断条件并反复执行,直到条件不成立为止

1

do while循环的语法格式如下

[init_statements]

do

{        statements;
         [iteration_statements]
}while(test_expression);

注意:do while循环的循环条件必须有一个分号,这个分号表明循环结束。

执行过程:先执行语句,再判断逻辑表达式的值,若为true,再执行语句,否则结束循环

在这里插入图片描述

控制循环条件

  • 使用循环,一定要保证循环条件有变成false的时候,如果循环条件永远为true,那就是死循环。使用while循环时还有一个陷阱,while循环条件后紧跟一个分号
  • do while循环语句里,即使test_expression循环条件的值开始是假,do while循环也会执行循环体。因此,do while循环的循环体至少执行一次

for循环语句

for([inint_statements];[test_expression];
   [iteration_statements]){ statements }
  • 执行过程:首先计算表达式1,即init_statements,接着执行表达式2,即test_expression,若表达式2的值为true,则执行语句(statements),接着执行表达式3,即iteration_statements,再判断表达式2的值;依次重复下去,直到表达式的值=false,则结束for循环。因此,for循环的循环条件(表达式2)比循环体(语句)要多执行一次。
  • 注意:for循环的循环迭代语句并没有与循环体放在一起,因此即使在执行循环体时遇到的continue语句结束本次循环,循环迭代语句一样会得到执行。

for循环指定多个初始化语句

  • for循环允许同时指定多个初始化语句,循环条件也可以是一个包含逻辑运算符的表达式。但只能有一个声明语句,因此如果需要在初始化中声明多个变量,那么这些变量应该有相同的数据类型
  • 初学者使用for循环时也容易犯一个错误,他们以为只要在for后的括号内控制了循环,循环迭代语句就万无一失,但实际情况却不是这样

for循环的分号

  • for循环圆括号中只有两个分号是必须的,初始化语句、循环条件、迭代语句部分都可以省略,如果省略了循环条件,则这个循环条件默认是true,将会产生一个死循环
  • 使用for循环时,还可以把初始化条件定义在循环体之外,把循环迭代语句放在循环体内,这种做法将非常类似前面的while循环

嵌套循环

  • 各种基本类型的循环都可以作为外层循环,各种基本类型的循环也可以作为内层循环
  • 假设外层循环的循环次数为n次,内层循环的循环次数为m次,那么内层循环的循环体实际上需要执行n*m次
  • 实际上,嵌套循环不仅可以是两层嵌套,还可以是三层嵌套,四层嵌套…

break语句

  • break用于完全结束一个循环,跳出循环体。不管是哪种循环,一旦在循环体中遇到break,系统将完全结束循环,开始执行循环之后的代码。
  • break不仅可以结束其所在的循环,还可技术其外层循环。此时需要在break后紧跟一个标签,这个标签用于表示一个外层循环。Java中的标签就是一个紧跟着英文冒号(:)的标识符。且它必须放在循环语句之前才有作用

continue语句

  • continue的功能和break有点类似,区别是continue只是中止本次循环,接着开始下一次循环。而break则是完全中止循环。

return语句

  • return关键字并不是专门用于跳出循环的,return的功能是结束一个方法。
  • 一旦在循环体内执行到一个return语句,return语句将会结束该方法,循环自然也随之结束。与continue和break不同的是,return直接结束整个方法,不管这个return处于多少层循环之内

数组类型

  • 在任何已有类型后加上方括号[],又变成一种新类型,这种类型统称为数组类型,所有的数组类型又称为引用类型,所以又称引用类型。
  • Java的数组要求所有数组元素具有相同的数据类型。因此,在一个数组中,数组元素的类型是唯一的,即一个数组里只能存储一种数据类型的数据,而不能存储多种数据类型的数据
  • 一旦数组的初始化完成,数组在内存中所占的空间将被固定下来,因此数组的长度将不可改变。即使把某个数组元素的数据清空,但它所占的空间依然被保留,依然属于该数组,数组的长度依然不变
  • Java的数组既可以存储基本类型的数据,也可以存储引用类型的数据
  • 值得指出的是:数组也是一种数据类型,它本身是一种引用类型

定义数组

  • Java语言支持两种格式来定义数组:
  • —type[]arrayName;
  • —type arrayName[];
  • 对于这两种语法格式,一般推荐使用第一种格式。因为第一种格式不仅具有更好的语意,也具有更好的可读性
  • 数组是一种引用类型的变量,因此使用它定义一个变量时,仅仅表示定义一个引用变量(也就是定义了一个指针),这个引用变量还未指向任何有效的内存,因此定义数组时不能指定数组的长度
  • 注意:定义数组时不能指定数组的长度

数组的初始化

  • 静态初始化:初始化时由程序员显式指定每个数组的初始值,由系统决定需要的数组长度
  • 动态初始化:初始化时程序员指定数组长度,由系统为数组元素分配初始值

动态初始化

  • arrayName=new type[length]

在上面的语法中,需要指定一个int整形的length参数,这个参数指定了数组的长度,也就是可以容纳数组元素的个数

使用数组

  • 数组最常用的用法就是访问数组元素,包括对数组元素赋值和访问数组元素的值,访问数组元素是通过在数组引用变量后紧跟一个方括号([]),方括号里是数组元素的索引值
  • Java语言的数组索引是从0开始的,也就是说,第一个数组元素的索引值为0,最后一个数组元素的索引为数组长度减1
  • 如果访问数组元素进指定的索引小于0,或者大于等于数组的长度,编译程序不会出现任何错误,但运行:java.lang.ArrayIndexOutOfBoundsException:2(数组索引越界异常),在这个异常提示信息后一个int整数,这个整数就是程序员试图访问的数组索引
  • 所有数组都提供了一个length属性,通过这个属性可以访问数组的长度,一旦获得了数组的长度后,就可以通过通过循环来遍历该数组的每个数组元素

数组常见操作

  • 求出最大值,最小值
  • 折半查找
  • 排序(冒泡,选择)

JDK1.5提供了foreach循环

  • 从JDK 1.5之后,Java提供了一种简单的循环:foreach循环,这种循环遍历数组和集合更加简洁。使用foreach循环遍历数组和集合更加简洁。使用foreach循环遍历数组和集合元素时,无需获得数组和集合长度,无需根据索引来访问数组元素和集合长度,无需根据索引来访问数组元素和集合元素,foreach循环自动遍历数组和集合的每个元素
  • 当使用foreach循环来迭代输出数组元素或集合时,通常不要对循环变量进行赋值,虽然这种赋值在语法上是允许的,但没有太大的意义,而且极容易引起错误

深入数组

  • 数组元素和数组变量在内存里是分开存放的。实际的数组元素是存储在堆(heap)内存中;数组引用变量是一个引用类型的变量,被存储在栈(stack)内存中
  • 如果堆内存数组中不再有任何变量指向自己,则这个数组将成为垃圾,该数组所占的内存将会被系统的垃圾回收机制回收。因此,为了让垃圾回收机制回收一个数组所占的内存空间,则可以将该数组变量赋为null,也就切断了数组引用变量和实际数组之间的引用关系,实际数组也就成了垃圾

3

数组长度不可变

  • 只要类型相互兼容,可以让一个数组变量指向另一个实际的数组,这种操作会产生数组的长度可变的错觉
  • 但由于数组变量整体赋值导致的数组的长度可以改变,只有一个假相

基本类型数组的初始化

对与基本类型数组而言,数组元素的值直接存储在对应的数组元素中,因此,初始化数组时,先为该数组分配内存空间,然后直接将数组元素的值存入对应数组元素之中

public class TestPrimitiveArray
{
 public static void main(String[]args){
     //定义一个int[]类型的数组变量
     int[]iArr;
     //动态初始化数组,数组长度为5
     iArr=new int[5];
     //采用循环方式为每个数组元素赋值
     for(int i=0;i<iArr.length;i++){
         iArr[i]=i+10;
         System.out.println(iArr[i]);
     }
 }   
}

引用类型数组的初始化

  • 引用类型数组的数组元素是引用,因此情况变得更加复杂;每个数组元素里存储的还是引用,它指向另一块内存,这块内存里存储了有效数组。
  • 下面程序将定义一个Person[]数组,接着动态初始化这个Person[]数组,并为这个数组的每个数组元素指定值。程序代码如下:
TestReferenceArray.java

没有多维数组

  • Java语言提供了多维数组的语法,但多维数组实质上还是一维数组。Java语言里的数组类型是引用类型,因此,数组变量其实是一个引用,这个引用指向真实的数组内存。数组元素的类型也可以是引用,如果数组元素的引用再次指向真实的数组内存,这种情形看上去很像多维数组
  • 定义二维数组语法:
type [][]arrName;
public static void main(String[]args){
    //定义一个二维数组
    int[][]a;
    //把a当成一位数组进行初始化,初始化a是一个长度维3的整数
    //a数组的元素又是引用类型
    a=new int[3][];
    //把数组当成一维数组,遍历a数组的每个元素
    for(int i=0;i<a.length;i++){
        System.out.println(a[i]);
    }
    //初始化a数组的第一个元素
    a[0]=new int[2];
    //访问a数组的第一个元素所指数组的第二个元素
    a[0][1]=6;
    //a数组的第一个元素是一个一维数组,遍历这个一维数组
    for(int i=0;i<a[0].length;i++){
        System.out.println(a[0][i]);
    }
}

4

我们可以得到一个结论:二维数组是一维数组,其数组元素是一维数组;三维数组也是一维数组,其数组元素是二维数组;四维数组还是一维数组,其数组元素是三维数组…从这个角度来看,Java语言里没有多维数组

Java8增强的Arrays工具类

  • Arrays类里包含的一些static修饰的方法可以直接操作数组
  • Java8增强了Arrays类的功能,Java8为Arrays类增加了一些工具方法,这些工具方法可以充分利用多CPU并行的能力来提高设值,排序的性能。下面是Java8为Arrays类增加的工具方法
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值