整理自 韩顺平零基础30天学Java
程序控制结构
循环控制
do-while循环
循环变量初始化;
do{
循环体;
循环变量迭代;
}while(循环条件);
先执行再判断,即无论符不符合,一定会执行一次。
//要账例题
Scanner scanner = new Scanner(System.in);
char ans = ' '; //先设置一个全局变量,while才能知道ans的存在。
do {
System.out.println("da");
System.out.println("还钱吗?y/n");
ans = scanner.next().charAt(0);
}while(ans == 'n');
System.out.println("以后早点还");
多重循环控制
- 嵌套循环,最好不要超过3层,否则可读性差。
- 嵌套循环中,内层循环结束后,跳出内层循环,才可结束外层的当次循环。
- 设外层循环次数为m次,内层为n次,则内层循环需要执行m*n次。
// 打印金字塔
Scanner scanner = new Scanner(System.in);
int totalLevel = scanner.nextInt();
for (int i = 1;i <= totalLevel;i++){
for (int k = 1;k <= totalLevel - i; k++){
System.out.print(" ");
}
for (int j = 1;j <= 2 * i - 1;j++){
if(j == 1 || j == 2 * i - 1 || i == totalLevel){
System.out.print("*");
}else{
System.out.print(" ");
}
}
System.out.println();
}
跳转控制
break
(int)(Math.random() * 100) + 1:取0-100的随机数
循环次数不确定时,使用break。当满足条件时,break跳出循环。
细节
- break语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的是哪一层语句块。
- 标签的基本使用
- break语句可以指定退出哪层。
- label1是标签,名字由程序员指定。(不要违反命名规则)
- break后指定到哪个label就退出哪个循环。
- 在实际的开发中,尽量不要使用标签。
- 如果没有指定break,默认退出最近的循环体。
//登录验证,3次机会,提示还有几次机会
Scanner scanner = new Scanner(System.in);
String name = "";
String pass = "";
for (int i = 1;i <= 3;i++){
System.out.println("请输入用户名:");
name = scanner.next();
System.out.println("请输入密码:");
pass = scanner.next();
// if (name == "兜瑞米" && pass == "666"){
//字符串的内容比较方法:equals
// 推荐写成"666".equals(pass),避免空字符
if (name.equals("兜瑞米") && "666".equals(pass)){
System.out.println("登录成功");
break;
}else {
int j = 0;
j = 3 - i;
System.out.println("信息错误!还有"+j+"次机会。");
}
}
continue
结束本次循环,继续执行下一次循环。
在多层嵌套的循环语句体中,可以通过标签指明要跳过的是哪一层循环。
return
return使用在方法,表示跳出所在的方法。
如果return写在main方法,退出程序。
数组
存放多个同一类型的数据。数组也是一种数据类型,是引用类型。
//double[] 表示 是double类型的数组,数组名 hens
//数组的值/元素 {3,5,1,3.4,2,50}
double[] hens = {3,5,1,3.4,2,50};
//遍历数组得到数组的所有元素的和
for (int i = 0;i < 6;i++){
//通过hens[下标] 来访问数组的元素
//下标从0开始标号
System.out.println("第" + (i+1) + "个元素的值是" + hens[i]);
}
使用
动态初始化
使用方法1
数组的定义:int a[] = new int[5]; / int[] a = new int[5];
数组的引用:a[2] //获得a数组的第3个数
使用方法2
声明数组:int[] a; / int a[];
创建数组:a=new int[10]; //分配内存空间,可以存放数据
静态初始化:知道数组有多少元素,具体值
int a[]={2,5,6,7,8,9,10}
相当于:int a[]=new int[7]; a[0]=2;a[1]=5;...a[6]=10;
注意
- 数组中的元素可以是任何数据类型,包括基本类型和引用类型,但是不能混用。
如:String[] arr = {"北京","jack","milan"}; - 数组创建后,如果没有赋值,有默认值。
int、short、byte、long:0;float、double:0.0;
char:\u0000;boolean:false;String:null - 数组属引用类型,数组型数据是对象(object)。
习题
// 数组打印出A-Z
char[] arr1 = new char[26];
for (int i = 0;i < arr1.length;i++){
arr1[i] = (char) ('A' + i); //'A'+i是int,需要强制转换
}
for (int i = 0;i < arr1.length;i++){
System.out.print(arr1[i]+" ");
}
赋值机制
- 基本数据类型赋值,这个值就是具体的数据,而且相互不影响。(值拷贝)
int n1 = 2; int n2 = n1; - 数组在默认情况下是引用传递,赋的值是地址。(地址拷贝)
int[] arr1 = {1,2,3}; int[] arr2 = arr1; //arr2变化会影响到arr1
数组拷贝:数据空间相互独立
int[] arr1 = {10,20,30};
//创建一个新的数组arr2,开辟新的数据空间
int[] arr2 = new int[arr1.length];
//遍历arr1,把每个元素拷贝到arr2对应的位置
for(int i = 0;i < arr1.length;i++){
arr2[i] = arr1[i];
}
数组反转
- 在原数组的基础上,两两交换。
- 逆序赋值:新建一个数组,逆序遍历赋值后,地址拷贝给原数组。
数组添加
不能直接赋值,地址划分时已经固定了数组的大小。
定义新数组,遍历原数组进行值拷贝后,添加新元素,再进行地址拷贝。
数组缩减
int[] arr1 = {1,2,3,4,5};
Scanner scanner = new Scanner(System.in);
while (true){
System.out.println("是否缩减数组? y/n");
char ans = scanner.next().charAt(0);
if(ans == 'y'){
if(arr1.length-1 >= 1){
int[] arr2 = new int[arr1.length - 1];
for (int i = 0;i < arr1.length-1;i++){
arr2[i] = arr1[i];
System.out.print(arr2[i]);
}
System.out.println();
arr1 = arr2;
}else {
System.out.println("仅剩下一个数字,无法进行缩减");
break;
}
}
}
排序
分类
- 内部排序:将需要处理的所有数据都加载到内部存储器中进行排序。
交换式排序法、选择式排序法、插入式排序法 - 外部排序:数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。
合并排序法、直接合并排序法
冒泡排序法:从小到大
会进行多次比较,交换时需要一个临时变量temp。
查找
- 顺序查找:逐一比较。
- 二分查找:《数据结构》有提到,就是对半切。比如随机猜数字,用二分法可以很快猜对。
编程思想:index索引可以省掉很多代码,如果index为初始值,则说明没有进入判断成功的语句,即无符合的条件。