流程控制
if-else
if( 条件表达式1 ){
执行代码块1
}else if( 条件表达式2 ){
执行代码块2
}else{
执行代码块3
}
- 条件表达式必须是布尔表达式,或者是布尔变量;
- 执行代码块只有一条执行语句时,{ }可以省略;
- if-else是“多选一”结构,因此else是可选的;
- 根据条件是“互斥”还是“包含”关系,各部分的条件表达式和执行代码块的顺序存在要求;
如果条件是“互斥”的,那没有顺序要求;
如果条件是“包含”的,那子级在上、父级在下;
switch-case
switch( 表达式 ){
case 常量1:
执行语句1;
break;
case 常量2:
执行语句2;
break;
case 常量3:
执行语句3;
break;
default:
执行语句1;
break;
}
- switch语句中,表达式的值必须是以下几种类型之一:
byte,short,char,int,枚举,String - case后面的常量必须是确定的值,不能是变量名或者表达式;
- break用来执行完一个case分支后跳出switch语句块,如果没有break,程序会自动执行到switch的结尾;
- default是可选的,位置也是灵活的,当没有匹配的case时,执行default后面的语句;
- 不同的case可以执行同一个语句,因此可以将case进行合并,比如:
switch(month){
case 3:
case 4:
case 5:
System.out.println("Spring");
break;
case 6:
case 7:
case 8:
System.out.println("Summer");
break;
case 9:
case 10:
case 11:
System.out.println("Autumn");
break;
case 12:
case 1:
case 2:
System.out.println("Winter");
break;
}
for
for ( 初始化部分 ; 循环条件部分 ; 迭代部分 ){
循环体
}
- for循环条件部分为boolean表达式,当值为false时,退出循环;
- 初始化部分可以声明多个变量,但必须是同一个类型,用逗号分隔;
- 迭代部分也可以有多个变量更新,用逗号分隔;
- 无限循环:
for( , , ){
循环体
} // 表达式中并没有语句,会导致无限循环下去
while/do-while
初始化部分
while( 循环条件部分 ){
循环体部分
迭代部分
}
初始化部分
do{
循环体部分
迭代部分
}while( 循环条件部分 )
- 两者的区别在于do-while在循环之前至少会执行一次循环体;
- 通过控制while的循环条件,可以造成无限循环:
while( true ){
循环体
}
嵌套
一个输出9*9乘法表的例子:
int num;
for(int i = 1; i <= 9; i++){
for(int j = 1; j <= i; j++){
num = i * j;
System.out.print(j + "*" + i + "=" + num + '\t');
}
System.out.print('\n');
}
break/continue
- 使用{ }定义的一段代码被称作代码块
- break可以终止并跳出当前所处代码块的执行;
- continue则可以跳过当前所处代码块的循环,直接进行下一次循环;
- break、continue之后不能有其它的语句,因为程序永远不会执行在其之后的语句;
数组
数组概述
- 数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
- 创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址。
- 数组的长度一旦确定,就不能修改。
一维数组
声明方式
// 数组声明;
int a[];
int[] a1;
//int a[5]; // 非法,声明数组时不能指定其长度
double b[];
String s[];
String[] s1;
// 理论上,type var[] 和 type[] var这两种方式没有什么区别;
初始化
java中使用new关键字来创建数组;
动态初始化:
int arr[] = new int[3];
arr[0] = 0;
arr[1] = 1;
arr[2] = 2;
String[] names;
names = new String[3];
names[0] = "kana";
names[1] = "omew";
names[2] = "yuki";
静态初始化:
int arr1[] = new int[]{0,1,2};
int arr2[] = {1,2,3};
String[] charas = {"甲","乙","丙"};
数组的引用
- 定义、并用运算符new为数组分配空间之后,才可以引用数组中的每个元素;
- 采用数组下标来引用数组元素,可以是整数常量或者整型表达式,数组的下标从0开始;
- 每个数组都有一个属性length指明它的长度,例如:a.length 指明数组a的长度;
- 数组一旦初始化,长度是不可变的;
for(int i = 0; i<names.length; i++ ){
System.out.println(names[i]);
}
数组元素默认初始化值
数组是引用类型,它的元素相当于类的成员变量,因此数组一经分配空间,其中的每个元素也被按照成员变量同样的方式被隐式初始化。
![](https://img.haomeiwen.com/i26145946/cd5b625ab83dbd69.png)
内存解析图(例)
![](https://img.haomeiwen.com/i26145946/a96b3640606b2dcb.png)
多维数组
数组中的数组:对于二维数组的理解,可以看成是一维数组array1又作为另一个一维数组array2的元素而存在。其实,从数组底层的运行机制来看,并没有多维数组。
初始化
动态初始化:
// 动态初始化,格式1
int[][] arr = new int[3][2];
int arr1[][] = new int[3][2];
// 动态初始化,格式2
int[][] arr2 =new int[3][];
arr2[0] = new int[1];
arr2[1] = new int[2];
arr2[2] = new int[3];
// int[][] arr3 = new int[][3]; // 非法
静态初始化:
// 静态初始化
int[][] arr4 = new int[][]{{2,3},{4,5,6},{7,8,9}};
java中的数组不一定都是规则的矩阵形式
多维数组的使用
for(int i = 0; i < arr4.length; i++){
for(int j =0; j < arr4[i].length; j++)
System.out.print(arr4[i][j] + " ");
System.out.print('\n');
}
本质上还是对数组下标的引用,与一维数组不同的是多维数组的循环为嵌套;
数组声明方式总结
一维数组:int x[ ] 或者 int[ ] x;
二维数组:int y[ ][ ] 或者 int[ ][ ] y 或者 int[ ] y[ ];
二维数组内存解析图(例)
![](https://img.haomeiwen.com/i26145946/fd750c2b11665133.png)
数组涉及的常见算法
复制数组
int[] array1, array2;
array1 = new int[] { 2, 3, 5, 7, 11, 13, 17, 19 };
array2 = array1;
这样是不行的,表面上看数组array2的元素确实跟数组array1的元素一样,但这其实是复制了array1引用地址的结果,两个数组在内存中指向的是一个空间。这就导致了:如果你对数组array2的元素进行修改,同样也会影响到array1的元素。
![](https://img.haomeiwen.com/i26145946/d789fb830fcfc80e.png)
正确的方法是,采用循环的方式对array2中的元素逐一进行复制操作:
//复制array1数组给array2
array2 = new int[array1.length];
for(int i = 0;i < array2.length;i++){
array2[i] = array1[i];
}
![](https://img.haomeiwen.com/i26145946/a32f096ba1ac3765.png)
二分查找
![](https://img.haomeiwen.com/i26145946/f963dded6cd1002e.png)
这里需要注意的是:循环停止的条件
理论上说,无论head和end的值怎么改变,都不可能出现head > end 的情况,因为这跟数组的基本结构是矛盾的;同时在每一次二分查找后,都会执行 end = middle - 1 或者 head = middle + 1 ,来确保程序正常运行。
冒泡排序
int temp;
for(int j = 1; j < arr.length; j++ ){ // 外层循环是冒泡操作的次数
for(int i = 0; i < arr.length - j; i++){ // 内存循环是相邻两个元素做比较的次数
if(arr[i] > arr[i + 1]){
temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
}
冒泡排序的本质是比较相邻的两个元素,如果第一个比第二个大,就对其进行交换(升序);
对每一组相邻的元素做相同的操作,从:
a[1] 和 a[2]
a[2] 和 a[3]
... ...
a[n-1] 和 a[n]
完成以上这个比较流程,最后的a[n]一定是最大的数,到此为止,执行了一次冒泡操作;
每执行一次冒泡操作后,除了最后一个元素,针对剩下的元素重复以上操作,直到没有任何一对数字需要比较为止。
Arrays工具类
Arrays类即为操作数组的工具类,包含了用来操作数组(比如排序和搜索)的各种方法;
使用时,必须在声明import java.util.Arrays;
![](https://img.haomeiwen.com/i26145946/26c95e5f023b396d.png)
表格中的数据类型为执行了此工具类方法后返回的值类型:
// Arrays工具类
int[] arr1 = new int[]{1,3,5,7,9};
int[] arr2 = new int[]{1,3,5,7,9};
System.out.println(Arrays.equals(arr1,arr2)); // true
System.out.println(Arrays.toString(arr1)); // [1, 3, 5, 7, 9]
Arrays.fill(arr2, 0);
System.out.println(Arrays.toString(arr2)); // [0, 0, 0, 0, 0]
int[] arr3 = new int[]{-12,-90,5,2,88,60,-17,-44,46,80,32,11,7};
Arrays.sort(arr3);
System.out.println(Arrays.toString(arr3)); // [-90, -44, -17, -12, 2, 5, 7, 11, 32, 46, 60, 80, 88]
System.out.println(Arrays.binarySearch(arr3, 11)); // 7
System.out.println(Arrays.binarySearch(arr3, 10)); // -8 随机返回一个负数值
数组使用的常见异常
此异常编译时不会报错,只有执行编译后的程序才会出现提示信息:
![](https://img.haomeiwen.com/i26145946/bec4013b385f0565.png)
网友评论