流程控制
- 顺序结构
程序从上到下执行。
- 分支结构
- if语句
写法1 :
if(条件表达式1){
代码1
}
条件表达式1为true,才会执行代码1
写法2:2选1
if(条件1){
代码1
}else{
代码2
}
条件1为true ,执行代码1,否则执行代码2
写法3:n选1
if(条件1){
代码1
}else if(条件2){
代码2
}else if(条件n){
代码n
}else{
代码3
}
注意点:
- else 结构可有可无。
- 针对于条件表达式
> 如果多个条件表达式之间是互斥关系,即没有交集的关系,那么判断和执行语句声明在上或在下是无所谓的。
比如 判断整数a 是不是1,是不是0
if(a == 1){
代码1
}else if(a==0){
代码2
}
和
if(a == 0){
代码2
}else if(a==1){
代码1
}
这两个写法是一样。
>如果多个条件表达式之间有交集的关系,则需要根据实际情况,考虑清楚应该将哪个结构声明在上面。
>如果多个条件表达式之间有包含的关系,通常情况下,需要将范围小的声明在范围大的上面,否则范围小的将没有机会执行。
比如 大于0的执行代码1,大于5的执行代码2。
if(a>0){
代码1
}else if(a>5){
代码2
}
如果按照这样的写法,那么代码2永远都不会执行。因为大于0的范围显然比大于5的范围要大
应该更正为
if(a>5){
代码2
}else if(a>0){
代码1
}
- if-else结构是可以互相嵌套的
- 如果if结构中的执行语句只有一行时,对应的{}也可以省略的,但是不建议这样做。
- if优化
由于if结构可以嵌套。会有两种方式写同样的问题,嵌套和不嵌套
问题:当条件1和条件2都为true时执行代码1。
方式1嵌套:
if(条件1){
if(条件2){
代码1
}
}else if(条件3){
代码2
}
方式2不嵌套:
if(条件1 && 条件2){
代码1
} else if(条件3){
代码2
}
优先使用方式1,因为方式1,当条件1,为真,无论条件2是否为真,都不会走else if 去判断条件3,而方式2,当条件1为真,还需要看条件2是否为真,如果条件2为假,则仍然会走else if 判断条件3。
方式1的流程图
方式2的流程图
- switch语句
写法
switch(表达式){
case 值1:
代码1
break;
case 值2:
代码2
break;
case 值n:
代码n
break;
default:
不满足所有才执行的
break;
}
对switch的说明
根据switch表达式中的值,依次匹配各个case中的常量。一旦匹配成功,则进入相应的case结构中,调用其执行语句,当调用完执行完语句以后,则仍然继续向下执行其他case结构中的执行语句,直到遇到break关键字结束switch-case结构
break:可以使用在switch-case中,表示一旦执行到该关键字,就跳出switch结构
switch的表达式只能是 byte、short、char 、int、枚举类、String类 其中一种
case 只能声明常量不能声明范围
break可选
default 相当于else,且可选,位置灵活
如果switch-case结构中的多个case的执行语句相同,则可以考虑进行合并
循环结构
循环结构四要素
1.初始化条件
2.循环条件 ---> boolean 类型
3.循环体
4.迭代条件
当循环条件为false时,循环就结束了
- while语句的写法
1.初始化条件
while(2.循环条件){
3.循环体
4.迭代条件
}
执行顺序:1->2->3->4->2->3->4... ...直到循环条件为false,结束循环。
- do-while语句的写法
1,初始化条件
do{
3.循环体
4.迭代条件
}while(2.循环条件);
执行顺序:1->3->4->2 ->3->4->2... ... 直到循环条件为false,结束循环
注意点
- do -while 是先执行循环体和迭代条件。也就是说,无论循环条件是否为true,do-while循环至少循环一次。
- while(); 后面必须加分号
- for循环的写法
for(1.初始化条件;2.循环条件;4.迭代条件){
3.循环体
}
执行顺序:1->2->3->4 ->2->3->4... ... 直到循环条件为false,结束循环
循环区别
经常使用while 和for循环
for 和while的初始化条件部分的作用域不同
for 和while执行多少次由循环条件决定,而do-while至少运行一次,因为它是先运行再判断。
对于已知循环次数,建议使用for循环。
无限循环即死循环写法
while(true) 当条件永远为真,就是死循环
for(;;) 这样写法就是死循环。
假设
boolean flag = true;
while(flag) 和for(;;) 这有区别吗?
有的兄弟,有的。
不同之处就是,while循环每次都要判断flag是否为true,而for(;;)不用判断
如果while的循环条件直接写的是(true),就不用判断。
额,好像在说废话......
循环嵌套
循环也可以嵌套,将一个循环结构A声明在另一个循环结构B的循环体中,就构成了循环嵌套
内层循环:循环结构A
外层循环:循环结构B
内层循环一遍,外层循环一次。就类似,天上一天,底下一年。
假设外层循环执行了m次,内层循环执行了n次,那一共执行了m*n次 时间复杂度就是O(m*n)
如果循环案例是M行N列的话
也可以抽象理解成外层循环控制行数,内层循环控制列数。
结束循环语句
关键字 | break | continue |
使用范围 | switch和循环 | 循环结构 |
不同点 | 结束循环 | 结束 当前循环,进入下一次循环 |
相同点 | 关键字之后不能声明执行语句 |
Scanner类的使用
Scanner类用于获取键盘输入
步骤:
- 导包 import java.util.Scanner
- 实例化类 Scanner input = new Scanner(System.in);
调用Scanner类的方法,来获取指定类型的值。如果输入的数据类型与要求的类型不匹配会报InputMisMatchException 异常。
常用的获取输入方法
类型 | 方法名 |
int | nextInt() |
double | nextDouble() |
String | next()\nextLine() |
基础使用
Scanner input = new Scanner(System.in)
System.out.println("请输入您的年龄:")
int age = input.nextInt();
System.out.println(age);
数组
什么是数组
数组(Array) 是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,通过索引对这些数据进行统一管理。
数组的特点
1.有序排列
2.数组属于引用类型的变量,数组的数据可以是基本数据类型,也可以是引用数据类型。
3.创建数组对象会在内存中开辟出一整块连续空间
4.数组的长度一旦确定,就不可以修改
5.Java8及以前String类,本质上是char类型的数组,Java9之后更改为byte类型数组
数组的分类
一维数组
声明和初始化方式
动态初始化:
类型[] 数组名 = new 类型[数组长度]; 长度一旦确定,就不可以修改。
int[] arr = new int[5];
静态初始化:
类型[] 数组名 = new 类型[]{值1,值2,......}
int arr = new int[]{1,2,3}; 可以简写成int[] arr = {1,2,3};
通过索引给元素赋值,第一个元素下标是0,最后一个元素下标是数组的长度-1。 数组长度则可以直接使用 数组名.length的方式获取。
arr[0] =1
arr[1]=2;
...
arr[arr.length-1]=9
二维数组
因为数组存放的元素是唯一的,且可以是任何类型,所以也可以存放数组,则称整个数组为二维数组,当然也可以有三维、四维等等。
声明和初始化
动态初始化方式:
int[][] arr = new int[3][2] 动态初始化方式1
int[][] arr =new int [3][]; 动态初始化方式2
当数组内元素个数不一致时,建议使用动态初始化方式2
静态初始化方式:
int[][] arr = new int[][]{{1,2},{1,2}};
也可以简写成
int[][] arr= {{1,2},{1,2}};
获取值
arr[x][y]
遍历数组
一维数组使用for循环遍历
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
二维数组使用for嵌套循环
for(int i=0;i<arr.length;i++){
for(int j =0;j<arr[i].length;j++){
System.out.println(arr[i][j])
}}
数组的默认值
一维数组元素的默认初始化值
int类型数组,默认值是0
浮点型默认值是0.0
char数组默认是0或'\u0000' 而不是'0'
boolean数组默认是false
引用类型数组默认是null。
对于int[][] arr = new int[4][3]这种初始化方式
二维数组外层的初始值是地址值。内层的初始值和一维数组一样。
对于int[][] arr = new int[4][]这种初始化方式,外层初始值为null,
Arrays工具类的使用
Arrays工具类定义在java.util包下
Arrays提供了很多操作数组的方法
常用方法
boolean equals(arr1,arr2): 判断两个数组是否相等
int[] arr1 = new int[]{1,2};
int[] arr2 = new int[]{1,2};
boolean isEquals = Arrays.equals(arr1,arr2)
System.out.println(isEquals)
//true
String toString(arr):输出数组信息
int[] arr = new int[]{1,2,34};
System.out.print(arr)// 输出的结果为地址值
System.out.println(Arrays.toString(arr));
//输出结果 [1,2,34]
void fill(arr,a):将指定的a填充到数组中
int[] arr1 = new int[]{1,2,3,4}
Arrays.fill(arr1,5);
System.out.println(Arrays.toString(arr1));
//结果为 [5,5,5,5];
void sort(int[] arr):对数组进行排序
int[] arr1 = new int[]{11,32,3,4};
Arrays.sort(arr1);
System.out.print(Arrays.toString(arr1));
int binarySearch(arr,a):从数组中查找指定的a
int[] arr = new int[]{-123,213,23,5,23,43,5523};
int index = Arrays.binarySearch(arr,5);
System.out.println(index>=0 ? index:"未找到");
//该方法为二分搜索法,如果要查找的a,数值有多个,无法保证找到的是哪一个
数组的优缺点
好处:查询方便,改也方便
坏处:因为数组长度一旦确定,就不可以进行修改,所以无法完成增删
数组的一些小案例
杨辉三角
杨辉三角
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
System.out.print("请输入杨辉三角的行数");
int row = input.nextInt();//行数
int[][] yanghui = new int[row][row];//n行n列数组
for (int i = 0; i < row; i++){//行
for(int j = 0;j<= i;j++){//列
if (j==0 || j==i){
yanghui[i][j]=1;
}else{
yanghui[i][j]=yanghui[i-1][j-1]+yanghui[i-1][j];
}
System.out.print(yanghui[i][j]+" ");
}
System.out.println();
}
回形数
回形数
1 2 3 4 5 6 7 8
28 29 30 31 32 33 34 9
27 48 49 50 51 52 35 10
26 47 60 61 62 53 36 11
25 46 59 64 63 54 37 12
24 45 58 57 56 55 38 13
23 44 43 42 41 40 39 14
22 21 20 19 18 17 16 15
Scanner scanner = new Scanner(System.in);
System.out.println("请输入回型数的行列数:");
int n = scanner.nextInt();
int[][] arr = new int[n][n];
int count = 0;//值
int maxX = n - 1;//x轴的最大下标
int maxY = n - 1;//y轴的最大下标
int minX = 0;//x轴的最小下标
int minY = 0;//y轴的最小下标
while(minX <= maxX){
for(int x = minX; x <= maxX; x++){
arr[minY][x] = ++ count;
}
minY ++;
for(int y = minY; y <= maxY; y++){
arr[y][maxX] = ++ count;
}
maxX --;
for(int x = maxX; x >= minX; x--){
arr[maxY][x] = ++ count;
}
maxY --;
for(int y = maxY; y >= minY; y--){
arr[y][minX] = ++ count;
}
minX ++;
}
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
if(i==0){
System.out.print(arr[i][j] + " ");
continue;
}
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
最大/最小值
public int Max(int[] arr){
int max = arr[0];
for (int i = 1; i <=arr.length; i++) {
if(max<arr[i]){
max=arr[i];
}
}
return max;
}
public int Min(int[] arr){
int min = arr[0];
for (int i = 1; i <=arr.length; i++) {
if(min>arr[i]){
min=arr[i];
}
}
return min;
}
随机数存到数组中,且不能重复
int[] arr = new int[6];
for(int i= 0;i<6;i++){
arr[i]=(int)Math.random()*30+1;
for (int j = 0; j < i; j++) {
if(arr[i]==arr[j]){
i--;
break;
}
}
}
反转数组
//方法一:
for(int i = 0;i < arr.length / 2;i++){
int temp = arr[i];
arr[i] = arr[arr.length - i -1];
arr[arr.length - i -1] = temp;
}
//方法2:
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= new int[]{23,5,234,53,236,23};
for(int i = 0; i<arr.length-1;i++){
for(int j = 0;j<arr.length-i-1;j++){
if(arr[j]>arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] =temp;
}
}
}
本人是Java初学者,水平有限,本文章中如果有不对的地方,麻烦您能指出来。向您表示感谢。