目录
if语句
if语句格式2 if…else…嵌套使用
·针对语句格式2
if(表达式){
语句1;
}else{
语句2;
}
if语句格式2的一种嵌套格式
if(表达式1){
if(表达式2){
语句1;
}else{
语句2;
}
}else{
if(表达式3){
语句3;
}else{
语句4;
}
}
键盘录入三个数据,获取三个数据中的最大值
import java.util.Scanner ;
class IfDemo{
public static void main(String[] artgs){
//创建键盘录入数据
Scanner sc = new Scanner(System.in) ;
//提示并录入数据
System.out.println("请您输入第一个数据:") ;
int a = sc.nextInt() ;
System.out.println("请您输入第二个数据:") ;
int b = sc.nextInt() ;
System.out.println("请您输入第三个数据:") ;
int c = sc.nextInt() ;
//三元运算符
//中间变量
int temp = (a>b)?a:b ;
//定义结果变量接收数据
int max = (temp>c)?temp:c ;
System.out.println("三个数据最大值是:"+max) ;
System.out.println("------------------------------") ;
//if...else...嵌套
//定义一个结果变量max2
int max2 ;
if(a>b){
//a比b大
//嵌套if...else...
if(a>c){
//同时a比c大
max2 = a ;
}else{
//c大
max2 = c ;
}
}else{
//a比b小
//b和在c进行比较
if(b>c){
max2 = b;
}else{
max2 = c ;
}
}
//输出结果
System.out.println("三个数据最大值是:"+max2) ;
}
}
if...else....流程控制语句它和三元运算符的区别?
面试题
if...else...格式和三元运算符的区别?
三元运算符只是一个运算符号,不是流程控制语句,在三元中不能输出打印值,
可以操作具体的数据值(结果最终是数据值);
而if...else...流程控制语句,范围远远大于三元运算符
既可以使用具体数据值,也可以是打印内容;
三元运算符能够使用的一定能够if...else...
if...else...能够实现的,不一定能够使用三元!
键盘录入一个数据(int类型),判断数据是否是偶数!
//导包
import java.util.Scanner ;
class IfDemo2{
public static void main(String[] args){
//创建键盘录入对象
Scanner sc = new Scanner(System.in) ;
//提示并录入数据
System.out.println("请您输入一个数据:") ;
int number = sc.nextInt() ;
//if...else...实现
if(number % 2 ==0){
System.out.println("是偶数") ;
}else{
System.out.println("不是偶数") ;
}
System.out.println("---------------------------") ;
//System.out.println(
//(number%2==0)?(System.out.println("是偶数")):(System.out.println("不是偶数"))
// );
//boolean s = (number%2==0)?(true):(false);
//System.out.println(s) ;
String s = (number%2 ==0)?("是偶数"):("不是偶数") ;
System.out.println(s) ;
}
}
if语句的第三种格式
if格式3:
if(表达式1){
语句1;
}else if(表达式2){
语句2;
...
}else{
语句n;
}
流程:
)先判断表达式1是否成立,成立,则执行语句1
2)不成立,则判断表达式2是否成立,成立,执行语句2;
否则依次...进行判断
...
3)如果上面都不成立,则执行else语句,最终结束;
场景:针对多种进行判断!
需求:
键盘录入学生成绩(0-100),判断
90-100 "优秀"
80-90 "较好"
70-80 "良好"
60-70 "及格"
60以下 "不及格"
//导包
import java.util.Scanner ;
class IfDemo3{
public static void main(String[] args){
//创建键盘录入数据对象
Scanner sc = new Scanner(System.in) ;
//提示并录入数据
System.out.println("请输入学生成绩:") ;
int socer = sc.nextInt() ;
//if格式3实现
/*
if(socer >= 90 && socer<=100){
System.out.println("该学生成绩优秀!") ;
}else if(socer>=80 && socer<90){
System.out.println("该学生成绩较好!") ;
}else if(socer>=70 && socer<80){
System.out.println("该学生成绩良好!") ;
}else if(socer>=60 && socer<70){
System.out.println("该学生成绩及格!") ;
}else{
System.out.println("不及格!") ;
}
*/
/*
测试数据的时候-----> 测试人员:编写测试用例!
1)测试边界数据
2)测试边界以内的数据
3)测试错误数据
*/
//优化
if(socer<0 || socer>100){
System.out.println("录入的成绩是非法数据!") ;
}else if(socer>=90 && socer<=100){
System.out.println("优秀!") ;
}else if(socer>=80 && socer<90){
System.out.println("较好!") ;
}else if(socer>=70 && socer<80){
System.out.println("良好!") ;
}else if(socer>=60 && socer<70){
System.out.println("刚及格!") ;
}else{
System.out.println("不及格!") ;
}
}
}
测试
需求:默认int
键盘录入月份的值,判断季节
3,4,5 春季
6,7,8 夏季
9,10,11 秋季
12,1,2 冬季
//导包
import java.util.Scanner ;
class IfTest{
public static void main(String[] args){
//创建键盘录入对象
Scanner sc = new Scanner(System.in) ;
//提示并录入数据
System.out.println("请你输入一个月份的值:") ;
int month = sc.nextInt() ;
if(month<1 || month>12){
System.out.println("对不起,月份数据非法!") ;
}else if( month== 3 || month == 4 || month==5){
System.out.println("春季") ;
}else if(month == 6 || month == 7 || month == 8){
System.out.println("夏季") ;
}else if(month == 9 || month == 10 || month==11){
System.out.println("秋季") ;
}else{
System.out.println("冬季") ;
}
}
}
选择结构语句之switch语句
switch语句格式
switch(表达式){
case 值1:
语句1;
break ;
case 值2:
语句2;
break ;
...
...
default:
语句n;
break ;
}
执行流程:
1)表达式中的值先和case值1比较,如果匹配,执行语句1,语句break,语句结束;
2)case值1不匹配,继续和case值2进行比较,如果一致,执行语句2,swich结束;
...
...
3)如果上面的case的值和表达式中的结果值都不匹配,执行default语句,
执行语句n,switch语句结束;
需求:
键盘录入一个int类型的数据,使用switch选择判断,对应的星期
1 星期一
2 星期二
3 星期三
4 星期四
5 星期五
6 星期六
7 星期日
//导包
import java.util.Scanner ;
class SwitchDemo{
public static void main(String[] args){
//创建键盘录入数据对象
Scanner sc = new Scanner(System.in) ;
int number = 3 ;
//提示并录入数据
System.out.println("请您录入一个星期值:") ;
int week = sc.nextInt();
switch(week){
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("您输入的数据非法!") ;
}
}
}
switch语句使用的注意事项:
1)case语句里面是有break,
如果没有书写break,会造成"case穿透"
2)case语句后面的值只能是常量值,不能是变量值
(Java是一个强类型语言:语法结构很严谨)
3)关于default语句
它可以在语句中的任何位置,不影响switch语句的执行流程!
但是如果在语句中,那么break不要省略!(考点)
如果default语句它在语句的末尾,break可以省略
4)switch语句的结束条件:
1)语句break结束
2)程序默认执行到末尾!(顺序结构语句都是依次由上而下,末尾结束!)
//导包
import java.util.Scanner ;
class SwtichDemo2{
public static void main(String[] args){
//创建键盘录入数据对象
Scanner sc = new Scanner(System.in) ;
int b = 3 ;
//提示并录入数据
System.out.println("请您录入一个星期值:") ;
int week = sc.nextInt();
switch(week){
/*default:
System.out.println("您输入的数据非法!") ;
//break ;
*/
case 1:
System.out.println("星期一") ;
break ;
case 2:
System.out.println("星期二") ;
break ;
//case b:
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
//看程序,写结果
class SwitchTest{
public static void main(String[] args){
int a = 3 ,b = 4 ;
switch(a){
default :
b++ ;//5
case 4:
b++ ; //6
case 5:
b++ ;//7
}
//b结果?
System.out.println("b:"+b) ;
System.out.println("-----------------------------");
int x = 3 ,y = 4 ;
switch(x){
default :
y++ ;
case 3:
y++ ; //5
case 4:
y++ ; //6
}
System.out.println("y:"+y);
}
}
有匹配的就执行匹配的,执行完后如若没有break则就会case穿透,default可以不只放最下方,只要无匹配的就执行default的语句,而如果default里也没有break,同样是会发生case穿透,如果正好不在最下方则就无论条件一直往下执行,当然case穿透不一定是坏事,也可以利用case穿透少些一些代码。
测试2
需求:默认int (使用switch语句实现)
键盘录入月份的值,判断季节
3,4,5 春季
6,7,8 夏季
9,10,11 秋季
12,1,2 冬季
//导包
import java.util.Scanner ;
class SwitchTest2{
public static void main(String[] args){
//创建键盘录入对象
Scanner sc = new Scanner(System.in) ;
//提示并录入数据
System.out.println("请您输入月份的值:") ;
int month = sc.nextInt() ;
//使用switch语句实现
/*
switch(month){
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 ;
case 8:
System.out.println("夏季") ;
break ;
case 9:
System.out.println("秋季") ;
break ;
case 10:
System.out.println("秋季") ;
break ;
case 11:
System.out.println("秋季") ;
break ;
case 12:
System.out.println("冬季") ;
break ;
default:
System.out.println("对不起,地球没有该月份!") ;
break ;
}
*/
//利用case穿透,简化代码
switch(month){
case 3:
case 4:
case 5:
System.out.println("春季") ;
break ;
case 6:
case 7:
case 8:
System.out.println("夏季") ;
break ;
case 9:
case 10:
case 11:
System.out.println("秋季") ;
break ;
case 1:
case 2:
case 12:
System.out.println("冬季") ;
break ;
default:
System.out.println("对不起,非法数据!地球没有该月份") ;
break ;
}
}
}
测试3
需求:
使用switch语句模拟单项选择题
'A'
'B'
'C'
'D'
分析:
1)先去给出一道选择题 (输出语句输出信息)
2)键盘录入(创建键盘录入对象)
3)Java中Scanner键盘录入不能录入字符,
可以录入int类型,65---'A'
66---'B'
67---'C'
68---'D'
将int---强转char
switch(字符){
case 'A':
///
break;
case 'B':
}
//导包
import java.util.Scanner ;
class SwitchTest3{
public static void main(String[] args){
System.out.println("<<我们结婚吧>>里面杨桃谁扮演的?") ;
System.out.println("65 张佳宁") ;
System.out.println("66 高圆圆") ;
System.out.println("67 孙俪") ;
System.out.println("68 赵丽颖") ;
//创建键盘录入对象
Scanner sc = new Scanner(System.in) ;
//提示并录入数据
System.out.println("请您输入一个选项:") ;
int choiceNumber = sc.nextInt() ; //65 int---->字符 'A'
//将choiceNumber强转为char字符类型
//目标类型 变量名 = (目标类型)(初始化值或者表达式) ;
char choice = (char)choiceNumber ;
//使用switch语句接收
switch(choice){
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("输入的选项有误,不存在") ;
break ;
}
}
}
测试4
需求:
使用switch语句模拟单项选择题
"A"
"B"
"C"
"D"
分析:
1)先去给出一道选择题 (输出语句输出信息)
2)键盘录入(创建键盘录入对象)
3)Java中Scanner键盘录入不能录入字符,
Scanner sc = new Scanner(System.in) ;
可以直接录入String
String num = sc.nextLine() ;
switch(num){ //jdk7以后,switch后面跟String字符串
case "A":
}
基本类型:byte,int,short,char
jdk5版本以后,表达式中值的类型可以是枚举 enum(属于引用类型)
jdk7版本以后,表达式中值的类型可以是String:字符串 (属于特殊的引用类型)
//导包
import java.util.Scanner ;
class SwitchTest4{
public static void main(String[] args){
System.out.println("<<我们结婚吧>>里面杨桃谁扮演的?") ;
System.out.println("A 张佳宁") ;
System.out.println("B 高圆圆") ;
System.out.println("C 孙俪") ;
System.out.println("D 赵丽颖") ;
//创建键盘录入对象
Scanner sc = new Scanner(System.in) ;
//提示并录入数据
System.out.println("请您输入一个选项:") ;
String number = sc.nextLine() ; //直接录入字符串
//使用switch语句接收
switch(number){
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("输入的选项有误,不存在") ;
break ;
}
}
}
循环结构语句之for
需求:
在dos控制台输出打印5次"helloworld";
见到这种代码重复性很高(冗余度很大)
java提供循环结构语句之for循环
for(初始化语句;条件表达式;控制体语句或步长语句){
循环体语句;
}
执行流程:
1)先初始化语句进行赋值
2)判断条件表达式是否成立,如果成立,执行循环体语句
2.1)继续执行控制台语句或者步长语句 对初始化语句的变量进行自增或者自减
2.2)继续判断条件表达是否成立,如果成立,按照上面 这种方式执行;
2.3)如果变量自增或者自减到条件表达式不成立为止,循环语句结束!
class ForDemo{
public static void main(String[] args){
//原始的做法
System.out.println("helloworld") ;
System.out.println("helloworld") ;
System.out.println("helloworld") ;
System.out.println("helloworld") ;
System.out.println("helloworld") ;
System.out.println("--------------------------") ;
//上面代码冗余度大,优化
/*
for(初始化语句;条件表达式;控制体语句或步长语句){
循环体语句;
}
*/
for(int x = 1; x<=5 ; x++){//x=1,1<=5-->x=2,x<=5,x=3,x<=5,x=4,x<=5,x<=5,x=6,x<=5
System.out.println("helloworld") ;//第一次打印/第二次/第三次//第四次//第五次
}
}
}
求和思想(求阶乘思想)
需求(for循环)
1)求1-100之间的和
2)求1-100之间的偶数和
3)求5的阶乘!
求阶乘思想和求和思想一样的
n!=n*(n-1)!....
定义一个最终结果变量
int jc = 1 ;
for(int x = 1;x <=5 ; x++){
jc *=x ; //jc = jc *x ;
}
class ForTest{
public static void main(String[] args){
//求5的阶乘
//定义一个最终结果变量
int jc = 1 ;
for(int x = 2; x<=5 ;x++){ //x=2,2<=5
jc*=x ;//jc = jc * x //jc= 1*2
}
System.out.println("5阶乘是:"+jc);
System.out.println("--------------------") ;
//1)求1-100之间的和
//定义结果变量
int sum = 0 ;
for(int x = 1 ;x <=100;x++){
sum +=x ;
}
System.out.println("1-100之间的和是:"+sum) ;
System.out.println("--------------------") ;
//2)求1-100之间的偶数和
//定义结果变量
int sum2 = 0 ;
for(int x = 1 ; x<=100;x++){
if(x%2==0){
//能够被2整除
sum2 +=x ;
}
}
System.out.println("1-100之间的偶数和是:"+sum2) ;
}
}
需求:
1)在dos控制台打印输出1-10的所有数据!
2)在dos控制台打印输出1-10的所有数据之和!(循环)
循环中的求和思想:
定义一个结果变量:int sum = 0 ;
规律:
0 + 1 = 1 ;
1 + 2 = 3 ;
3 + 3 = 6 ;
6 + 4 = 10
10 + 5 = 15
循环中的第一个加数:sum的值
循环中的变量:就是第二个加数 ...
class ForTest2{
public static void main(String[] args){
//原始的做法:
System.out.println(1) ;
System.out.println(2) ;
System.out.println(3) ;
System.out.println(4) ;
System.out.println(5) ;
System.out.println(6) ;
System.out.println(7) ;
System.out.println(8) ;
System.out.println(9) ;
System.out.println(10) ;
System.out.println("----------------------------------------") ;
//循环改进
for(int x =1; x<=10 ;x++){//x=1,1<=10
System.out.println(x) ;//1
}
System.out.println("----------------------------------------") ;
//原始的做法
System.out.println(1+2+3+4+5+6+7+8+9+10) ;
System.out.println("----------------------------------------") ;
//for循环
//定义一个结果变量
int sum = 0 ; //sum=0
for(int x = 1 ; x <=10 ; x++){//x=1,1<=10,x=2,2<=10
//循环体
//sum = sum +x;
sum += x ; // sum = 0 + 1 =1 ; sum = 1 + 2 ;
}
System.out.println("1-10的数据之和是:"+sum) ;
}
}
水仙花数
需求:
在dos控制台打印输出所有的水仙花数
什么是水仙花数:
水仙花数指的是三位数,而且这个三位数每个位上的数据的立方之和是它本身
153 = 1*1*1+5*5*5 +3*3+3
分析:
1)水仙花(三位数)---已经明确了范围,使用for循环x取值 100-999
2)循环里面获取这三位数的上每个位上的数据本身 (关键点)
举例:
153 % 10 = 3 个位 %(求余数)
153 / 10 % 10 = 5 十位 去掉低位,获取低位(获取十位)
153 /10 /10 % 10 = 1 百位
定义三个变量,分别代表个位,十位,百位
int ge = x % 10 ;
int shi = x /10 %10 ;
int bai = x /10/10 %10;
2.1)满足条件 if(x==(ge*ge*ge+shi*shi*shi+bai*bai* bai)){
//输出x
}
class ForTest3{
public static void main(String[] args){
System.out.println("水仙花数是:") ;
//水仙花,三位数--for循环
for(int x = 100;x<=999; x++){
//定义三个变量:ge,shi,bai
int ge = x % 10 ; // 153 %10 =3
int shi = x /10%10 ; // 153 /10%10 = 5
int bai = x /10/10 %10 ; //153 /10/10%10 = 1
//如果当前x就是ge*ge*ge+shi*shi*shi+bai*bai*bai,输出x
if(x==(ge*ge*ge+shi*shi*shi+bai*bai*bai)){
System.out.println(x) ;
}
}
}
}
/*
水仙花数是:
153
370
371
407
*/
统计思想
需求:
统计水仙花数有多少个?
循环中的统计思想:
1)定义统计变量 int count = 0 ;
2)水仙花数---明确范围 for循环 x 的取值100-999
2.1)定义三个变量,int ge = x % 10 ;
int shi = x/10 % 10 ;
int bai = x/10/10%10;
2.2)如果满足条件x==(ge*ge*ge+shi*shi*shi+bai*bai* bai)
2.3)统计变量++即可
3)输出统计变量即可!
class ForTest4{
public static void main(String[] args){
//1)定义统计变量
int count = 0 ;
//2)水仙花:三位数
for(int x = 100; x<=999; x++){
//个位,百位,十位三个变量
//获取x这个数据每个位上的数据本身
int ge = x % 10;
int shi = x /10%10;
int bai = x /10/10 %10;
//2.1)如果满足条件x==(ge*ge*ge+shi*shi*shi+bai*bai* bai)
if(x==(ge*ge*ge+shi*shi*shi+bai*bai*bai)){
//2.2)统计变量++
count ++ ;
System.out.println("第"+count+"次的水仙花数是:"s+x) ;
}
}
System.out.println("水仙花数共有:"+count+"个");
}
}
循环结构语句之while
while循环
格式:
基本格式:
while(条件表达式){
循环体语句;
控制体语句或者步长语句;
}
扩展格式:(使用多)
初始化语句:
while(条件表达式){
循环体语句;
控制体语句或者步长语句;
}
执行流程:
1)初始化语句进行变量赋值
2)判断条件表达式是否成立,
成立,执行循环体语句,依次执行控制体语句(对变量控制)
继续回到2)进行判断
...
...
3)条件表达式不满足,循环结束!
需求:在dos控制体输出打印 5次"helloworld"
需求2:
使用while循环
1)求1-100的偶数和
2)打印所有的水仙花数
3)统计水仙花数的个数
class WhileDemo{
public static void main(String[] args){
/*
初始化语句:
while(条件表达式){
循环体语句;
控制体语句或者步长语句; (必须存在,否则造成"死循环")
}
*/
int x = 1 ;
while(x <= 5){
System.out.println("helloworld") ;
x++ ;//控制体语句
}
}
}
while和for的区别
面试题
while和for的区别?
共同点:
都是使用循环思想解决一些问题
不同点:
1)格式本身不同
for(初始化语句;条件表达式;控制体语句){
循环体语句;
}
初始化语句;
while(条件表达式){
循环体语句;
控制体语句;
}
2)是否明确循环次数
for循环:明确循环次数优先for循环,(for还是很频繁使用的)
while循环:不明确循环次数,使用while循环
3)从内存角度考虑销毁不同:
for循环结束,里面的变量及时释放了,所以不能在访问for中的变量
whlile循环结束,依然可以访问里面变量,
所以消耗资源相对for循环大一些!
class WhileDemo2{
public static void main(String[] args){
//需求:在dos控制台打印输出 5次"我爱高圆圆"
//for实现
/*
for(int x = 1 ; x <=5 ;x++){
System.out.println("我爱高圆圆") ;
}
*/
//System.out.println(x) ;
//while实现
int x = 1 ;
while(x<=5){
System.out.println("我爱高圆圆") ;
x++ ;
}
System.out.println(x) ;
}
}
死循环
常见的两种死循环格式
for(;;){ //jdk源码中比较多
循环体...
}
while(true){ //推荐
循环体...
}
利用死循环解决一些问题!
死循环:肯定需要利用一些条件,当达到某种条件的时候,结束循环(break;中断,结束!)
class WhileDemo3{
public static void main(String[] args){
/*
for(;;){
//逻辑:达到一种条件,break
System.out.println("今天很开心,学习了死循环!") ;
}
*/
//第二种格式
while(true){
//逻辑:达到一种条件,break
System.out.println("今天很开心,学习了死循环!") ;
}
}
}
水仙花数
class WhileTest{
public static void main(String[] args){
//1-100偶数和
int x = 1 ;
//结果变量
int sum = 0 ;
while(x<=100){
if(x%2==0){
sum +=x ;
}
x++ ;
}
System.out.println("1-100偶数和是:"+sum) ;
System.out.println("----------------------------") ;
//打印所有水仙花数
//统计水仙花多少个
//统计变量
int count = 0 ;
int i = 100;
while(i<=999){
//定义三个变量
int ge = i % 10 ;
int shi = i /10 % 10 ;
int bai = i /10/10 % 10;
if(i ==(ge*ge*ge+shi*shi*shi+bai*bai* bai)){
count ++ ;
System.out.println("第"+count+"次的水仙花是:"+i) ;
}
i ++ ;
}
System.out.println("共有"+count+"个") ;
}
}
测试
/*
需求:
键盘录入int类型的数据,猜数字游戏(1-100之间的数据!)
jdk提供了一个类java.lang.Math(不需要导包):数学运算的工具
random()这个函数可以获取[0.0,1.0)的随机数 (常用类讲)
分析:
1)产生一个1-100之间的随机数(利用jdk提供Math完成)--number
while(true){
2)不断的创建键盘录入对象,录入int类型的数据--guessNumber
3)判断
如果guessNumber > number ,提示数据大了
否则如果guessNumber < number ,提示数据小了
最终,一致! 结束循环,break(中断,结束);
}
*/
//导包
import java.util.Scanner ;
class WhileTest2{
public static void main(String[] args){
//先去使用Math类产生随机数--public static double random()
/*
for(int x = 1 ; x <=10 ;x++){
//0.0-1.0的随机数:取不到1.0
//double number = Math.random() ;
//1-100的随机数 int
int number = (int)(Math.random()*100+1);
System.out.println(number) ;
}
*/
//1)产生一个1-100之间的随机数(利用jdk提供Math完成)--number
int number = (int)(Math.random()*100+1) ;
System.out.println("猜数字游戏开始了...") ;
//定义一个统计变量
int count = 0 ;
while(true){
//统计变量++
count ++ ;
//2)创建键盘录入对象
Scanner sc = new Scanner(System.in ) ;
//3)提示并录入数据
System.out.println("请您输入要猜的数据:") ;
int guessNumber = sc.nextInt() ;
if(guessNumber<1 || guessNumber>100){
System.out.println("您输入的数据不合法!") ;
}else if(guessNumber > number){
System.out.println("您要猜的数据"+guessNumber+"大了") ;
}else if(guessNumber < number){
System.out.println("您要猜的数据:"+guessNumber+"小了") ;
}else{
System.out.println("恭喜您,第"+count+"次,猜对了!") ;
break ;//满足条件,结束死循环
}
}
}
}
do-while 循环
/*
do-while 循环
格式
初始化语句;
do{
循环体语句;
控制体语句;
}while(条件表达式) ;
执行流程:
1)初始化语句进行赋值
2)循环体语句,--->-完成条件判断---控制体语句
继续判断,当条件不满足,循环结束!
如果条件直接不满足,循环体至少执行一次;
这也是for/while最大的区别
dowhile 循环开发中很少使用这个格式 (jdk源码会用的!)
*/
class DoWhileDemo{
public static void main(String[] args){
//dos控制台 打印 6次 "helloword"
int x = 1 ;
do{
System.out.println("helloword");
x++ ;
}while(x<=6) ;
System.out.println(x) ;
}
}
for循环嵌套
/*
需求:
在dos控制台打印输出四行5列的*形
*****
*****
*****
*****
for循环的嵌套
for(初始化语句;条件表达式;控制体语句){
//循环体---就是内层for循环
for(初始化语句2;条件表达式2;控制体语句2){
内层循环的循环体...
}
}
*/
class ForForDemo{
public static void main(String[] args){
//原始的做法:
//输出四句话:每一个*****
System.out.println("*****") ;
System.out.println("*****") ;
System.out.println("*****") ;
System.out.println("*****") ;
System.out.println("---------------------------------") ;
//第一行:有5个*,单独每次打印一个*,还不能换行,
//Sytem.out.print():不换行打印内容
/*
System.out.print("*") ;
System.out.print("*") ;
System.out.print("*") ;
System.out.print("*") ;
System.out.print("*") ;
*/
//上面这个代码每次打印一个*,冗余度大,循环改进
//循环5次
for(int x = 0 ; x<5;x++){//0,1,2,3,4
//循环体:
System.out.print("*") ;
}
//换行
System.out.println() ;
//第二行
//5个*,在进行换行
for(int x = 0 ; x < 5 ; x++){
//循环体
System.out.print("*") ;
}
//换行
System.out.println() ;
//第三行
//5个*,在进行换行
for(int x = 0 ; x < 5 ; x++){
//循环体
System.out.print("*") ;
}
//换行
System.out.println() ;
//第四行
//5个*,在进行换行
for(int x = 0 ; x < 5 ; x++){
//循环体
System.out.print("*") ;
}
//换行
System.out.println() ;
System.out.println("----------------最终版优化----------------") ;
//最终版的进行优化
/*
上面的这个代码 ,循环了四次,冗余度,进行优化
//5个*,在进行换行
for(int x = 0 ; x < 5 ; x++){
//循环体
System.out.print("*") ;
}
//换行
System.out.println() ;
*/
for(int x =0 ; x<4; x++){//x=0,1,2,3 x:行数
for(int y = 0 ; y < 5 ; y++){//y:列数 0,1,2,3,4
//循环体
System.out.print("*") ;
}
//换行
System.out.println() ;
}
}
}
//需求
/*
打印
*
**
***
****
*****
分析:
定义变量x:行数 ,y,列数(从0开始)
x=0,第一行, 有1列 y= 0
x=1,第二行,有2列 y<=1
x=2,第三行,有3列 , y<=2 0,1,2
x=3,第四行,有4列, y<=3 0,1,2,3
x=4,第五行,有5列, y<=4 0,1,2,3,4
列数的变化y<=x
*/
class ForForDemo2{
public static void main(String[] args){
//5行5列的*
for(int x = 0 ; x <5 ; x++) { //外层控制行数
for(int y = 0 ; y < 5 ;y++){ //控制列数
System.out.print("*") ;
}
System.out.println() ;
}
System.out.println("--------------------------") ;
//5行5列,列数在变化
for(int x = 0 ; x < 5 ; x++){//行数 x=0,0<5 ,1<5
for(int y = 0 ; y <=x ;y++){//变化的列数 y=0,y<=0 y=0,y<=1
System.out.print("*") ; //第一行一个*
}
System.out.println() ;//换行
}
}
}
99乘法表
/*
1 * 1 = 1 ;
1* 2 = 2 ; 2* 2 = 4;
...
*形很类似
*
**
***
****
*****
******
*******
********
*********
*/
class ForForDemo3{
public static void main(String[] args){
//99乘法表:列数y小于等于行数 (x)
//保证数据:x,y都是1开始
for(int x = 1 ; x <=9 ; x++){//行数 x=1 ,1<=9
for(int y = 1 ; y <=x ; y ++){//列数 y=1,y<=1
//1 * 1 = 1
// \x:x代表任意字符
// "\t" :制表符号 ,相当于tab键的效果
System.out.print(x+"*"+y+"="+(y * x)+"\t") ;
}
System.out.println() ;//换行
}
}
}
其他的跳转控制语句
break
/*
跳转控制语句:
break
continue
return
break:结束中断的意思
两种应用场景:
1)循环语句中使用,结束循环用的
2)switch语句中使用,结束switch
不能单独使用,不能脱离上面两种场景!
早期使用:break 标签名称; 结束指定的循环
在for循环嵌套中,给for循环的前面加上一个 "标签名称:"
wc:代表外层循环
nc:代表内层循环
wc:for(初始化语句;条件表达式;控制体语句){
nc:for(初始化语句2;条件表达式2;控制体语句2;){
//循环体;
//当达到我指定的条件,
break wc;//结束外层循环了
}
}
*/
class BreakDemo{
public static void main(String[] args){
//break; 在 switch 或 loop 外部中断
for(int x = 1 ; x <=10 ; x++){
if(x == 3){
break ;//结束,中断
}
System.out.println(x) ;
}
System.out.println("-----------------------------") ;
wc:for(int x = 0 ; x < 5 ; x ++){//行数 //x=0 ,0<5,1<5
nc:for(int y = 0 ; y <6 ; y ++){//列数 y=0,0<6,1<6,2<6,3<6
/*
if(x==3){//四行
//break wc;//结束外层循环
}
*/
if(y==3){
break nc;
}
System.out.print("*") ; //***
//***
}
System.out.println();//换行
}
}
}
continue
/*
跳转控制语句之continue
continue:继续执行(结束当前循环,立即进入下一次循环)
不能单独使用
看程序,补全代码
for(int x =1 ; x<=10;x++){
if(x%3==0){
//补全代码
//continue;
}
System.out.println("我爱高圆圆!") ;
}
//1)想在控制台输出7次 "我爱高圆圆" continue
//2)想在控制台输出13次 "我爱高圆圆" System.out.println("我爱高圆圆!") ;
*/
class ContinueDemo{
public static void main(String[] args){
//continue ; //continue 在 loop 外部 (仅仅在循环语句中使用)
for(int x = 1 ;x<=10;x++){
if(x==4){
//continue:继续执行(结束当前循环,立即进入下一次循环)
continue ;
}
System.out.println(x) ;//1235678910
}
}
}
return
/*
return :返回
很少单独去使用(不建议),后面一般都会有返回结果值;
return应用场景:
在Java中的方法(函数)中去使用,目的就是结束这个方法,并且还有返回结果;
return既然和方法有关系,Java中如何定义方法?
(什么是方法?)
*/
class ReturnDemo{
public static void main(String[] args){
//for循环
System.out.println("程序开始了") ;
for(int x = 1 ; x <= 10 ;x ++){
if(x ==3){
System.out.println("进入if了...") ;
//break ;//结束,中断的意思
//continue ;//结束当期循环,继续进入下一次循环
return ; //结束方法了
}
System.out.println("x的值是:"+x) ;
}
System.out.println("over....") ;
}
}
方法
/*
什么是Java中的方法(函数)?
方法:就是一个代码块{},给{}起一个名字(方法名),然后方法中逻辑书写(根据你的实际需求)
以后见到同样一个功能代码块,直接调用方法名即可!
举例:
植物大战僵尸游戏---每一个关卡都有一个豌豆芽发射炮弹这个动作
,这动作,可能需要100行代码,每一个关卡,都需要书写100行代码,所以
干脆给100行代码---{}包裹起来,给它单独起一个名字,以后见到这种"豌豆芽发射炮弹这个动作"
直接调用这个"方法名",代码复用性就提高了!
Java中定义方法的格式:
1)有返回值类型的方法的定义
public static 返回值类型 方法名(形式参数类型1 参数名1,形式参数类型2 参数名2...){
//完成方法的逻辑
return 结果;
}
解释上面这个格式
前面固定public static
返回值类型:也就是数据类型(现在研究的基本数类型)
方法名:就是满足标识符的命名规则:见名知意 (小驼峰命名法)
形式参数类型:也是数据类型(目前:基本数据类型)
参数名:就是变量名
有返回值类型的方法如何调用呢?
1)单独调用 ---方法名(实际参数列表) ; (有返回类型的方法不能使用)
2)输出调用 ---System.out.println(方法名(实际参数列表)) ;
输出调用:可以,写死了,如果相对结果值在进行操作,就不能用了
3)赋值调用:(推荐)
有返回值类型的方法定义以及调用
方法调用流程(图片)
需求: 自定义一个方法, 求两个数据之和
*/
class FunctionDemo{
//main方法不是我们定义,jvm可以调用的固定格式
public static void main(String[] args){
/*
int a = 10 ;
int b = 20 ;
int result = a +b ;
*/
//不能将所有的代码都房子main方法中操作
//调用下面的sum方法
//单独调用(不行)
//sum(10,20) ;//实际参数
//输出调用:可以,写死了,如果相对结果值在进行操作,就不能用了
//实际参数
int x = 10;
int y = 20 ;
//System.out.println(sum(x,y)) ;
//赋值调用:(推荐)
int result = sum(x,y) ;
System.out.println("两个数据之和是:"+result) ;
}
/*
public static 返回值类型 方法名(形式参数类型1 参数名1,形式参数类型2 参数名2...){
//完成方法的逻辑
return 结果;
}
*/
//定义一个求两个数据之和的方法(没有提示类型:默认int)
/*
两个明确:
1)明确返回值类型: int
2)明确形式参数类型以及形式参数的个数
int类型,2个
*/
public static int sum(int a ,int b){//a,b需要数据值
//a+b的结果
//定义一个结果变量
int c = a+b ;
return c ;
}
}
注意事项
/*
在Java中有返回值类型的方法的定义以及调用格式中注意事项:
1)方法和方法平级关系,不能在一个方法中去定义另一个方法!
2)定义方法的返回值类型和main方法中调用方法的时候,接收结果类型不匹配!
3)Java是强类型语言,在定义的方法时候,
形式参数名前面必须有参数类型
4) 必须有return语句,没有就会编译报错!
5)定义方法的时候,有{号地方不能有分号;有分号;,不能有{左大括号
*/
class FunctionDemo2{
public static void main(String[] args){
//定义两个数据求和的方法
/*
//方法和方法平级关系,不能在一个方法中去定义另一个方法!
public static int sum(int a,int b){
}*/
//赋值调用
//接收也必须为int
//boolean result = sum(10,20) ;
int result = sum(10,20) ;
System.out.println(result) ;
}
//两个数据求和,返回是int
public static int sum(int a,int b){
//public static int sum(int a,int b);{ 没有意义这个方法,;代表语句结束!
// public static int sum( a,b){//形式参数名前面必须有参数类型
return a + b ;
}
}
/*
定义格式
public static 返回值类型 方法名(形式参数类型1 参数名1,
形式参数类型2 参数名2...){
//完成方法的逻辑
return 结果;
}
1)键盘录入两个数据,定义一个方法,比较两个数据是否相等
2)键盘录入三个数据,定义一个方法,比较三个数据的最大值
3)键盘录入两个数据,定义一个方法,比较两个数据中最小值
*/
//导包
import java.util.Scanner ;
class FunctionTest{
public static void main(String[] args){
//1)键盘录入两个数据,定义一个方法,比较两个数据是否相等
//创建键盘录入对象
Scanner sc = new Scanner(System.in) ;
//提示并录入数据
System.out.println("请您输入第一个数据:") ;
int firtNum = sc.nextInt();
System.out.println("请您输入第二个数据:") ;
int secNum = sc.nextInt();
//调用比较两个数据是否相等的方法
boolean result = compare(firtNum,secNum) ;//实际参数
System.out.println(result) ;
System.out.println("------------------------------------------") ;
//键盘录入三个数据,定义一个方法,比较三个数据的最大值
//提示并录入数据
System.out.println("请您输入第一个数据:") ;
int a = sc.nextInt();
System.out.println("请您输入第二个数据:") ;
int b = sc.nextInt();
System.out.println("请您输入第三个数据:") ;
int c = sc.nextInt();
//调用方法
int max = getMax(a,b,c);
System.out.println("三个数据最大值:"+max);
}
/*
定义一个方法:求三个数据中的最大值
两个明确
明确返回值类型:int
明确参数类型以及参数个数
int,3个
*/
public static int getMax(int a,int b,int c){
//三元/if...else...
//定义max
int max ;
if(a>b){
if(a>c){
max = a;
}else{
max = c;
}
}else{
if(b>c){
max = b ;
}else{
max = c ;
}
}
return max ;
}
/*
定义方法:
两个明确:
1)明确返回值类型:boolean
2)明确参数类型以及参数个数:
int类型 2个
*/
public static boolean compare(int a,int b){
//三元/if..else...
//完成的逻辑
if(a==b){
return true ;
}else{
return false ;
}
//boolean flag = (a==b)?true:false ;
//return flag ;
//return a==b;
}
}
键盘录入字符串
/*
键盘录入数据的时候,先录入int,在使用nextLine()录入字符串,出现问题:
这个字符串值没有录入,就直接输出了;
原因:
Scanner类的它的nextLine()功能,"录入一行字符串"
录入int类型,回车才算第一个数据录入完毕,"回车"这个本身换行了,导致第二个数据没有!
解决方案:
1)方案1:必须要使用Scanner提供的nextLine()录入字符串,在录入这个字符串之前
重新创建新的键盘录入对象(文本扫描器)
2)方案2:不使用Scanner提供的nextLine(),另一种功能public String next():直接录入字符串
*/
//导包
import java.util.Scanner ;
class Demo{
public static void main(String[] args){
//创建键盘录入对象
Scanner sc = new Scanner(System.in) ;
//先录入两个int
//int a = sc.nextInt() ;
//int b = sc.nextInt() ;
//先录入String,在录入int
//录入String---jdk提供类:Scanner:官方用法 nextLine()
//String a= sc.nextLine() ;
//int b = sc.nextInt();
//先录入int,在录入字符串
int a = sc.nextInt() ;
//方案1:重新创建一个新的文本扫描器
//Scanner sc2 = new Scanner(System.in) ;
//String b = sc2.nextLine() ;
//方案2:next()
String b = sc.next();
System.out.println("a:"+a+",b:"+b) ;
}
}
没有返回值类型的方法定义以及调用
/*
没有返回值类型的定义格式:
按照正常方法定义(遵循有返回值类型的格式)
public static 返回值类型 方法名(形式参数类型1 参数名1,参数类型2 参数名2...){
方法逻辑体...
return 结果;
}
有些需求,是直接要求将内容直接打印控制台,没有具体返回值,Java规定,
当方法没有具体返回值的时候,需要使用"void"充当这个 "返回值类型"这个格式,
没有返回值类型的方法体中{}里面,就应该直接打印或者完成一些其他业务(数据交互)...
没有具体返回值类型的方法的定义格式:(没有return语句)
public static void 方法名(参数类型1 参数名1,参数类型2 参数名2...){
//完成方法体逻辑
//输出内容....
}
调用方法:
1)赋值调用和输出调用 都使用不了
2)推荐:单独调用
需求:使用方法来完成打印4行5列的*形
*****
*****
*****
*****
*/
class FunctionDemo{
public static void main(String[] args){
//没有使用方法
for(int x = 0 ; x < 4 ; x++){
for(int y = 0 ; y < 5 ; y ++){
System.out.print("*") ;
}
System.out.println() ;
}
System.out.println("-----------使用方法改进上面的代码---------------") ;
//调用没有具体返回值的方法
//赋值调用
//void v = printStar(5,6); //void不是数据类型 (非法的表达式开始)
//输出调用 (错误使用)
//System.out.println(printStar(5,6)) ;
//单独调用
printStar(5,6) ;
}
//定义一个打印4行5列*的方法
/*
两个明确
1)明确返回值类型: void
2)明确参数类型以及参数个数
int类型,行数和列数2个参数
*/
public static void printStar(int m,int n){//m行数,n列数
for(int x = 0 ; x < m ; x++){
for(int y = 0 ; y < n ; y ++){
System.out.print("*") ;
}
System.out.println() ;
}
}
}
重载
/*
需求:求多个数据之和!(使用方法完成)
分析:
没有明确说几个数据
求两个数据,求三个/求四个数据
分别去定义三个方法
分别测试,没问题---要遵循 定义方法满足标识符的命名规则,做到"见名知意"
Java中规定:如果方法名相同,参数列表不同,与返回值无关---
这一系列的方法都称为"方法重载OverLoad"
参数列表不同
1)参数个数不同
2)参数类型不同
3)考虑参数类型的先后顺序
public static int sum(double a,int b){}
public static int sum(int a,double b){}
方法重载的意义:
重载的意义,为了提高这个方法的使用率,让这个方法在任何场景下都能用
同一个方法,可以传递不同类型!
jdk提供大部分的工具:针对数学运算操作java.lang.Math--- 很多重载
求绝对值
abs(double a)
abs(float a)
abs(int a)...
以下哪些方法是重载方法
public static int open(int a,int b){}
public static int OPEN(int a,double b){}
public static double open(double a,double b){}
public static float open(double a,int b,double c)
public static int opEN(int a,int b)
public static int OPEN(double a,int b)
*/
class FunctionDemo2{
public static void main(String[] args){
//调用
int result = sum(10,20) ;
System.out.println(result) ;
//int result2 = sum2(10,20,30) ;
int result2 = sum(10,20,30) ;
System.out.println(result2) ;
//int result3 = sum3(10,20,30,40) ;
int result3 = sum(10,20,30,40) ;
System.out.println(result3) ;
double result4 = sum(3.14,12.56) ;
System.out.println(result4) ;
}
public static double sum(double a,double b){
return a + b ;
}
/*
定义求两个数据之和的方法
两个明确
明确返回值类型:int
明确参数类型以及参数个数:
int,2个参数
*/
public static int sum(int a,int b){
return a + b ;
}
//定义一个求三个数据之和的方法
//public static int sum2(int a,int b ,int c){
public static int sum(int a,int b ,int c){
return a + b + c ;
}
//定义一个求四个数据之和的方法
//public static int sum3(int a,int b,int c,int d){
public static int sum(int a,int b,int c,int d){
return a + b + c + d ;
}
}
测试
/*
没有返回值类型的定义格式
public static void 方法名(参数类型1 参数名1,参数类型2 参数名2...){
//完成方法体逻辑
//输出内容....
}
*/
//需求:
//1)键盘录入一个数据n,打印nn乘法表(使用方法完成)
//2)键盘录入行数,和列数,打印对应的*行 (举例:4行5列的*)(使用方法完成)
//导包
import java.util.Scanner ;
class FunctionTest{
public static void main(String[] args){
//创建键盘录入对象
Scanner sc = new Scanner(System.in) ;
//提示并录入数据
System.out.println("请您输入一个数据n:") ;
int n = sc.nextInt();
//调用打印nn乘法表方法
printNN(n) ;
System.out.println("-----------------------------------") ;
//提示并录入数据
System.out.println("请输入一个行数:") ;
int i = sc.nextInt() ;
System.out.println("请输入一个列数:") ;
int j = sc.nextInt() ;
//调用方法
printIJ(i,j) ;
}
//定义一个打印i行,j列的方法
public static void printIJ(int i,int j){//i行数,j列数
for(int x = 0 ; x <i ; x++){
for(int y = 0 ; y < j ; y++){
System.out.print("*") ;
}
System.out.println() ;
}
}
/*
定义一个打印nn乘法表的方法
两个明确:
1)明确返回值类型:没有具体返回值 void
2)明确参数类型以及参数个数
int类型,一个参数
*/
public static void printNN(int n){
for(int x = 1 ; x<=n ; x++){
//列数y 和x行数有关系
for(int y = 1; y <=x ; y++){
System.out.print(x+"*"+y+"="+(y*x)+"\t") ;
}
System.out.println() ;
}
}
}
方法形式参数是基本数据类型
//考点:形式参数问题: (现在研究基本类数据类型)---
// jvm内存结构(栈,堆,方法区,本地方法区,pc寄存器(程序计数器)
class Demo{
public static void main(String[] args){
int a = 20 ;
System.out.println(a) ;//20
change(a) ;
System.out.println(a) ;//40 //20
}
public static void change(int a){
a = 40 ;
System.out.println(a) ;
}
}
插图
数组
/*
给员工发工资,有60个员工,按照目前说,只能定义60个变量,
分别去赋值,显的非常麻烦;
Java提供一种容器--->可以存储同一种类型的元素--->数组
数组:必须满足这些元素数据类型必须是同一种类型!
数组定义以及初始化
定义格式:
1)数据类型[] 数组名称;
2)数据类型 数组名称[] ;
举例:
int[] arr; 定义一个int类型的数组arr
int arr[] ; 定义一个int类型的arr数组
初始化:
1)动态初始化
给定数组长度,系统(jvm)默认分配数组元素内容;
格式:
数据类型[] 数组名称 = new 数据类型[数组长度] ;
数据类型 数组名称[] = new 数据类型[数组长度] ;
举例:
int[] arr = new int[3] ;
在数组如何确定元素的内容
数组名称[索引值(角标值)]:从0开始
2)静态初始化
*/
class ArrayDemo{
public static void main(String[] args){
int a = 10 ;//基本类型
System.out.println(a) ;
//创建一个数组:动态初始化
//数据类型[] 数组名称 = new 数据类型[数组长度] ;
int[] arr = new int[3] ;
//=左边
//int[] :定义一个int类型的数组
//arr:变量名(满足标识符的规则) arr变量(数组名称arr)
//=右边
//new:在堆内存中开辟空间(创建对象)
//int[]:在堆内存中创建一个int类型的数组
//3:在堆内存中创建数组,长度为3
System.out.println(arr) ;//[I@6d06d69c :理解为"地址值"
//[:表示是一个数组
//@:地址值标记
//6dxxx 具体十六进制转
//在数组如何确定元素的内容
//数组名称[索引值(角标值)]:从0开始
System.out.println(arr[0]) ;//第一个
System.out.println(arr[1]) ;//第二个
System.out.println(arr[2]) ;//第三个
System.out.println("----------------------------") ;
//显示赋值
arr[0] = 10 ;
arr[1] = 30 ;
arr[2] = 20 ;
System.out.println(arr) ;
System.out.println(arr[0]) ;//第一个
System.out.println(arr[1]) ;//第二个
System.out.println(arr[2]) ;//第三个
}
}
/*
创建两个数组对象的内存图解
分别创建两个数组,分别输出他们的数组名称以及元素
再次两个数组中的部分元素进行显示初始化,再次输出数组名称以及元素;
*/
class ArrayDemo2{
public static void main(String[] args){
//创建两个数组
int[] arr = new int[2] ;
int[] arr2 = new int[3] ;
System.out.println(arr) ;
System.out.println(arr2) ;
System.out.println(arr[0]) ;//0
System.out.println(arr[1]) ;//0
System.out.println(arr2[0]) ;//0
System.out.println(arr2[1]) ;//0
System.out.println(arr2[2]) ;//0
System.out.println("--------------------------------------") ;
arr[1] = 25 ;
arr2[0] = 15 ;
arr2[2] = 45 ;
System.out.println(arr) ;
System.out.println(arr2) ;
System.out.println(arr[0]) ;//0
System.out.println(arr[1]) ;//25
System.out.println(arr2[0]) ;//15
System.out.println(arr2[1]) ;//0
System.out.println(arr2[2]) ;//45
//定义第三个数组,将第一个数组名称赋值给它
int[] arr3 = arr ;
arr3[0] = 10 ;
arr3[1] = 67 ;
System.out.println(arr) ;
System.out.println(arr2) ;
//打印:使用第一个数组arr[角标]
System.out.println(arr[0]) ;
System.out.println(arr[1]) ;
}
}
/*
数组的第二种格式进行初始化:
静态初始化:
给定数组元素,长度由系统给定
原本格式:
数据类型[] 数组名称 = new 数据类型[]{元素1,元素2,元素3....} ;
数据类型 数组名称[] = new 数据类型[]{元素1,元素2,元素3....} ;
简写格式
数据类型[] 数组名称 ={元素1,元素2,元素3....} ;
数据类型 数组名称[] = {元素1,元素2,元素3....} ;
举例:
int[] arr = {1,2,3} ;
arr[0] = 1 ;
arr[1] = 2 ;
arr[2] = 3 ;
注意事项:
不能既动态初始化,又静态初始化(动静结合)
int[] arr = new int[3]{1,2,3} ;//错误
*/
class ArrayDemo3{
public static void main(String[] args){
//创建一个数组,静态初始化
//int[] arr =new int[]{11,22,33,44} ;
int[] arr ={11,22,33,44} ;
System.out.println(arr) ; //地址值
System.out.println(arr[0]) ;
System.out.println(arr[1]) ;
System.out.println(arr[2]) ;
System.out.println(arr[3]) ;
//System.out.println(arr[4]) ;
//java.lang.ArrayIndexOutOfBoundsException
arr = null ; //给数组引用类型,重新赋值null(引用类型默认值null)
//System.out.println(arr[1]) ;//java.lang.NullPointerException
if(arr!=null){
System.out.println(arr[1]) ;
}else{
System.out.println("对不起,该对象为null,没有地址值了") ;
}
}
}
数组的应用
/*
数组的应用:
数组遍历
将数组的元素一一输出打印
举例:
数组静态初始化了,
int[] arr = {67,53,13,21,87};
需求:
将上面的数组最终以下面格式出现:
[元素1, 元素2, 元素3, .....]
*/
class ArrayTest{
public static void main(String[] args){
//已知数组静态初始化
int[] arr = {67,53,13,21,87};
//遍历数组获取每一个元素,打印在dos控制台上
//访问数组:数组名称[索引值]
//原始做法
System.out.println(arr[0]) ;
System.out.println(arr[1]) ;
System.out.println(arr[2]) ;
System.out.println(arr[3]) ;
System.out.println(arr[4]) ;
System.out.println("---------------------") ;
//优化上面代码
for(int x = 0 ; x < 5 ; x++){//x:角标值
System.out.println(arr[x]) ;
}
//举例:如果这个元素很多,数循环次数,数组提供数据length(数组长度)
//数组名称.length:获取数组长度
//System.out.println(arr.length) ;
System.out.println("---------------------") ;
//继续优化
for(int x = 0 ; x <arr.length; x++){
System.out.println(arr[x]) ;
}
System.out.println("----------方法优化-----------") ;
//调用方法完成数组遍历
printArray(arr) ;//实际参数--->int[] arr = {67,53,13,21,87};
System.out.println("----------最终版优化-----------") ;
//[元素1, 元素2, 元素3, .....最后一个元素] ---使用方法
printArray2(arr) ;
}
public static void printArray2(int[] array){
//1)先输出左中括号
System.out.print("[") ;
//2)遍历array中所有元素
for(int x = 0 ; x < array.length;x++){
//判断
//如果当前角标x 取到了最大索引值,应该将最后一个元素并且,拼接一个右中括号
if(x==array.length-1){
//换行并输出
System.out.println(array[x]+"]") ;
}else{
//中间的元素: 元素1, 元素2, 元素3, ... (同一行上)
System.out.print(array[x]+", ") ;
}
}
}
/*
定义一个遍历数组的方法
两个明确:
1)明确返回值类型 void
2)明确参数类型以及参数个数
引用类型数组,1个
*/
public static void printArray(int[] array){//形式参数:引用类型---> 数组
for(int x = 0 ; x < array.length;x++){
System.out.println(array[x]) ;
}
}
}
/*
数组的最值问题:
要么最大值/要么最小值
需求:
已知数组,静态初始化,获取这个数组中的最大值!
*/
class ArrayTest2{
public static void main(String[] args){
//已知数组,静态初始化
int[] arr = {24,69,57,45,13} ;
//1)定义一个参照物
int max= arr[0] ; //假设第一个元素是最大值
//2)从角标1开始遍历后面的元素
for(int x = 1;x < arr.length ; x++){
//arr[1],arr[2]....
//判断
//使用后面的所有元素依次和max进行比较
if(arr[x] > max){
//将arr[x]赋值给max
max = arr[x] ;
}
}
System.out.println("最大值是:"+max) ;
System.out.println("--------------------------------") ;
//使用方法来完成
int max2 = getArrayMax(arr) ;
System.out.println("最大值是:"+max2) ;
}
/*
定义一个方法:获取数组中最大值的方法
两个明确:
明确返回值类型:int
明确参数类型以及参数个数: 数组,1个数组
*/
public static int getArrayMax(int[] arr){
//定义一个参照物
int max = arr[0] ;
//遍历其他元素
for(int x = 1 ; x < arr.length ; x++){
//使用arr[x]和max进行对比
if(arr[x]> max){
//改变max的值
max = arr[x] ;
}
}
return max ;
}
}
测试1
/*
百钱买百鸡:
公鸡5文钱一只,
母鸡3文钱一只,小鸡1文钱3只,如何使用100文钱买到一百只鸡
分析:
穷举法
100文钱可以买多少只公鸡
100文件可以买多少只母鸡
可以x:代表公鸡 ----20只
y:代表母鸡的数量----33只
z:代表小鸡的数量
*/
class Test{
public static void main(String[] args){
//定义三个变量
//分别代码公鸡,母鸡,小鸡的数量
//x:公鸡
//y:母鸡
int z = 0 ;
for(int x = 0 ; x <= 20 ; x++){
//公鸡的数量
for(int y = 0 ; y <= 33; y ++){
//母鸡的数量
//小鸡的数量
z = 100 - x - y ;
//满足条件:100文件同时公鸡,母鸡,小鸡
if((5*x+3*y+z/3)==100 && (z%3==0)){
System.out.println(
"公鸡的数量是:"+x+"只,母鸡的数量是:"+y+",小鸡的数量是:"+z) ;
}
}
}
}
}
测试2
//(while循环)输入一个整数,
//计算它各位上数字的和。(注意:是任意位的整数)使用方法完成
//导包
import java.util.Scanner ;
class Test2{
public static void main(String[] args){
//创建键盘录入对象
Scanner sc = new Scanner(System.in) ;
//提示并录入数据
System.out.println("请你输入一个数据n:") ;
int n = sc.nextInt() ;
//调用方法
int result = getSum(n) ; //实际参数
System.out.println("任意位的整数的各个位和是:"+result) ;
}
/*
定义一个方法:两个明确
明确返回值类型:int
明确参数类型以及参数个数 :int,1个
*/
public static int getSum(int n){
//循环不断再去:获取低位--->求和,
//去除低位
//定义一个结果变量
int sum = 0 ;
while(n!=0){
sum = sum +n%10; //获取低位
n = n / 10 ; //去除低位
}
return sum ;
}
}
测试3
/*
猜数字游戏,1-100之间数据,使用方法完成(预习没有返回值类型的方法地定义以及调用)
提示:因为最终要提示"大了还是小了,还是恭喜您,猜对了,输出在控制台上"
*/
import java.util.Scanner ;
class Test3{
public static void main(String[] args){
//单独调用
guessNumberGame() ;
}
/*
定义一个方法:猜数字游戏的方法---不断的循环录入数据
两个明确:
1)明确返回值类型:void
2)明确参数类型以及参数个数
没有参数,直接产生随机数
*/
public static void guessNumberGame(){
//1)产生随机数
int number =(int)(Math.random()*100+1);//1-100随机数
//定义一个统计变量
int count = 0 ;
while(true){
count ++ ;
//2)创建键盘录入对象
Scanner sc = new Scanner(System.in) ;
//提示并录入数据
System.out.println("请输入你要猜的数字:") ;
int guessNumber = sc.nextInt() ;
if(guessNumber>number){
System.out.println("你要猜的数字"+guessNumber+"大了") ;
}else if(guessNumber<number){
System.out.println("你要猜的数字"+guessNumber+"小了") ;
}else{
System.out.println("恭喜您,"+count+"次猜对了!") ;
break ;
}
}
}
}
数组_以及高级排序算法
插图
/*
数组的元素查询表法:
需求:
键盘录入一个数据,输出对应的星期值
分析:
定义一个字符串数组
数据类型[] 数组名称= {元素内容} ;
String[] strArray =
{"星期一","星期二","星期三","星期四","星期五","星期六","星期日"} ;
*/
import java.util.Scanner ;
class ArrayDemo{
public static void main(String[] args){
//创建键盘录入对象
Scanner sc = new Scanner(System.in) ;
//提示并录入数据
System.out.println("请输入一个数据(0-6):") ;
int weekValue = sc.nextInt() ;
//创建一个字符串数组
String[] strArray =
{"星期一","星期二","星期三","星期四","星期五","星期六","星期日"} ;
System.out.println("你要查询的是:"+strArray[weekValue]) ;
}
}
/*
数组的基本元素查找查询数组中元素第一次出现索引值
已知:
int[] arr = {25,67,13,66,89,76} ;
需求:查询13第一次出现的索引值;
(考虑:查询到了,返回角标;没有没有查询到,也需要返回!)
查询130
*/
class ArrayDemo2{
public static void main(String[] args){
//已知一个数组,静态初始化了
int[] arr = {25,67,13,66,89,76} ;
//调用
int index = getIndex(arr,13) ;
System.out.println("index值是:"+index) ;
int index2 = getIndex(arr,130) ;
System.out.println("index2值是:"+index2) ;
System.out.println("----------------------------------") ;
int index3 = getIndex2(arr,87) ;
System.out.println("index3:"+index3) ;
int index4 = getIndex2(arr,89) ;
System.out.println("index4:"+index4) ;
}
/*
方式2:假设思想
1)定义一个 int index = -1; 找不到
2)遍历arr数组,获取到每一个元素
2.1)判断 arr[x] == target,找到了
2.2)修改index的值(重新赋值) index = x ;
2.3)break;
3)循环一圈都没有找到,
rturn index ;
*/
public static int getIndex2(int[] arr,int target){
//定义一个index角标值
int index = -1 ;
//遍历数组
for(int x = 0 ; x < arr.length ; x++){
//获取到每一个元素
//判断 如果arr[x]就是target
if(arr[x] == target){
//重新给index赋值
index = x ;
break ;
}
}
return index ;
}
/*
定义一个在数组中查询指定元素的第一次出现的索引值
两个明确:
1)明确返回值类型:int
2)明确参数类型以及参数个数
int[]数组, int类型元素(指定的元素),2个 参数
*/
//方式1:
public static int getIndex(int[] arr,int target){
//1)遍历数组,获取到每一个元素
for(int x = 0 ; x < arr.length ; x++){
//判断
//如果target就是arr[x],两个值相等,即可返回x
if(arr[x] == target){//13
return x ;//找到了返回角标
}
}
//如果循环结束了,还没有找到,返回值
return -1 ;
}
}
冒泡排序
/*
数组高级排序算法之:冒泡排序
思想:
两两比较,将大的值往后方法,第一次比较完毕,最大值出现在最大索引处!
*/
class BubleSortArrayDemo{
public static void main(String[] args){
//已知一个数组,静态初始化
int[] arr = {24,69,87,54,14} ;
//排序前:
System.out.println("排序前:") ;
//先遍历
printArray(arr) ;
System.out.println("--------------------------------------------") ;
/*
//第一次比较
//将数组的中元素比较
//arr.length-1:为了防止角标
//arr.length-1-0:第一次有0个不比
for(int x = 0 ;x < arr.length-1-0; x++){
//逻辑
//如果前面的元素>后面元素,使用中间变量的方式进行交换
if(arr[x] > arr[x+1]){
int temp = arr[x] ;
arr[x] = arr[x+1] ;
arr[x+1] = temp ;
}
}
System.out.println("第一次比较完毕:") ;
printArray(arr) ;
System.out.println("---------------------------------------------") ;
//第二次比较
//arr.length-1:防止角标越界
//arr.length-1-1:第二次有一个不比(最大值已经出现了)
for(int x = 0 ; x < arr.length-1-1;x++){
if(arr[x] > arr[x+1]){
int temp = arr[x] ;
arr[x] = arr[x+1] ;
arr[x+1] = temp ;
}
}
System.out.println("第二次比较完毕:") ;
printArray(arr) ;
System.out.println("---------------------------------------------") ;
//第三次比较
//arr.length-1:防止角标越界
//arr.length-1-2:第三次有2个不比(最大值已经出现了)
for(int x = 0 ; x < arr.length-1-2;x++){
if(arr[x] > arr[x+1]){
int temp = arr[x] ;
arr[x] = arr[x+1] ;
arr[x+1] = temp ;
}
}
System.out.println("第三次比较完毕:") ;
printArray(arr) ;
System.out.println("---------------------------------------------") ;
//第四次比较:
//arr.length-1:防止角标越界
//arr.length-1-3:第四次有3个不比(最大值已经出现了)
for(int x = 0 ; x < arr.length-1-2;x++){
if(arr[x] > arr[x+1]){
int temp = arr[x] ;
arr[x] = arr[x+1] ;
arr[x+1] = temp ;
}
}
System.out.println("第四次比较完毕:") ;
printArray(arr) ;
*/
System.out.println("---------------------优化------------------------") ;
//比较的次数:arr.length-1次 :上面代码循环了这个次数
for(int x = 0 ; x < arr.length-1;x++){//比较的次数
//里面元素进行比较
//x=0:第一次有0个不比
//x=1:第二次有1个不比
//x=2:第三次有2个不比
//x=3:第四次有3个不比
for(int y = 0 ; y < arr.length-1-x;y++){//y数组角标
//如果前面的元素比较后面大
if(arr[y]> arr[y+1]){
int temp = arr[y] ;
arr[y] = arr[y+1] ;
arr[y+1] = temp ;
}
}
}
System.out.println("冒泡排序后:") ;
printArray(arr) ;
System.out.println("-----------------------使用方法优化----------------------") ;
//调用冒泡排序的方法
bubleSort(arr) ; //只是排序,没有输出
printArray(arr) ; //输出打印
}
/*
两个明确
1)明确返回值类型: void
2)明确参数类型以及参数个数:int[] ,1个参数
*/
public static void bubleSort(int[] arr){
for(int x = 0 ; x < arr.length-1;x++){//比较的次数
//里面元素进行比较
//x=0:第一次有0个不比
//x=1:第二次有1个不比
//x=2:第三次有2个不比
//x=3:第四次有3个不比
for(int y = 0 ; y < arr.length-1-x;y++){//y数组角标
//如果前面的元素比较后面大
if(arr[y]> arr[y+1]){
int temp = arr[y] ;
arr[y] = arr[y+1] ;
arr[y+1] = temp ;
}
}
}
}
public static void printArray(int[] arr){
//先输出左中 不换行
System.out.print("[") ;
//遍历数组
for(int x = 0 ; x < arr.length ; x++){
//判断
if(x==arr.length-1){
System.out.println(arr[x]+"]") ;
}else{
//中间元素
System.out.print(arr[x]+", ") ;
}
}
}
}
形式参数问题
/*
方法的形式参数如果是基本数据类型,形式参数的改变不影响实际参数
方法的形式参数如果是引用数据类型(数组,类,接口),形式参数的改变会直接影响实际参数
String类:字符串,它是一个特殊的引用类型,它作为形式参数传递,和基本类型作为形式参数效果一致!
*/
插图
//看程序,写结果
class ArgsDemo{
public static void main(String[] args){
int a = 10 ;
int b = 20 ;
System.out.println("a:"+a+",b:"+b) ;
changeValue(a,b) ;
System.out.println("a:"+a+",b:"+b) ;//a:10,b:20
System.out.println("--------------------------------") ;
int[] arr = {1,2,3,4,5} ;
System.out.println(arr[1]) ;
changeValue(arr) ;
System.out.println(arr[1]) ;
}
public static void changeValue(int a,int b){//形式参数基本类型
a = b ; //a = 20
b = a + b ;//b = 20 + 20 = 40
System.out.println("a:"+a+",b:"+b) ;//20,40
}
public static void changeValue(int[] arr){//形式参数:引用类型 数组,(实际参数传递是数组地址值)
for(int x= 0 ; x < arr.length; x++){
if(arr[x] % 2 ==0){
arr[x] *=2 ;//arr[x] = arr[x] *2 ;
}
}
}
}
/*
/*
方法的形式参数如果是基本数据类型,形式参数的改变不影响实际参数
String类:字符串,它是一个特殊的引用类型;
它作为形式参数传递,和基本类型作为形式参数效果一致!
*/
class ArgsDemo2{
public static void main(String[] args){
String s = "helloworld" ;
System.out.println(s) ;
changeValue(s) ;
System.out.println(s) ; //"helloword"
}
public static void changeValue(String str){//str=s="helloworld"
str += "JavaEE" ;//str = "helloworldJavaEE"
System.out.println(str) ;//"helloworldJavaEE"
}
}
面向对象的思想特点
面向对象_创建一个对象内存图解
面向对象_创建多个对象内存图解
面向对象的思想特点 -->基于面向过程
面向过程代表--->C语言
1)需求分析 --- 键盘录入三个数据,比较数据中最大值---->使用方法完成
2)定义方法---分析返回值/参数类型/有几个参数
3)返回结果
4)自己在main方法测试
最大特点:
自己始终执行者
举例:生活中的例子
面向过程
买电脑
看配置(喜欢的)---->去赛格电脑城--->砍价还价---->买回来电脑
洗衣服:
脏衣服---->找一个盆--->接水--->泡一泡---->搓一搓---->拧一拧----->晾衣服
买菜
去菜市场---->砍价/还价---->买菜回来
面向对象:
买电脑
看喜欢的配置---->找一个懂行的朋友---->买回来电脑
洗衣服:
脏衣服---->找一个全自动洗衣机---->晾衣服
买菜
找一个"对象"--->买菜回来
面向对象思想特点:
1)更符合生活中的思想行为习惯!
2)让复杂的事情简单化!
3)让我们从执行者变成指挥者!(角色变化)
面向对象设计理念/特征
不断去创建对象,指挥对象做事情!
//Scanner sc = new Scanner(System.in) ;
面向对象的特征:
封装
继承
多态
将大象装进冰箱 (赵本山说过这样一句话) 面向过程分析
//伪代码
//面向过程:
class Demo{
public static void main(String[] args){
open() ;
in();
close() ;
}
//分析:冰箱开的方法
public static void open(){
System.out.println("打开冰箱门") ;
}
//分析:将大象装进去的方法
public static void in(){
System.out.println("将大象装进冰箱") ;
}
//分析:将冰箱门关闭
public static void close(){
System.out.println("关闭冰箱门") ;
}
}
将大象装进冰箱(面对对象的方式分析)
//UML:名词提取法:分析:有几个名词---->使用"类"来定义,分析:这个类与哪些功能?
//大象---大象事物-----> class 大象类{}
//冰箱---冰箱事物---->class 冰箱类{}
//Demo类 测试类 (有main方法类)
//伪代码
class Demo{
public static void main(String[] args){
//使用Java面向对象中创建类对象的格式
//创建冰箱类对象
//使用冰箱类对象调用开门的方法 open() ;
//创建大象类对象
// 使用大象类对象调用in方法 in();
// 调用冰箱类的关门的方法 close() ;
}
}
//大象类--->进去的方法
class 大象类{
public static void in(){
System.out.println("大象进去了") ;
}
}
//冰箱类---->开/关
class 冰箱类{
public static void open(){
System.out.println("打开冰箱门") ;
}
public static void close(){
System.out.println("关闭冰箱门");
}
}
类和事物 / ---- 对象/具体事物
类: (是Java中最基本单元)
类是描述现实世界"事物"的一组"属性"和"行为"的集合!
类和事物: 一一对应,相辅相成!
一个事务------>定义一个类
举例:
学生事物 ----- >
学生事物 Java代码体现---- 定义一个 class Student{}
属性:年龄,姓名,身高.... 成员变量:位置 类中,方法外
行为:学习....
成员方法(去掉static):和方法定义方法格式一样
study():学习
事物:一个类型的总称---描述具体的事物 ----------
学生事物 ----->具体事物
属性:姓名,年龄,性别 张三,20,男
行为:学习 正在学习JavaEE
具体事物-----代码中体现--------->创建一个对象
创建对象的格式:
类名 对象名 = new 类名() ;
对象名.成员变量名 = 值; (跟成员变量类型一致);
对象名.方法名() ;调用方法,展示这个具体事物有什么功能
插图
举例
/*
有一个手机事物,手机事物有品牌,价格,手机颜色,手机内存,
手机可以打电话,发短信,玩游戏
定义一个手机类,在PhoneDemo测试类中进行测试
手机事物:
属性:品牌(String brand) ,价格(int price),颜色(String color),
内存(String memory)
行为:
打电话callPhone()
sendMsg()
playGame()
*/
class Phone{
//成员变量(属性)
String brand ; //品牌
int price ; //价格
String color ; //手机颜色
String memory ; //内存
//成员方法(非静态)
//打电话
public void callPhone(String toName) { //自己分析可以带参/无参,直接输出
System.out.println("使用手机给"+toName+"打电话了") ;
}
//发短信
public void sendMsg(){
System.out.println("使用这个"+brand+"可以发短信...") ;
}
//玩游戏
public void playGame(String gameName){
System.out.println("使用"+brand+"可以玩"+gameName) ;
}
}
//测试类
class PhoneDemo{
public static void main(String[] args){
//测试:
//创建一个具体的手机事物--创建对象
//类名 对象名 = new 类名() ;
Phone p = new Phone() ;
System.out.println(p.brand+"---"+p.price+"---"+p.color+"----"+p.memory) ;
//成员变量
p.brand = "华为mate40pro" ;
p.price = 12999;
p.color = "翡翠绿" ;
p.memory = "128G" ;
System.out.println(
"手机的品牌是:"+p.brand+",价格是:"+p.price+",机身颜色是:"+p.color+
",机身内存是:"+p.memory) ;
//成员方法 (行为)
p.callPhone("高圆圆") ;
p.sendMsg() ;
p.playGame("王者农药") ;
}
}
/*
使用Java代码描述一个学生事物
学生事物
属性:姓名,年龄,性别...
行为:学习
代码中体现出来----定义一个学生类
成员变量(类中,方法外)---就是描述现实世界事物的属性
成员方法(非静态):和定义方法格式一样,(去掉了static)
类:描述现实世界事物的一组属性和行为的集合!
*/
//学生类
class Student{
//成员变量(属性):类中,方法外
String name ; //姓名
int age ; //年龄
String gender ; //性别
//成员方法---->学生的行为:学习
public void study(){
System.out.println("good good study,day day up!!") ;
}
//带一个返回值String
public String playGame(String gameName){//玩的游戏名字 "csgo"
return "学习累了,可以玩会"+gameName ;
}
}
//测试类---main方法所在类的类
class StudentDemo{
public static void main(String[] args){
/*
具体事物-----代码中体现--------->创建一个对象
创建对象的格式:
类名 对象名 = new 类名() ;
对象名.成员变量名 = 值; (跟成员变量类型一致);
对象名.方法名() ;调用方法,展示这个具体事物有什么功能
//代码中:描述---这个学生的叫 "高圆圆"
//年龄 44
//性别 女
*/
//创建学生类对象
//类名 对象名 = new 类名() ;
Student s = new Student() ;
//成员变量赋值: name,age,gender
// 对象名.成员变量名 = 值;
s.name = "高圆圆" ;
s.age = 44 ;
s.gender = "女";
System.out.println("该学生的姓名是:"+s.name+",年龄是:"
+s.age+",性别是:"+s.gender) ;
//体现学生的行为(调用成员方法)
s.study();
//public String playGame(String gameName){
String result = s.playGame("csgo") ;
System.out.println(result) ;
}
}
举例2
/*
需求:
定义一个学生类,描述这个学生事物的属性:姓名,年龄
学生行为:学习
方便打印学生信息--->提供show()展示姓名和年龄
按上面的需求:进行测试
发现问题:如果在测试类中给年龄赋值非法数据,依然打印;
优化方案1:在学生类中定义一个成员方法(非静态),给年龄赋值(加入逻辑判断)
可以去解决,但是不调用这个方法,依然使用 对象名.age = 非法数据;
方案2:
java提供另一种技术
封装
将一个事物的属性私有化(对外界隐藏,private)--->保证数据的安全性
对外提供公共的成员访问方法:setXXX(传参)/getXXX(),来对成员属性进行操作!
以后在书写 事物(对应的类:手机类/用户类等等,只要描述它的属性和行为)
成员变量(属性)---->全部私有化!
*/
//定义一个学生类
class Student{
String name ; //姓名
private int age ; //年龄
//方便打印学生信息--->提供show()展示姓名和年龄
public void show(){
System.out.println("这个学生的姓名是:"+name+",年龄是:"+age) ;
}
//给年龄赋值的方法,并且加入逻辑判断
public void setAge(int a){ //a就是传入的年龄值
if(a<0 || a >150){
System.out.println("对不起,年龄非法!") ;
}else{
age = a ;//年龄赋值
}
}
}
//测试类
class StudentDemo{
public static void main(String[] args){
//创建一个学生对象(具体事物)
Student s = new Student() ;
//s.show() ;
s.name = "高圆圆" ;
s.age = 44 ;
s.show() ;
System.out.println("------------------------------------") ;
//在创建一个学生对象(新的具体事物)
Student s2 = new Student() ;
s2.name = "赵又廷" ;
//s2.age = -45 ;//外界类将它年龄赋值为非法数据!
//访问setAge()方法
//s2.setAge(-45) ;
//不调用自定义的给年龄赋值的方法,依然可以直接访问age,赋值一个非法数据
s2.age = -1 ;
s2.show() ;
}
}
封装
/*
需求:
定义一个学生类,描述这个学生事物的属性:姓名,年龄
学生行为:学习
方便打印学生信息--->提供show()展示姓名和年龄
按上面的需求:进行测试
发现问题:如果在测试类中给年龄赋值非法数据,依然打印;
优化方案1:在学生类中定义一个成员方法(非静态),给年龄赋值(加入逻辑判断)
可以去解决,但是不调用这个方法,依然使用 对象名.age = 非法数据;
方案2:
java提供另一种技术
封装
将一个事物的属性私有化(对外界隐藏,private)--->保证数据的安全性
对外提供公共的成员访问方法:setXXX(传参)/getXXX(),来对成员属性进行操作!
以后在书写 事物(对应的类:手机类/用户类等等,只要描述它的属性和行为)
成员变量(属性)---->全部私有化!
*/
//定义一个学生类
class Student{
String name ; //姓名
private int age ; //年龄
//方便打印学生信息--->提供show()展示姓名和年龄
public void show(){
System.out.println("这个学生的姓名是:"+name+",年龄是:"+age) ;
}
//给年龄赋值的方法,并且加入逻辑判断
public void setAge(int a){ //a就是传入的年龄值
if(a<0 || a >150){
System.out.println("对不起,年龄非法!") ;
}else{
age = a ;//年龄赋值
}
}
}
//测试类
class StudentDemo{
public static void main(String[] args){
//创建一个学生对象(具体事物)
Student s = new Student() ;
//s.show() ;
s.name = "高圆圆" ;
s.age = 44 ;
s.show() ;
System.out.println("------------------------------------") ;
//在创建一个学生对象(新的具体事物)
Student s2 = new Student() ;
s2.name = "赵又廷" ;
//s2.age = -45 ;//外界类将它年龄赋值为非法数据!
//访问setAge()方法
//s2.setAge(-45) ;
//不调用自定义的给年龄赋值的方法,依然可以直接访问age,赋值一个非法数据
s2.age = -1 ;
s2.show() ;
}
}
private关键字的特点
/*
private关键字的特点:
1)被private修饰的成员变量/成员方法(非静态),
只能在本类中访问,外界类不能访问!
2)虽然被私有修饰的成员变量以及成员方法(非静态)不能直接访问,但是
都可以间接的通过"public"公共访问访问!
*/
//定义Demo类
class Demo{
//成员变量:类中方法外
public int num = 10 ;
private int num2 = 20 ;
//定义一个公共的方法
public void show(){
System.out.println(num) ; //10
System.out.println(num2) ;//20
}
//其他成员方法
public void method(){
System.out.println("method Demo") ;
System.out.println("-------------------------") ;
function() ;
}
//私有的成员方法
private void function(){
System.out.println("function Demo") ;
}
}
//测试类
class PrivateDemo{
public static void main(String[] args){
//需求:访问Demo类中num和num2变量?
//创建Demo类对象
Demo d = new Demo() ;
System.out.println(d.num) ;
System.out.println("---------------------------") ;
//System.out.println(d.num2) ; //num2 在 Demo 中是 private 访问控制
//要访问num2这个变量:间接访问了
d.show() ;
d.method() ;
//d.function() ; // function() 在 Demo 中是 private 访问控制
}
}
/*
学生有姓名,年龄两个属性;
将姓名和年龄属性私有化,加入private,外界类不能直接使用(保证数据的安全性!)
定义一个学生类,然后在StudentTest中进行测试,成员变量赋值,打印成员信息;
封装:
一个事物的私有化(private),外界类不能直接使用,
对外需要通过公共的访问setXXX(参数)/getXXX()赋值(成员变量赋值)
获取值(获取成员变量的值)
*/
//学生类
class Student{
//属性私有化:全部private
private String name ; //姓名
private int age ; //年龄
//对外提供公共的访问方法setXXX()/getXXX():才能赋值/获取值
//1)给成员变量 name赋值
public void setName(String n){ //"高圆圆" n:局部变量
name = n ;
}
//获取成员变量name 的值
public String getName(){
return name ; //成员变量
}
//2)给成员变量 年龄age赋值
public void setAge(int a){//44 a:局部变量
age = a ; //44
}
public int getAge(){
return age ;
}
//成员方法:学习
public void study(){
System.out.println(name+"正在学习JavaSE") ;
}
}
//学生类的测试类
class StudentTest{
public static void main(String[] args){
//类名 对象名 = new 类名() ; //创建一个学生
Student s = new Student() ;
//对象名.成员变量 = 赋值;
//s.name = "高圆圆" ;//name 在 Student 中是 private 访问控制
//访问setXXX(xxx)/getXXX()
s.setName("高圆圆") ;
s.setAge(44) ;
System.out.println("该学生的姓名是:"+s.getName()+
",年龄是:"+s.getAge()) ;
//其他成员方法
s.study() ;
}
}
一个标准类_加入private和this
/*
学生有姓名,年龄两个属性;
将姓名和年龄属性私有化,加入private,外界类不能直接使用(保证数据的安全性!)
定义一个学生类,然后在StudentTest中进行测试,成员变量赋值,打印成员信息;
按需上面的测试:
通过setXXX(xx)给成员变量赋值,问题:变量并没有"见名知意"
给成员变量name/age进行赋值,局部变量名称也是name,age;
优化之后:成员变量 姓名name ,年龄age 都赋值不了
原因:局部变量名称 和成员变量名称一致,导致出现的问题;
Java提供了一个关键字:(局部变量名称隐藏了成员变量名称)this--->
代表当前类的对象的地址值引用!
this.成员变量名 = 局部变量名;
*/
//学生类
class Student{
//属性私有化:全部private
private String name ; //姓名
private int age ; //年龄
//对外提供公共的访问方法setXXX()/getXXX():才能赋值/获取值
//1)给成员变量 name赋值
//public void setName(String n){ //"高圆圆" n:局部变量
//name = n ;
//}
//优化
public void setName(String name){//"高圆圆"
//name = name ;错误的
this.name = name ;
}
//获取成员变量name 的值
public String getName(){
return name ; //成员变量
//return this.name ; //this可以省略
}
//2)给成员变量 年龄age赋值
/*
public void setAge(int a){//44 a:局部变量
age = a ; //44
}
*/
//优化
public void setAge(int age){
//age = age ;//错误的
this.age = age ;
}
public int getAge(){
//return this.age ;//this可以省略
return age ;
}
//成员方法:学习
public void study(){
System.out.println(name+"正在学习JavaSE") ;
}
}
//测试类
class StudentTest{
public static void main(String[] args){
//测试学生类
Student s = new Student() ;
s.setName("高圆圆") ;
s.setAge(44) ;
System.out.println(s.getName()+"---"+s.getAge()) ;
}
}
/*
手机类:
品牌brand,价格price,颜色color--->属性加入私有修饰!
打电话callPhone(),发短信sendMsg()
在PhoneTest中进行 手机类的测试,给属性赋值,并且调用成员方法,打印信息!
(加入this:局部变量给成员变量赋值,局部变量--见名知意)
*/
//定义一个手机类
class Phone{
//成员变量
private String brand ;
private int price ;
private String color ;
//setXXX(xx)赋值
public void setBrand(String brand){ //局部变量
this.brand = brand ;
}
public void setPrice(int price){
this.price = price ;
}
public void setColor(String color){
this.color = color ;
}
//getXXX()获取值
public String getBrand(){
return brand ;
}
public int getPrice(){
return price ;
}
public String getColor(){
return color ;
}
}
//测试类
class PhoneTest{
public static void main(String[] args){
//使用 类 对象名 = new 类名() ;
Phone p = new Phone() ;
p.setBrand("华为p40") ;
p.setPrice(4599) ;
p.setColor("翡翠绿") ;
System.out.println(p.getBrand()+"---"+p.getPrice()+"---"+
p.getColor()) ;
}
}
局部变量和成员变量的区别
/*
面试题:(理解并去识记)
局部变量和成员变量的区别?
区别:
1)类中的书写位置不同
成员变量:在类中,方法外
局部变量:在方法定义中或者方法声明上
2)jvm内存位置不同
成员变量:在堆内存中
局部变量:在栈内存中
3)生命周期不同:
成员变量:随着对象的创建而存在,随着对象的创建完毕并且使用完
等待垃圾回收器回收(不会立即回收)而消失!
局部变量:随着方法调用而存在,随着方法调用结束而消失
4)初始化值不同:
成员变量:存在系统默认初始化,也可以显示初始化
局部变量:总之:在使用局部变量之前,必须赋值,不赋值不行!
*/
//定义一个类Variable
class Variable{
//成员变量
int num ; //系统默认初始化就是0
public void show(String y){ //y
//int x = 100 ; //x 局部变量
int x ;
x = 100 ;
System.out.println(x+y) ;
}
}
//测试类
class VariableDemo{
public static void main(String[] args){
//访问show方法
//创建Variable类对象
Variable v = new Variable() ;
System.out.println(v.num) ;
v.num = 100 ;
System.out.println(v.num) ;
v.show("hello") ;
}
}
构造方法
/*
一个类的成员:
成员变量
成员方法(非静态)
构造方法:
什么是构造方法?
1)方法名和类名一致
2)没有具体返回值类型
3)连void都没有
构造方法是可以重载!
构造方法的作用:
给类的成员进行数据初始化!
注意事项:
1)一个类中,如果没有任何构造方法,那么系统(jvm)自动会给我们提供无参构造方法!
2)一个类中,只提供有参构造方法,那么系统不会无参构造方法,此时,建议我们永远给出无参构造方法!否则,就出现问题!
创建对象的时候固定格式:
类名 对象名 = new 类名() ;
*/
class Student{//学生类
//带两个参数
private String name ;//姓名
private int age ; //年龄
/*
1)方法名和类名一致
2)没有具体返回值类型
3)连void都没有
*/
//无参构造方法
/*
public Student(){
System.out.println("这是Student的无参构造方法") ;
}
*/
//带有一个String类型的参数的构造方法
public Student(String name){ //姓名:局部变量---成员变量
System.out.println("这是一个带有String参数的构造方法") ;
this.name = name ;
}
//带有String类型,以及int类型的构造方法
public Student(String name,int age){
System.out.println("这是一个带两个参数的构造方法") ;
}
}
//测试类
class ConstructorDemo{
public static void main(String[] args){
//创建一个学生类对象
Student s = new Student();
System.out.println(s) ;//堆内存地址
System.out.println("-------------------") ;
Student s2 = new Student("高圆圆") ;
System.out.println(s2) ;//新的堆内存空间
System.out.println("-------------------") ;
//在创建第三个学生对象
Student s3 = new Student("高圆圆",44) ;
System.out.println(s3) ;
}
}
举例
/*
手机类:
品牌brand,价格price,颜色color--->属性加入私有修饰!
打电话callPhone(),发短信sendMsg()
在PhoneTest中进行 手机类的测试,给属性赋值,并且调用成员方法,打印信息!
(加入this:局部变量给成员变量赋值,局部变量--见名知意)
一个标准类的写法:
类的成员
成员变量:属性私有化
成员方法:公共访问setXXX(xx)/getXXX()
构造方法:无参构造方法:永远给出
有参构造方法
*/
//定义一个手机类
class Phone{
//成员变量
private String brand ;
private int price ;
private String color ;
//无参构造方法
public Phone(){
}
//有参构造方法
public Phone(String brand,int price ,String color){ //"Iphone14",12999,"土豪金"
//局部变量给成员变量赋值
this.brand = brand ;
this.price = price ;
this.color = color ;
}
//setXXX(xx)赋值
public void setBrand(String brand){ //局部变量
this.brand = brand ;
}
public void setPrice(int price){
this.price = price ;
}
public void setColor(String color){
this.color = color ;
}
//getXXX()获取值
public String getBrand(){
return brand ;
}
public int getPrice(){
return price ;
}
public String getColor(){
return color ;
}
}
//测试类
class PhoneTest{
public static void main(String[] args){
//使用 类 对象名 = new 类名() ;
//无参构造方法+setXXX(xx)+getXXX()
Phone p = new Phone() ;
p.setBrand("华为p40") ;
p.setPrice(4599) ;
p.setColor("翡翠绿") ;
System.out.println(p.getBrand()+"---"+p.getPrice()+"---"+
p.getColor()) ;
System.out.println("-----------------------") ;
//方式2:手机类的有参构造方法+getXXX()
/*
public Phone(String brand,int price ,String color){
//局部变量给成员变量赋值
this.brand = brand ;
this.price = price ;
this.color = color ;
}
*/
Phone p2 = new Phone("Iphone14",12999,"土豪金") ;
System.out.println(p2.getBrand()+"---"+p2.getPrice()+"---"+
p2.getColor()) ;
}
}