java基础03
流程控制
1、用户交互:Scanner
-
之前我们学的基本语法并没有实现程序和人的交互,Java给我们提供了一个工具类,可以获取用户的输入java.util.Scanner是Java5的新特征,我们通过Scanner类来获取用户的输入。
-
基本语法
Scanner s = new Scnner(system in);
-
通过Scanner类的 next()与 nextLine()方法获取用户的字符串,读取前一般用hasNext()与hasNextLine()判断是否还有输入的数据。
public class Scanner { public static void main(String[] args) { //创建一个扫描器对象,用于接受键盘数据 java.util.Scanner scanner = new java.util.Scanner(System.in); System.out.println("使用next方式接收:"); //判断用户有没有输入字符串 if(scanner.hasNext()){ //使用next方式接收 String str = scanner.next(); System.out.println("输入的内容为:"+str); } //凡是属于Io流的类如果不关闭会一直占用资源,要养成好习惯用完就关掉 scanner.close();
public class Scanner { public static void main(String[] args) { //创建一个扫描器对象,用于接受键盘数据 java.util.Scanner scanner = new java.util.Scanner(System.in); System.out.println("使用nextLine方式接收:"); //判断用户有没有输入字符串 if (scanner.hasNextLine()) { //使用nextLine方式接收 String str = scanner.nextLine(); System.out.println("输入的内容为:" + str); } //凡是属于Io流的类如果不关闭会一直占用资源,要养成好习惯用完就关掉 scanner.close(); } }
-
scanner.next()这个方法会忽略掉输入有效字符前面的空格,输入内容中遇到空格后,从空格开始往后的内容就都不作为扫描结果了。
-
scanner.nextLine()方法不会忽略空格,扫描的结果是回车之前的所有输入内容。
2、顺序结构
-
任何一个算法都离不开的一种基本算法结构。
3、选择结构
-
if单选择结构
-
if双选择结构
-
if多选择结构
-
嵌套的if结构
-
switch多选择结构
char grade='C';
switch (grade){
case 'A':
System.out.println("优秀");
break;
case 'B':
System.out.println("良好");
break;
case 'C':
System.out.println("及格");
break;
case 'D':
System.out.println("再接再厉");
break;
default:
System.out.println("未知等级");
}
从Java SE 7 开始,支持字符串String类型
String str="world";
switch (str){
case "hello":
System.out.println("你好");
break;
case "world":
System.out.println("世界");
break;
default:
System.out.println("java");
break;
}
- 反编译
- 打开project structure,找到Project compiler output中的路径并打开
- 将.class文件复制到项目目录底下,再次用idea查看
- 由此可见:switch中字符串比较的本质还是数字比较,每一个字符串都有其特定的hash值
4、循环结构
while循环
-
while是最基本的循环,它的结构为:
while(布尔表达式){ // 循环 }
-
只要布尔表达式一直为true,就会一直执行下去。
-
大多数情况下会让循环停止下来,我们需要一个让表达式失效的方式来结束循环。
-
少部分情况需要循环一直执行,如服务器请求响应监听等。
-
循环条件一直为true就是造成死循环,正常业务编程中要尽量避免死循环。否则会影响程序性能或者造成程序卡死崩溃。
-
计算1+2+3+…+100=?
int i = 0; int sum = 0; while(i<100){ i++; sum += i; } System.out.println(sum);
dowhile循环
-
对于while语句而言,如果不满足条件,则不能进入循环。
-
while是先判断条件然后再执行。
-
do…while先执行一次后判断是否满足条件。
do{ //代码语句 }while(布尔表达式);
// 计算 1+2+...+100 int i = 0; int sum = 0; do { i++; sum += i; }while(i<100); System.out.println(sum);
for循环
-
for循环的循环执行次数在执行前就确定的。
for(初始化;布尔表达式;更新){ // 代码语句 }
-
for循环语句是支持迭代的一种通用结构,最高效、最灵活的循环结构。
-
打印九九乘法表:
package learn; public class Table99 { public static void main(String[] args) { for (int i=1;i<=9;i++){ for (int j=1;j<=i;j++){ System.out.print(i+"*"+j+"="+i*j+"\t"); } System.out.println(); } } }
-
增强for循环
-
Java5引入了一种主要用壬数组或集合的增强型for循环。
-
语法格式:
for(声明语句:表达式){ // 代码句子 }
-
声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。
-
表达式:表达式是要访问的数组名,或者是返回值为数组的方法。
public class Main { public static void main(String[] args) { int[] numbers = {1, 2, 3, 4, 5, 6, 7}; //遍历数组元素 for (int x : numbers) { System.out.println(x); } } }
-
break、continue、goto
-
break在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句。(break语句也在switch语句中使用)
-
continue语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。
-
goto关键字 (不用掌握,知道就好)
-
goto关键字很早就在程序设计语言中出现。尽管goto仍是Java的一个保留字,但并未在语言中得到正式使用;Java没有goto。然而,在break和continue这两个关键字的身上,我们仍然能看出一些goto的影子—带标签的break和continue。
-
“标签”是指后面跟一个冒号的标识符,例如: label:
-
对Java来说唯一用到标签的地方是在循环语句之前。而在循环之前设置标签的唯一理由是:我们希望在其中嵌套另一个循环,由于break和continue关键字通常只中断当前循环,但若随同标签使用,它们就会中断到存在标签的地方。
public class Main { public static void main(String[] args) { // 打印101-150的质数 outer:for (int i = 101; i <= 150; i++) { for (int j = 2; j < i / 2; j++) { if (i % j == 0) { continue outer; } } System.out.print(i + " "); } } } // 下面的和上面的结果一致 public class Main { public static void main(String[] args) { // 打印101-150的质数 for (int i = 101; i <= 150; i++) { boolean flag = true; for (int j = 2; j < i / 2; j++) { if (i % j == 0) { flag = false; break; } } if(flag){ System.out.print(i + " "); } } } }
-
方法
Java方法是语句的集合,他们在一起执行一个功能。
- 方法是解决一类问题的步骤的有序结合
- 方法包含于类或对象中
- 方法在程序中被创建,在其他地方被引用
设计方法的原则:方法的本意是代码块,就是实现某个功能的语句块。我们设计方法的时候,最好保持方法的原子行,就是一个方法只完成1个功能,这样利于我们后期的扩展。
1、方法的定义
Java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段,一班情况下,定义一个方法包含以下语法:
-
修饰符:修饰符,这是可选的,告诉编译器如何调用该方法,定义了该方法的询问类型
-
返回值类型:方法可能会返回值,returnValueType是返回值的数据类型,有些方法执行所需的操作,但没有返回值,在这种情况下,returnValueType是关键字void
-
方法名:是方法的实际名称、方法名和参数共同构成方法签名
-
参数类型参数像是一个占位符,当方法被调用时,传递值给参数,这个值被称为实参或者变量,参数列表是指方法的参数类型、顺序和参数的个数,参数是可选的,方法可以不包含任何参数
-
方法体:方法体包含具体的语句定义该方法的功能
修饰符 返回值类型(void不返回) 方法名(参数类型 参数名){ ··· 方法体 ··· return 返回值; }
2、方法的调用
- 调用方法:对象名.方法名(实参)
- java支持两种调用方法的方式,根据方法是否返回值来选择
- 当方法返回一个值得时候,方法调用通常被当做一个值。
- 如果方法返回值是void,方法调用一定是一条语句。
3、方法的重载
-
重载就是在一类中,有相同的函数名称,但形参不同的函数
-
方法的重载的规则
- 方法名称必须相同
- 参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)
- 方法的返回类型可以相同也可以不相同
- 仅仅返回类型不同不足以成为方法的重载
-
实现理论:
方法名称相同时,编译器会根据调用方法的参数个数、参数类型去逐个匹配,已选择对应的方法 ,如果匹配失败,则编译器报错
4、命令行传参
-
有时候希望运行一个程序时再传递给它消息。这要靠传递命令行参数给main()函数实现
-
命令行传参在dos命令中执行,实际就是传参进初始的args数组中,然后在main方法中实现操作。
public class Main { public static void main(String[] args) { for (int i =0;i<args.length;i++) { System.out.println("args[" + i + "]: " + args[i]);// 打印接收到的数据 } } }
-
执行结果:
5、可变参数
-
Jdk1.5开始,Java支持传递同类型的可变参数给一个方法。
-
在方法声明中,在指定参数类型后加一个省略号 (…)。
-
一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。
public class Main { public static void main(String[] args) { double sum = add(60,80,79,45,77,88,100); System.out.println(sum); } public static double add(int a , double...score){ // 除了第一个数据,其余累加 int sum = 0; for (int i = 0; i < score.length; i++) { sum += score[i];// 调用类似于数组 } return sum; } }
6、递归
- 递归就是在方法中自己调用自己
- 利用递归可以用简单的程序解决一些复杂的问题。递归的能力在于用有限的语句来定义对象的无限集合。
- 递归结构包括两个部分:
- 递归头:什么时候不调用自身方法。如果没有递归头,将陷入死循环。
- 递归体:什么时候需要调用自身方法。
public class Main {
public static void main(String[] args) {
System.out.println(f(5));
}
public static int f(int num){
// 阶乘
if(1 == num){return 1;}
else{
return num*f(num-1); //递归
}
}
}
数组
1、数组的定义
- 数组是相同类型数据的有序集合
- 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成
- 每一个数据被称作一个数组元素,每个数组元素可以通过一个下标来访问它们。
2、数组的声明创建
1、数组的声明
-
使用数组需要先声明数组变量
dataType[] arrayRefVar //首选 dataType arrayRefVar[] //效果相同
-
Java语言使用new操作符来创建数组,语法如下
dataType[] arrayRefVar = new dataType[arraySize] // 例如 int[] num = new int[]{3}; // 创建int数组num,里面存着一个数据3 // 等同于 int[] num = {3};
-
数组的元素是通过索引访问的,索引从0开始。
int[] num = new int[3]; // 创建长度为3的int数组num num[1] = 2;// 赋值 num[0] // 默认初始值是0; num[1] // 2 num[2] //初始值是0; num[3] //越界,报错 ArrayIndexOutOfBoundsException
-
获取数组长度用
.length
2、内存分析
3、三种初始化
-
静态初始化
int[] a = {1,2,3};
-
动态初始化
int[] a = new int[2]; a[0] = 1; a[1] = 2;
-
数组的默认初始化
数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。
//静态初始化: 创建+赋值 int[]a = {1,2,3,4,5,6,7,8}; System.out.println(a[0]);// 1 //动态初始化:包含默认初始化 int b[] = new int[10]; b[0] = 10; b[1] = 12; System.out.println(b[0]);// 10 System.out.println(b[1]);// 12 System.out.println(b[2]);// 0 System.out.println(b[3]);// 0
-
数组的四个基本特点
- 其长度是确定的。数组一旦被创建,它的大小就是不可以被改变的。
- 其数组元素必须是相同类型,不允许出现混合类型。
- 数组中的元素可以是任何数据类型,包括基本类型和引用类型。
- 数组变量属于引用类型,数组也可以看成是变量,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组本身是在堆中的。
-
数组边界
- 下标的合法区间:[ 0,length-1 ],如果越界就会报错;
- ArrayIndexOutOfBoundsException:数组下标越界异常
- 小结:
- 数组是相同数据类型(数据类型可以为任意类型)的有序集合
- 数组也是对象。数组元素相当于对象的成员变量
- 数组长度是确定的,不可变的。如果越界,则报错:ArrayIndexOutOfBounds
4、数组的使用
-
普通的For循环
int[] array = {1,2,3,4,5}; //打印全部数组元素 for (int i = 0; i < array.length; i++) { System.out.println(array[i]); // 1 2 3 4 5 } System.out.println("==============================="); //计算所有元素的和 int sum = 0; for (int i = 0; i < array.length; i++) { sum+=array[i]; } System.out.println("sum="+sum);// sum = 15 System.out.println("=================================="); //查找最大元素 int max =array[0]; for (int i = 1; i < array.length; i++) { if (array[i]>max){ max = array[i]; } } System.out.println("max = "+max);// max = 5 }
-
For-Each循环(增强型for循环)
-
数组方法入参
-
数组作返回值
int[] arrays = {1,2,3,4,5}; //jdk1.5 没有下标 // for (int array : arrays) { // System.out.println(array); // } printArray(arrays);// 1 2 3 4 5 System.out.print("========================="); int[] reverse = reverse(arrays); printArray(reverse);// 5 4 3 2 1 } //反转数组 public static int[] reverse(int[] arrays) { int[] result = new int[arrays.length]; //反转的操作 for (int i = 0,j = result.length-1; i < arrays.length ; i++,j--) { result[j] = arrays[i]; } return result; } //打印数组元素 public static void printArray(int[] arrays) { for (int i = 0; i < arrays.length; i++) { System.out.print(arrays[i]+" "); } }
5、多维数组
-
多维数组可以看做是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组
-
二维数组:
int a [][] = new int[2][5];
6、Arrays类
- 数组的工具类是java.utill,Arrays
- 由于数据对象本身并没有方法可以供我们使用,但是API提供了一个工具类Arrays供我们使用
- Array类中的方法都是static修饰的静态方法,使用时直接使用类名进行调用,可以不用对象调用
- 查找jdk帮助文档
- 常用功能 :
- 给数组赋值:fill方法
- 排序:sort方法,升序
- 比较数组:equals方法比较数组中元素值是否相等
- 查找数组元素:binarySearch对排序号的数组进行二分法查找操作
7、稀疏数组
- 当一个数组中大部分元素为0,或者为同一值的数组时,可以用稀疏数组来保存该数组。