JavaBasis
0、控制结构补充
1) break、continue 关键字
- break 结束当前循环
- continue 结束本次循环
示例代码 :
//若去掉 break、continue 关键字,两条语句输出结果为 : 1 ~ 10
// print :打印时不换行显示; println :打印时换行显示
//使用 break 关键字
for(int i = 1; i <= 10; i++){
if (i == 5){ break; }
System.out.print(i + " ");
}
System.out.println();
for(int i = 1; i <= 10; i++){
if (i == 5) { continue; }
System.out.print(i + " ");
}
结果 :
当第一个 for 循环 i = 5 时, if 判断语句生效,执行到 break 后结束当前 for 循环;
当第二个 for 循环 i == 5 时, if 判断语句生效,执行到 continue 后,结束本次循环,本次 if 后面的语句都不会执行,重新开始下一次循环;
// 第一次结果
1 2 3 4
// 第二次结果
1 2 3 4 6 7 8 9 10
2) 带标识符的循环结构
循环结构可以通过在其前面添加 标识符 : 这种形式,配合 break 和 continue 一起使用,可以达到不同的效果
a : for ( ; ;){
for (int i = 1; i <= 10; i++) {
if (i == 5) break a;
System.out.print(i + " ");
}
}
结果 :
外层循环为死循环,内层循环若去掉 break 关键字则为打印 1 ~ 10 的循环,嵌套就是一个一直重复打印 1 ~ 10 的死循环;
若在外层循环前面添加一个标识符 a : ,在 if 判断语句后添加 break a; ,则当内层循环 i == 5 时,if 判断语句生效,执行 break a; ,直接结束外层循环,避免了死循环的发生
// 运行结果
1 2 3 4
1、数组(一)
1. 概述 :
用以存储多个相同数据类型元素的容器;
数组支持所有数据类型创建
2. 格式 :
1) 格式一 :定义时给定数组长度
① 数据类型[] 数组名 = new 数据类型[元素个数 / 数组长度];
eg :int[] arr = new int[3]; //给定数组长度为 3
注意 :若定义数组时为指定数组元素值,则数组元素为定义数组的数据类型的初始值,元素个数等于给定数组长度的值
格式一数组定义也可以分为声明和初始化两个过程
② 数据类型[] 数组名;
数组名 = new 数据类型[数组长度];
eg : int[] arr;
arr = new int[3];
2) 格式二 :定义时直接给值
① 数据类型[] 数组名 = new 数据类型[]{元素值1 , 元素值2 , …};
eg : int[] arr = new int[]{1, 2, 3}; //指定数组元素值就确定了数组长度
格式二数组定义也可以分为声明和初始化两个过程
② 数据类型[] 数组名;
数组名 = new 数据类型[]{元素值1 , 元素值2 , …};
eg : int[] arr;
arr = new int[]{1 , 2 , 3};
3) 格式三 :底层动态开辟内存空间
数据类型[] 数组名 = {元素值1 , 元素值2 , …}; //指定素组元素值就确定了数组长度
eg : int[] arr = {1 , 2 , 3};
注意 :格式三不能分为声明和初始化两个阶段;若按照格式三进行定义数组,底层会动态开辟内存空间进行存储数据;若将声明和初始化分开,因为初始化时没有通过 new ,底层不会开辟内存空间,所以无法存储数据,编译不通过
3. 解析数组地址值
若直接使用输出语句打印数组,则不会输出数组内元素信息,而是输出数组的地址值
比如 : [ I @15db9742
解析 :
[ 此位代表对象的类型,这里为数组类型
I 此位代表对象身上的元素类型,这里代表数组类型为 int 类型
@ 代表后面是地址值
15db9742 代表哈希码值的十六进制表现形式,不同数组的哈希码值不同
[ I @15db9742 代表数组的地址值,即存储在内存的位置
4. 数组的遍历
数组定义后,java 会自动给数组元素进行编号(下标从 0 开始),根据数组名和数组下标共同作用,就能确定唯一数组元素值;因为下标从 0 开始,所以数组中元素所在位置的最大下标为 :数组长度 - 1
-----格式 :数组名[下标]
// 利用 for 循环实现数组遍历
int[] arr = new int[]{2,3,4,1};
for (int i = 0; i < arr.length; i++) {// arr.length 获取数组长度
System.out.print(arr[i] + " ");
}
结果 :
2 3 4 1
当 i == 0 时,arr[ i ] = arr[ 0 ] 代表数组中的下标为 0 的元素,即第一个元素 2,然后 i++ 依次获取,直到 i < arr.length 不满足时结束循环,arr.length 为数组长度 4
注意 :若上述获取元素值得过程中,i 的下标大于或等于数组长度时,即运行时会报 数组下标越界异常
java.lang.ArrayIndexOutOfBoundsException: 4
5. 数组的最值
若在特殊情况下,需要获取数组中存入元素值的最大和最小值时,可以结合使用循环结构和 if 判断结构,得到想要的结果
获取最大值
int[] arr = {2,3,1,5,9};
int max = arr[0]; //把数组的第一元素当做参照物
for(int i = 1; i < arr.length; i++){
if(arr[i] > max){ //把参照物和数组中元素依次进行比较
max = arr[i]; //若当前元素大于参照物,则设置最大值为当前元素
}
}
System.out.println(max); //此时获取的 max 即为数组中最大值
结果 :
9
获取最小值只需将上述获取最大值中 if 判断语句改为小于即可
6. 数组的查找
查找 :给定一个查找数,返回第一次在数组中出现的下标
int[] arr = {5,3,1,4,8};
int num = 4; //设置查找数
for(int i = 0; i < arr.length; i++){
if(n == arr[i]){ //判断数组元素是否和查找数相等
System.out.println(i); //输出的 i 即为查找数所在数组中的位置
break; //若找到查找数后,就可以结束循环
}
}
上述查找方法存在缺陷,比如 :如果查找数未在数组中出现,打印的结果却为 0;而且如果数组数据较多时,上述查找方法效率也比较低
二分查找 :只能针对有序的数组,每次求取其不同范围的中间值和查找数进行比较,若两数相等表示已找到查找数,输出下标即可;
若查找数小于中间值,则只在中间值的左半边进行查找,而舍弃右半部分,或者若查找数大于中间值,则只在中间值得右半边进行查找,而舍弃左半边;重新计算左半边 或 右半边的中间值,重复上述步骤即可
//二分查找
int[] arr = {3,8,4,7,5,7,1,1,9,9};
//利用 Arrays 类中的 sort() 方法可以对无序的数组进行从小到大排序
Arrays.sort(arr);
//利用 Arrays 类中的 toString() 方法可以将数组内容拼接为字符串类型
System.out.println(Arrays.toString(arr));
//定义查找数
int num = 9;
//定义三个下标
//左边开始下标
int min = 0;
//右边结束下标
int max = arr.length - 1;
//计算中间下标 : >> 右移一位,即代表整除 2
int mid = (min + max) >> 1;
while(arr[mid] != num){ //循环终止条件为中间值等于查找数,即为找到
if (min > max){ //若左边下标大于右边下标时表示查找数不存在数组中
System.out.println("查无此数");
return;
}
//若查找数大于中间值时,舍弃左半边即将左边下标移动到 mid 的下一位
if (num > arr[mid]){
min = mid + 1;
}
//若查找数小于中间值时,舍弃右半边即将右边下标移动到 mid 的前一位
if (num < arr[mid]){
max = mid - 1;
}
//重新计算中间值 mid
mid = (min + max) >> 1;
}
//若查找数有重复,则查看下标为 (mid - 1) 的元素是否也为查找数
for (int i = mid - 1; i >= 0; i--) {
if (arr[mid] == arr[i])
mid = i;
else
break;
}
//输出的值即为查找数第一次出现的下标
System.out.println("查找数 "+ num +" 所在下标 : " + mid);
结果 :
[1, 1, 3, 4, 5, 7, 7, 8, 9, 9]
查找数 9 所在下标 :8