JavaSE-从入门到精通(2)

一,逻辑控制:

程序如人生,循环中夹杂着顺序,顺序中夹杂则循环,伴随着一次次的成长

本文的以下结构其实和C语言大差不差,主要区别在后面的内容, Java是注重面向对象编程的语言。 

1.1顺序结构

顺序结构比较简单,按照代码书写的顺序一行一行执行。
System . out . println ( "博主好帅" );
System . out . println ( "是呀是呀" );
System . out . println ( "对呀对呀" );
// 运行结果
博主好帅
是呀是呀
对呀对呀

 1.2分支结构

1.2.1 if语句

语法格式1

if ( 布尔表达式 ){
// 语句
} else {
// 语句 2
}
如果布尔表达式结果为 true ,执行 if 中的语句,否则执行else语句。
int score = 92 ;
if ( score >= 90 ){
System . out . println ( "奖励100原石 " );
}else{
System . out . println ( "原神关闭 " );
}
语法格式2(适合多种情况时)
if ( 布尔表达式 1 ){
// 语句 1
} else if ( 布尔表达式 2 ){
// 语句 2
} else {
// 语句 3
if(score >= 90){
System.out.println("优秀");
}else if(score >= 80 && score < 90){
System.out.println("良好");
}else if(score >= 70 && score < 80){
System.out.println("中等");
}else if(score >= 60 && score < 70){
System.out.println("及格");
}else if(score >= 0 && score < 60){
System.out.println("不及格");
}else{
System.out.println("错误数据");
}

判断一个年份是否为闰年:

int year = 2000;
if (year % 100 == 0) {
// 判定世纪闰年
if (year % 400 == 0) {
System.out.println("是闰年");
} else {
System.out.println("不是闰年");
}
} else {
// 普通闰年
if (year % 4 == 0) {
System.out.println("是闰年");
} else {
System.out.println("不是闰年");
}
}

运行结果:

1.2.2switch 语句

1. 先计算表达式的值
2. case 依次比较,一旦匹配就执行该项下的语句,直到遇到 break 时结束
3. 当表达式的值没有与所列项匹配时,执行 default
switch 的括号内 只能是 以下类型的表达式:
基本类型: byte char short int ,注意不能是float,double, long,boolean 类型
引用类型: String 常量串、枚举类型
double num = 1.0;
switch(num) {
case 1.0:
System.out.println("hehe");
break;
case 2.0:
System.out.println("haha");
break;
}
// 编译出错
Test.java:4: 错误: 不兼容的类型: 从double转换到int可能会有损失
switch(num) {
^
1 个错误

语法格式:

switch ( 表达式 ){
case 常量值 1 :{
语句 1 ;
[ break ;]
}
case 常量值 2 :{
语句 2 ;
[ break ;]
}
...
default :{
内容都不满足时执行语句 ;
[ break ;]
}
}

判断星期几,一个简单的易理解的switch语句: 

int day = 1 ;
switch ( day ) {
case 1 :
System . out . println ( " 星期一 " );
break ;
case 2 :
System . out . println ( " 星期二 " );
break ;
case 3 :
System . out . println ( " 星期三 " );
break ;
case 4 :
System . out . println ( " 星期四 " );
break ;
case 5 :
System . out . println ( " 星期五 " );
break ;
case 6 :
System . out . println ( " 星期六 " );
break ;
case 7 :
System . out . println ( " 星期日 " );
break ;
default :
System . out . println ( " 输入有误 " );
break ;
}

 1.3循环结构:

1.3.1while循环

基本语法格式 :
while ( 循环条件 ){
循环语句 ;
}//循环条件为 true, 则执行循环语句 ; 否则结束循环;

//打印1到10
int num = 1 ;
while ( num <= 10 ) {
System . out . println ( num );
num ++ ;
}

注意事项:

1. if 类似 , while 下面的语句可以不写 { } , 但是不写的时候只能支持一条语句 . 建议还是加上 { }
2. if 类似 , while 后面的 { 建议和 while 写在同一行 .
3. if 类似 , while 后面不要多写 分号 , 否则可能导致循环不能正确执行 .

break
break 的功能是让循环提前结束 .
代码示例 : 找到 100 - 200 中第一个 3 的倍数
int num = 100 ;
while ( num <= 200 ) {
if ( num % 3 == 0 ) {
System . out . println ( " 找到了 3 的倍数 , :" + num );
break ;
}
num ++ ;
}
// 执行结果
找到了 3 的倍数 , : 102
continue
continue 的功能是跳过这次循环 , 立即进入下次循环 .
代码示例 : 找到 100 - 200 中所有 3 的倍数
int num = 100 ;
while ( num <= 200 ) {
if ( num % 3 != 0 ) {
num ++ ; // 这里的 ++ 不要忘记 ! 否则会死循环 .
continue ;
}
System . out . println ( " 找到了 3 的倍数 , :" + num );
num ++ ;
}

1.3.2 for 循环

 基本语法

for ( 表达式① ; 布尔表达式② ; 表达式③ ){
表达式④ ;
}
表达式 1: 用于初始化循环变量初始值设置,在循环最开始时执行,且只执行一次
表达式 2: 循环条件,满则循环继续,否则循环结束
表达式 3: 循环变量更新方式

 打印 1 - 10 的数字

for ( int i = 1 ; i <= 10 ; i ++ ) {
System . out . println ( i );
}

 1.3.3do while 循环(选学)

基本语法
do {
循环语句 ;
} while ( 循环条件 );

 先执行循环语句, 再判定循环条件,循环条件成立则继续执行,否则循环结束。

 例如:打印 1 - 10

 int num = 1;

do {
System . out . println ( num );
num ++ ;
} while ( num <= 10 );

 【注意事项】:

1. do while 循环最后的分号不要忘记
2. 一般 do while 很少用到 , 更推荐使用 for while.

 1.4. 输入输出

1.4.1基本语法

System . out . println ( msg ); // 输出一个字符串 , 带换行
System . out . print ( msg ); // 输出一个字符串 , 不带换行
System . out . printf ( format , msg ); // 格式化输出
println 输出的内容自带 \n, print 不带 \n
printf 的格式化输出方式和 C 语言的 printf 是基本一致的.
格式化字符串:
不需要记,需要时可查

1.4.2 从键盘输入

使用 Scanner 读取字符串 / 整数 / 浮点数
next遇到空格结束,nextLine遇到空格结束。
import java.util.Scanner; // 需要导入 util 包
Scanner sc = new Scanner(System.in);
System.out.println("请输入你的姓名:");
String name = sc.nextLine();
System.out.println("请输入你的年龄:");
int age = sc.nextInt();
System.out.println("请输入你的工资:");
float salary = sc.nextFloat();
System.out.println("你的信息如下:");
System.out.println("姓名: "+name+"\n"+"年龄:"+age+"\n"+"工资:"+salary);
sc.close(); // 注意, 要记得调用关闭方法
// 执行结果
请输入你的姓名:
张三
请输入你的年龄:
18
请输入你的工资:
1000
你的信息如下:
姓名: 张三
年龄:18
工资:1000.0
使用 Scanner 循环读取 N 个数字,并求取其平均值

Scanner sc = new Scanner(System.in);
int sum = 0;
int num = 0;
while (sc.hasNextInt()) {
int tmp = sc.nextInt();
sum += tmp;
num++;
}
System.out.println("sum = " + sum);
System.out.println("avg = " + sum / num);
sc.close();
// 执行结果
10
40.0
50.5
^Z
sum = 150.5
avg = 30.1
当循环输入多个数据的时候 , 使用 ctrl + z 来结束输入 (Windows 上使用 ctrl + z, Linux / Mac 上使用 ctrl
+ d).

1.4.3猜数字 

最后,一个简单的猜数字游戏来巩固所学的知识

import java.util.Random;
import java.util.Scanner;;
class Test {
public static void main(String[] args) {
Random random = new Random(); // 默认随机种子是系统时间
Scanner sc = new Scanner(System.in);
int toGuess = random.nextInt(100);//0-100的随机数
// System.out.println("toGuess: " + toGuess);
while (true) {
System.out.println("请输入要输入的数字: (1-100)");
int num = sc.nextInt();
if (num < toGuess) {
System.out.println("低了");
} else if (num > toGuess) {
System.out.println("高了");
} else {
System.out.println("猜对了");
break;
}
}
sc.close();
}
}

 二,方法

在编程中也是一样,某段功能的代码可能频繁使用到,如果在每个位置都重新实现一遍,会
使程序变得繁琐,开发效率低下,做了大量重复性的工作 ,不利于维护,需要改动时,所有用到该段代码的位置都需要修改
因此,在编程中,我们也可以将频繁使用的代码封装成 ,需要时直接拿来链接 ( 即方法名 -- 方法的入口地址) 使用即可,避免了一遍一遍的累赘,
有点类似于C语言中的函数

 2.1. 方法概念及使用

方法就是一个代码片段 . 类似于 C 语言中的 " 函数 "

方法的定义

方法语法格式
// 方法定义
修饰符 返回值类型 方法名称 ([ 参数类型 形参 ...]){
方法体代码 ;
[ return 返回值 ];
}

示例一:实现一个函数,检测一个年份是否为闰年

public class Method{
// 方法定义
public static boolean isLeapYear(int year){
if((0 == year % 4 && 0 != year % 100) || 0 == year % 400){
return true;
}else{
return false;
}
}
}

 注意事项:

1. 修饰符:现阶段直接使用 public static即可
2. 返回值类型:如果方法有返回值,返回值类型必须要与返回的实体类型一致,如果没有返回值,必须写成 void
4. 参数列表:如果方法没有参数, () 中什么都不写,如果有参数,需指定参数类型,多个参数之间使用逗号隔开
5. 方法体:方法内部要执行的语句
6. java 当中,方法必须写在类当中
7. java 当中,方法不能嵌套定义
8. java 当中,没有方法声明

方法调用的执行过程

调用方法 --- > 传递参数 --- > 找到方法地址 --- > 执行被调方法的方法体 --- > 被调方法结束返回 --- > 回到主调方法继续往下 执行
代码示例 : 计算 1! + 2! + 3! + 4! + 5!
public class TestMethod {
public static void main(String[] args) {
int sum = 0;
for (int i = 1; i <= 5; i++) {
sum += fac(i);
}
System.out.println("sum = " + sum);
}
public static int fac(int n) {
System.out.println("计算 n 的阶乘中n! = " + n);
int result = 1;
for (int i = 1; i <= n; i++) {
result *= i;
}
return result;
}
}

实参和形参的关系(重要)

Java 中方法的形参就相当于 sum 函数中的自变量 n ,用来接收 sum 函数在调用时传递的值的 。形参的名字可以随意
取,对方法都没有任何影响, 形参只是方法在定义时需要借助的一个变量,用来保存方法在调用时传递过来的值

public static int getSum ( int N ){ // N 是形参
return ( 1 + N ) * N / 2 ;
}
getSum ( 10 ); // 10 是实参 , 在方法调用时,形参 N 用来保存 10
getSum ( 100 ); // 100 是实参,在方法调用时,形参 N 用来保存 100

在Java中,实参的值永远都是拷贝到形参中,形参和实参本质是两个实体

public class TestMethod {
public static void main(String[] args) {
int a = 10;
int b = 20;
swap(a, b);
System.out.println("main: a = " + a + " b = " + b);
}
public static void swap(int x, int y) {
int tmp = x;
x = y;
y = tmp;
System.out.println("swap: x = " + x + " y = " + y);
}
}
// 运行结果
swap: x = 20 y = 10
main: a = 10 b = 20

可以看到,在swap函数交换之后,形参xy的值发生了改变,但是main方法中ab还是交换之前的值,即没有交换成功。有点类似于C语言中的指针交换才可以使实参的值交换。

没有返回值的方法

方法的返回值是可选的. 有些时候可以没有的,没有时返回值类型必须写成void

class Test {
public static void main ( String [] args ) {
int a = 10 ;
int b = 20 ;
print ( a , b );
}
public static void print ( int x , int y ) {
System . out . println ( "x = " + x + " y = " + y );
}
}

2.2方法重载

什么需要方法重载:

在自然语言中,一个词语如果有多重含义,那么就说该词语被重载了,具体代表什么含义需要结合具体的场景。
Java 中方法也是可以重载的。
Java方法重载的概念
Java 中,如果多个方法的名字相同,参数列表不同,则称该几种方法被重载了
public class TestMethod {
public static void main ( String [] args ) {
add ( 1 , 2 ); // 调用 add(int, int)
add ( 1.5 , 2.5 ); // 调用 add(double, double)
add ( 1.5 , 2.5 , 3.5 ); // 调用 add(double, double, double)
}
public static int add ( int x , int y ) {
return x + y ;
}
public static double add ( double x , double y ) {
return x + y ;
}
public static double add ( double x , double y , double z ) {
return x + y + z ;
}
}
注意:
1. 方法名必须相同
2. 参数列表必须不同 ( 参数的个数不同、参数的类型不同、类型的次序必须不同 )
3. 与返回值类型是否相同无关
4.返回值不同无法构成重载
一张图看懂方法重载:

 方法签名  
在同一个作用域中不能定义两个相同名称的标识符。比如:方法中不能定义两个名字一样的变量,那 为什么类中就 可以定义方法名相同的方法呢?
方法签名即:经过编译器编译修改过之后方法最终的名字。具体方式: 方法全路径名 + 参数列表 + 返回值类型,构成 方法完整的名字
简单来说,就是编译器会给相同的方法定义不同的调用名字,如图所示:

2.3递归 

一个方法在执行过程中调用自身 , 就称为 " 递归 ".
递归相当于数学上的 " 数学归纳法 ", 有一个起始条件 , 然后有一个递推公式 .
例如, 我们求 N!
起始条件: N = 1 的时候, N! 为 1. 这个起始条件相当于递归的结束条件.
递归公式: 求 N! , 直接不好求, 可以把问题转换成 N! => N * (N-1)

 代码示例: 递归求 N 的阶乘

public static void main(String[] args) {
int n = 5;
int ret = factor(n);
System.out.println("ret = " + ret);
}
public static int factor(int n) {
if (n == 1) {
return 1;
}
else
return n * factor(n - 1); // factor 调用函数自身
}
// 执行结果
ret = 120

这是递归的调用过程:先是层层的递进,然后都回归到最初的位置

 

递归的使用场景也有限制,如计算斐波那契数列时,会出现大量冗余的运算

 

 如图,计算了三千多万次,此时不如循环节省空间

public static int fib(int n) {
int last2 = 1;
int last1 = 1;
int cur = 0;
for (int i = 3; i <= n; i++) {
cur = last1 + last2;
last2 = last1;
last1 = cur;
}
return cur;
}

  • 28
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值