学习java之路之第三周

面试题

if…else…和三元运算符的区别?

共同点:都是针对两种情况进行判断,都有表达式;
不同点:
	*if...else...流程控制语句,范围很大,不仅仅可以操作数据值,还可以操作输出语句去完成逻辑判断;而三元运算符仅仅是运算符,操作两个具体的数据值;
	*三元运算符能实现的一定能够使用if...else...流程语句
	*if....else....流程语句实现的,不一定能够使用三元!(流程控制语句操作 System.out.println())

switch语句后面的变量名可以是什么样的数据类型呢?

本身能够跟的基本数据类型:byte,short,char,int
Jdk5以后可以是枚举(引用类型) enum
JDK7以后可以跟String类型

for和while循环有什么区别?

1)从用法格式上看,格式不同,while循环的这个格式,不要忽略了控制体语句;
		for(初始化语句;条件表达式;控制体语句){
			循环体语句;
		}		
		初始化语句;
		while(条件表达式){
			循环体语句;
			控制体语句;
		}
2)是否明确循环次数(开发中,优先使用for)
		如果需求明确了循环次数,优先使用for循环,工程上的for循环使用最多的!
		(最频繁的)
		如果不明确循环次数,使用while循环  
		* 举例: 猜数字游戏(1-100的数据)
				统计才多少次(使用while新年好)
				不断录入数据,模拟用户登录
				密码和用户名的信息都不一致,错误
				否则,登录成功...
3)从内存角度考虑,for循环更优一些,比较节省内存空间	
	从for循环本身的格式上来说,for循环结束,里面的局部变量(方法定义中的变量)就被及时的释放空间!
	while循环格式,结束之后,依然能够去访问那个变量,(比较消耗内存空间)所以相对来说whle循环没有for循环好

形式参数是基本数据类型和引用类型(重点)的区别

形式参数如果是基本类型,形式参数改变不影响实际参数(包括特殊的应用java.lang.String)
形式参数如果是引用数据类型,形式参数的改变直接影响实际参数的

在这里插入图片描述
在这里插入图片描述

局部变量和成员变量有什么区别?

局部变量和成员变量有什么区别?

  • 1)书写位置的区别
    • 局部变量:在方法定义中或者方法声明上的变量
    • 成员变量:类中方法外!
    • 实际开发中:根据具体的情况具体使用,范围越小越好,因为范围小,使用完,释放内存了!
  • 2)内存位置不同
    • 局部变量:在栈内存中—跟方法有关(方法进栈)
    • 成员变量:在堆内存中—跟对象有关 (类名 对象名 = new 类名()😉
  • 3)生命周期不同:
    • 局部变量:随着方法调用而存在,随着方法调用结束而消失
    • 成员变量:随着对象的创建而存在,随着对象的创建完毕后,使用完毕(访问成员变量/访问成员方法)之后等待
    • 垃圾回收器空闲时候回收而消失!(不会立即释放)
  • 4)初始化值不同
    • 局部变量:在使用之前必须初始化,否则报错
    • 成员变量:跟对象有关系,存在系统默认初始化,然后可以显示初始化 对象名.成员变量名=赋值;

if…else…嵌套

if....else....一种嵌套   (不推荐,知道可以实现解决一些问题)
	if(表达式1){
		if(表达式2){
			语句1;
		}else{
			语句2;
		}
	}else{
		if(表达式3){
			语句3;
		}else{
			语句4;
		}
		
	}

流程控制语句之switch

//格式:
switch(变量名){
	case1:
		语句1;
		break ;
	case2;	
		语句2;
		break ;
	....
	....
	....
	default:
		语句n;
		break ;
	}

执行流程:
switch后面的变量需要和case进行匹配,case 值1:成立,执行语句1,
遇见break,switch语句结束;
如果不匹配,继续执行case 值2:成立,执行语句2,break结束

switc语句中的注意事项:
1)case语句的后面只能是常量(在Java语言中:强类型语言:语法结构很严谨),而前端javascript里面的switch语句的case可以是常量,变量;
2)在case语句里面,如果一旦匹配成功,一定书写break;否则会造成case穿透,case匹配成功了,就会执行里面的语句,遇见break语句结束; (这个现象 “灵活运用”)
3)switch中的default语句可以在语句中的任何位置,不影响语句的执行流程
正常的格式,在语句末尾,break可以是省略的;
如果在语句中,break带上,否则case穿透了 (考点)
4)switch语句的结束条件:
第一种情况,就是语句break结束; case语句后面的break或者default语句的break
第二种情况,就是语句默认执行到末尾结束!

循环结构语句

for 语句

循环结构语句:当需求中有这种循环的思想,就需要使用循环语句去实现
for循环格式

			for(初始化语句;条件表达式;控制体语句){
				
					//实际开发中,此处需要去完成一些逻辑判断
					循环体语句;
			}
执行流程:
	1)初始化语句,对变量进行赋值,
	2)条件表达式判断结果是否成立,成立,则执行循环体语句,进行控制体语句++或者--
	3)继续判断条件表达式是否成立,成立,继续上面这种操作...
	...
	...
	如果控制体语句造成了条件表达式不成立,语句结束!
	
	求和思想
	统计思想
	for-while的区别
	for和while死循环格式(使用while(true)居多)
	跳转语句
	引入方法
/*需求:
		求5的阶乘
		
	n! = n*(n-1)*(n-2)...4 * 3 * 2 * 1	
	
	求阶乘思想
	
	1)定义最终结果变量
	int jc = 1 ;
	2)循环:5的阶乘 ---- 明确了范围 int x=  1 ; x <=5 ;x++
	
			jc *= x;    //x = 1 ,1<=5 , x++ , 2 <=5 
						//jc = 1 * 1 =1 , jc=1*2
	3)输出结果变量即可		
*/
class ForDemo2{
	
	public static void main(String[] args){
		//求5的阶乘
		//定义结果变量
		int jc = 1 ; 
		for(int x = 2 ; x <= 5 ; x++){ //初始化语句 从2开始
			//循环体
			jc *= x ;//1*1 永远是1 
		}
		System.out.println("5的阶乘是:"+jc) ;
	}
}

水仙花数

/*需求:在控制台输出所有的水仙花数
	水仙花:水仙花是一个三位数,特点就是每个位上的立方之和的结果就是当前数据本身
	153=1*1*1 + 5*5*5 + 3*3*3
	分析:
		1)明确范围三位数,使用for   初始化语句:变量x
		2)确定了范围,如何获取每个位的数据呢,个位,百位,十位?(关键)
			2.1)定义三个变量 int ge,int shi ,int bai
			  个位数据 = 就使用x%10 ;
			  十位上的数据 = x /10 %10 ;
			  百位上的数据 = x/10 /10 %10;
			2.2)完成逻辑判断  
			  满足条件:如果x的值 == (ge*ge*ge+shi*shi*shi+bai*bai* bai)
			2.3)输出这个x值,即可
*/
class ForDemo3{
	public static void main(String[] args){
		System.out.println("水仙花数是:") ;
		//在控制台输出所有的水仙花数
		//1)明确范围三位数,使用for   初始化语句:变量x
		for(int x = 100; x <1000; x++){
			//2)定义三个变量:分别代表个位数据,十位数据,百位上的数据
			int ge = x % 10 ;   //153 % 10 = 3
			//去掉了低位,再去对10求余 //153 /10 % 10 = 5
			int shi = x / 10 % 10 ; 
			int bai = x/10/10%10 ; //153/100 %10 = 1
			//完成逻辑判断  
			//满足条件:如果x的值 == (ge*ge*ge+shi*shi*shi+bai*bai* bai)
			if(x==(ge*ge*ge+shi*shi*shi+bai*bai* bai)){
				//输出x
				System.out.println(x)  ;
			}
		}
	}
}

统计思想

/*
	统计思想:
		统计所有的水仙花有多少个?
		1)定义统计变量
		2)分析题意,明确范围,for循环
		3)满足条件,则统计变量++
		4)输出统计变量
*/
class ForTest{
	public static void main(String[] args){
		//1)定义统计变量
		int count = 0 ;
		//2)统计所有水仙花----水仙花 三位数,明确范围 for循环
		for(int x= 100 ; x<=999; x++){
			//2.1)确定每个位数据
			int ge = x %10 ;
			int shi = x/10%10;
			int bai = x/10/10%10 ;
			//2.2)满足条件,统计变量++
			if(x==(ge*ge*ge+shi*shi*shi+bai*bai*bai)){
				count ++ ;//统计变量++
				System.out.println("第"+count+"个,水仙花数是:"+x) ;
			}
		}
		System.out.println("所有的水仙花共有"+count+"个") ;
	}
}

for循环嵌套

for(初始化语句1;条件表达式1;控制体语句1){
	for(初始化语句2;条件表达式2;控制体语句2){
		循环体语句.....
	}
}

示例:

需求:
输出四行5列的******
*****
*****
*****		
*/
class ForForDemo{
	public static void main(String[] args){
		//原始的做法:
		System.out.println("*****") ;
		System.out.println("*****") ;
		System.out.println("*****") ;
		System.out.println("*****") ;
		//不好,上面的代码,冗余度太大(重复度太大)
		System.out.println("---------------------------------------") ;
		//循环思想改进
		for(int x = 0 ; x < 4 ; x ++){//0,1,2,3
			System.out.println("*****") ;
		}
		System.out.println("---------------------------------------") ;
		
		//上面虽然可以,使用for循环,但是*,单独去输出 冗余度在低一些
		//一行5个*,我可以将一行的每一个*都使用for循环操作
		//每一个*在同一行上,将输出语句System.out.print() ,在同一行上打印
		//第一行的5个*
		for(int x = 0 ;x < 5 ;x++){ //0,1,2,3,4
			System.out.print("*") ;
		}
		//换行
		System.out.println() ;
		
		System.out.println("--------------第二行----------------") ;
		//第二行 还是5个*
		for(int x = 0 ;x < 5 ;x++){ //0,1,2,3,4
			System.out.print("*") ;
		}
		//换行
		System.out.println() ;
		
		System.out.println("--------------第三行----------------") ;
		//第三行 还是5个*
		for(int x = 0 ;x < 5 ;x++){ //0,1,2,3,4
			System.out.print("*") ;
		}
		//换行
		System.out.println() ;
		System.out.println("--------------第四行----------------") ;
		//第四行 还是5个*
		for(int x = 0 ;x < 5 ;x++){ //0,1,2,3,4
			System.out.print("*") ;
		}
		//换行
		System.out.println() ;
		
		System.out.println("----------------将上面代码最终优化为:------------------------") ;
		
		//上面代码也能够实现,冗余度还是存在,为了更好的去书写
		//使用for循环嵌套,上面的代码循环四次
		for(int x = 0 ; x < 4 ; x ++){//行数,四行,x= 0 ,1,2,3
			for(int y = 0 ;y < 5 ;y++){ //列数,5列 y=0,1,2,3,4 
				System.out.print("*") ;
			}
			//换行
			System.out.println() ;
		}
	}
}

打印九九乘法表

class ForForTest{
	public static void main(String[] args){
		//6行6列的*形
		for(int x= 0 ; x <6 ;x++){//行数
			for(int y = 0 ; y < 6 ;y++){
				System.out.print("*") ;
			}
				System.out.println() ;
			}
System.out.println("-----------------------------------------") ;
			//现在列数随着行的变化而变化
			//6行6列,列数有变化
			for(int x= 0 ; x <6 ;x++){//行数
				for(int y = 0 ; y <=x ;y++){//列数
					System.out.print("*") ;
				}
				System.out.println() ;
			}
System.out.println("-----------------------------------------") ;
			//99乘法表:跟我们的这个上面的格式一样
			//为了保证有数据 数据从1开始
			for(int x = 1 ; x <=9 ; x ++){//行数
				for(int y = 1 ; y <=x ; y ++){//列数,在变化
					//循环体语句
					//转义字符: "\t" 制表符 类似tab键的效果
					System.out.print(x +"*"+y+"="+(y*x)+"\t") ;
				}
				System.out.println() ;
			}
	}
}

for循环语句嵌套的应用——百钱买百鸡

 public static void main(String[] args) {
        //定义公鸡为x,母鸡为y,小鸡为z
        int x, y, z;
        for (x = 0; x <= 20; x++) {
            for (y = 0; y <= 33; y++) {
                z = 100 - x - y;
                if ((5 * x + 3 * y + z / 3) == 100 && x + y + z == 100 && z % 3 == 0) {
                    System.out.println("公鸡" + x + "母鸡" + y + "小鸡" + z);
                }
            }
        }
    }

while语句

while循环扩展格式:
	初始化语句;
	while(条件表达式){
		循环体语句;
		控制体语句;
	}
执行流程:
	1)初始化语句进行变量赋值,执行一次;
	2)判断条件表达式是否成立,成立,执行循环体语句,依次执行控制体语句;
	3)再次回到2)继续操作
	...
	...
	当条件表达式不成立,while循环结束
/*
	使用while循环来完成			
		1)1-100之间的和
		2)1-100之间的偶数和
		3)输出所有的水仙花数
		4)统计所有水仙花的个数
*/
class WhileTest{
	public static void main(String[] args){
		//1-100之间的和
		int i = 1 ; 
		//定义结果变量
		int sum = 0 ;
		while(i<=100){
			sum += i ;
			i++ ;
		}
		System.out.println("1-100之间的和是:"+sum);
		System.out.println("---------------------------") ; 
		//1-100之间的偶数和
		int x = 1; 
		//结果变量
		int sum2 = 0 ;
		while(x<=100){
			//满足偶数
			if(x % 2 ==0){
				sum2 +=x ;
			}
			x++;
		}
		System.out.println("1-100之间偶数和是:"+sum2);
		System.out.println("---------------------------") ; 
		//输出所有的水仙花数
		//水仙花三位数
		System.out.println("水仙花数是:") ;
		int j = 100 ;
		while(j<=999){
			//定义三个变量,ge,shi,bai
			int ge = j % 10 ;
			int shi = j /10 % 10;
			int bai = j /10/10 %10 ;
			//满足条件
			if(j==(ge*ge*ge+shi*shi*shi+bai*bai*bai)){
				System.out.println(j) ;
			}
			j++;
		}
		System.out.println("---------------------------") ; 
		//统计水仙花多少个?
		//定义统计变量
		int count = 0 ;
		int m = 100 ;
		while(m<=999){
			//定义三个变量,ge,shi,bai
			int ge = m % 10 ;
			int shi = m /10 % 10;
			int bai = m /10/10 %10 ;
			//满足条件
			if(m==(ge*ge*ge+shi*shi*shi+bai*bai*bai)){
				//统计变量++
				count ++ ;
				System.out.println("第"+count+"个,水仙花数是"+m) ;
			}
			m++ ;
		}
		System.out.println("水仙花共有"+count+"个") ;
	}

dowhile

初始化语句;
	do{
		循环体语句;
		控制体语句;
	}while(条件表达式) ;
初始化语句赋值
判断条件,成立,执行循环体,控制体语句,再次判断....

特点:和for,while最大的区别就是:即使条件不成立,循环体至少执行一次!
开发中 do-while很少,一般也就是jdk提供的类的源码中会见到!

两种死循环

for死循环格式

for(;;){
		循环体语句;
	   }

while死循环

while(true){//推荐这个格式
		循环体语句;
		}
死循环的格式最终里面完成某个逻辑,当达到某种条件结束循环
会用到一个跳转控制语句 break(中断,结束) ;
不能单独用,它使用在循环语句以及switch语句中;

猜大小小游戏

/*
	想要完成一个猜数字游戏:使用循环来操作,不断的键盘录入数据,进行猜
	大了,提示大了,
	小了,提示小了
	如果一致,恭喜猜中了,提示  第几次猜中了
	键盘录入数据实现
	1)产生一个1-100之间的随机数 通过刚才的Math.random() *100+1 --->int
	2)不断的键盘录入一个数据,guessNumber   (使用死循环while(true))  ,不明确循环次数
	3)里面完成逻辑判断
		guessNumber比1)产生的随机数大,提示"大了"
		guessNumber比1)产生的随机数小,提示"小了"
		否则,提示"恭喜您,猜中了"
*/
import java.util.Scanner ;
class WhileTest{
	public static void main(String[] args){
		//1)产生一个1-100之间的随机数 通过刚才的Math.random() *100+1 --->int
		int number = (int)(Math.random()*100+1) ;
		//定义统计变量
		int count = 0  ;

		while(true){//死循环格式
			count ++ ;//统计变量++
			//2)2)不断的键盘录入一个数据,guessNumer(使用死循环while(true)),不明确循环次数
			//创建键盘录入对象
			Scanner sc = new Scanner(System.in) ;
			System.out.println("请输入您要猜的数字:") ;
			int guessNumber = sc.nextInt() ;
			if(guessNumber<=0 || guessNumber>100){
				System.out.println("录入的数据不合法") ;
				break ;
			}else if(guessNumber >number){
				//提示"大了"
				System.out.println("你要猜的"+guessNumber+"大了") ;
			}else if( guessNumber < number){
				提示"小了"
				System.out.println("你要猜的"+guessNumber+"小了") ;
			}else{
				System.out.println("恭喜您,第"+count+"次猜中了") ;
				break ;//结束中断
			}
		}
	}
}

跳转控制语句 break,continue,return

break语句

break:结束,中断,不能单独使用!
一般在循环语句(loop),或者是switch语句中用,不能超过这个范围去使用;

for循环嵌套中也可以使用break
break 标签名称; 在多层循环嵌套的时候,标签名称就是给循环语句前面加上的标签名字(以前的早期用法)
xx:for(初始化语句;条件表达式;控制体语句){
}

continue语句

跳转控制语句
continue  结束当前循环,立即进入下一次 循环! (不能单独用,在循环中用)

return跳转控制语句

return:是在Java中跟定义方法相关的,跟有返回值类型的方法有关
它结束有返回值类型的方法去使用的,一般很少单独用(可以用,不建议)
return实际开发中,和方法息息相关(下午分解)

Java中的方法

解释

权限修饰符 :目前 public 公共,公开的,访问权限足够大
static: 这周面向对象中讲  (必须先上)
返回值类型:现在数据类型(这几天:使用的基本数据类型,以后就是引用类型)
方法名:满足标识符的规则-->方法名需要满足"小驼峰命名法")
参数类型:就是数据类型(这几天:使用的基本数据类型,以后就是引用类型)
参数名称:就是形式参数(变量名)
return:关键字 :这个方法结束,带回结果,谁调用,给谁! (返回结果--->最终 后期交给前端(JavaEE技术))

方法就是通过独立的{}代码块,完成具体的逻辑,给它相应的名字!(满足标识符的规则:变量和方法名需要满足小驼峰命名法)

固定格式

方式1:有返回值类型的方法定义(在需求中需要根据实际场景需要返回值类型:数据类型)
权限修饰符 static  返回值类型 方法名(参数类型1 参数名称1,参数类型2 参数名称2....){
//完成的方法逻辑操作
return 结果;
}

方式二:没有具体返回值类型的方法定义
public static   返回值类型   方法名(形式参数类型1 参数名1,.....){
里面直接完成了输出操作或者一些其他逻辑,
没有return关键字
System.out.println("xxxx") ;
}
在一些具体的业务场景中,像数组排序,99乘法表,猜数字游戏(提示"大了,小了,还是猜中了..."),没有具体的返回结果但是还要遵循方法定义格式,所以Java提供了关键字void 充当这个返回值类型,只是没有具体返回结果的一种格式而已!没有具体返回结果的方法的定义格式 (回想:我们的main这样写的)
public static void  方法名(形式参数类型1 参数名1,.....){
里面直接完成了输出操作或者一些其他逻辑,
没有return关键字
System.out.println("xxxx") ;
}

方式1-有具体返回值的方法的调用

  • 1)单独调用
  • 2)输出调用
  • 3)赋值调用

方式2—调用:

  • 单独调用(只能用这个)
  • 输出调用
  • 赋值调用

定义方法的注意事项

定义方法的注意事项:

  • 方法和方法是平级关系,不能在一个方法中去定义另一个方法!
  • 定义方法的时候,返回值类型需要最终和return语句的结果类型一致,否则报错!
  • 有左{ 大括号的地方不能有分号,有分号的地方不能出现"{"
  • 定义方法的时候,形式参数类型必须带上,Java语言强类型语言(语法结构很严谨,不像Javascript,定义函数的时候,不需要写参数类型)
  • 调用方法的时候,实际参数要么定义要么键盘录入的,不需要在调用方法里面再去书写数据类型了

方法重载

Java中有一个规定:标识符里面规则: 给方法起名,见名知意!
为了标记同一种方法里面可以完成不同参数的使用,为了提高代码的扩展!
java提供overload方法重载:多个方法的方法名可以相同,参数列表不同,与返回值无关!

参数列表不同:可以有下面几种

参数类型不同
参数个数不同
考虑参数的先后顺序不同

猜大小小游戏(用方法来写)

ublic static void main(String[] args) {
        //main方法中 代码,越少越好
        //调用我们写的方法
        playGuessNumberGame();
    }
    /**
     * 定义一个方法,里面是猜数字游戏
     *  两个明确
     *          明确返回值类型:没有具体返回结果,直接输出
     *          明确参数类型以及参数个数
     *                  空参
     */
    public static void playGuessNumberGame(){
        //产生随机数 1-100之间随机数
        int number = (int) (Math.random()*100+1) ;

        //定义统计变量
        int count = 0 ;
        //不断的键盘录入数据
        while(true){
            count ++ ;
            //创建键盘录入对象
            Scanner sc = new Scanner(System.in) ;

            System.out.println("请您要输入要猜的数字(1-100):");
            int guessNumber = sc.nextInt() ;

            if(guessNumber <0 || guessNumber>100){
                System.out.println("录入数据不合法!");
                break ;
            }else if(guessNumber > number){
                System.out.println("您要猜的数字"+guessNumber+"大了");
            }else if(guessNumber<number){
                System.out.println("您要猜的数字"+guessNumber+"小了");
            }else{
                System.out.println("恭喜您,您是第"+count+"次,猜中了!");
                break;
            }
        }
    }

Jvm内存分配:栈,堆,方法区,本地方法区(和系统相关),寄存器(和系统相关)

  • 栈内存:存储局部变量(在方法定义中或者方法声明上),局部变量跟方法有关的;方法进栈,方法调用完毕,里面局部变量随着调用结束而消失
  • 堆内存:new出来的东西(引用数据类型)存储在堆中,而且它是随着对象的创建完毕,产生堆内存空间地址值!
  • 方法区:里面很多的区域:class字节码文件区域—存储字节码文件—jvm需要加载这个类,解析这个类所有的方法以及变量(—这个过程"反射技术")
  • static区域:----静态区域–存储跟static相关的一些方法以及变量等等
  • constant pooll:常量池 里面存储常量相关的
  • 本地方法区(了解): 和系统相关的----->创建系统资源完成系统相关的操作
  • 寄存器(了解): 和系统cpu都有关系:电脑的核数(16核/8核的)–核数越大,高并发场景下,运行效率越高;
    在这里插入图片描述

数组

什么是数组

数组是一个容器,这个容器能够存储同一种类型的多个元素!

如何定义一个数组?

Java规定有一种固定的格式

  • 数据类型[] 数组名称 ;
  • 数据类型 数组名称[] ;

创建对象的内存图解

创建一个对象

在这里插入图片描述

创建两个对象

在这里插入图片描述

创建多个对象

在这里插入图片描述

创建数组的两种方式

  • 动态初始化:程序员你自己 给定数组长度,系统去默认分配的元素值
    • 数据类型[] 数组名称 = new 数据类型[数组长度];
    • 数据类型 数组名称[] = new 数据类型[数组长度] ;
 public static void main(String[] args) {

        //创建一个数组,动态初始化
        int[] arr = new int[3] ;

        //解释
        //=左边
        //int:表示存储 int类型数据
        //[]:一维数组(数组默认)
        //=右边
        //new:Java关键字,表示创建对象,堆内存中开辟空间(new出来的东西在堆中)
        //int:表示数组中存储的都是int类型数据
        //[]:数组中的长度是3
        System.out.println(arr); //打印了 数组名称---就是当前创建数组在堆内存产生的空间地址值
                                //[I@1540e19d   [:一维数组 I:int类型数据   @xxxds :地址值标记
        //如何访问数组的元素:数组名称[索引值或者叫角标] ---索引值从0开始算
        //访问第一个元素:arr[0]
        System.out.println(arr[0]);//0
        System.out.println(arr[1]);//0
        System.out.println(arr[2]);//0

        //重新赋值
        arr[0] = 20 ;
        arr[1] = 10 ;
        System.out.println(arr[0]);
        System.out.println(arr[1]);
        System.out.println(arr[2]);

    }

  • 静态初始化:指定数组的元素,长度由系统给定
    • 数据类型[] 数组名称 = new 数据类型[]{元素1,元素2,元素3…}; 推荐这个
    • 数据类型 数组名称[] = new 数据类型[]{元素1,元素2,元素3…};
    • 简写格式
      • 数据类型[] 数组名称 = {元素1,元素2,元素3…};
      • 数据类型 数组名称[] = {元素1,元素2,元素3…};

ps:使用静态初始化,不能动静结合!
创建数组_静态初始化的过程
在这里插入图片描述

数组的应用

静态初始化,将数组的遍历

 public static void main(String[] args) {
       //创建一个数组,静态初始化
       int[] arr = {11,22,33,44,55} ;
       //原始的做法:
       //通过数组名称[索引值]访问
       System.out.println(arr[0]);
       System.out.println(arr[1]);
       System.out.println(arr[2]); //ctrl+d:复制行
       System.out.println(arr[3]) ;
       System.out.println(arr[4]) ;
       System.out.println("---------------------------------");
       //改进:上面代码冗余度很高,arr[索引值在变化]---循环改进:for
       for(int x = 0 ; x < 5 ; x ++){ //0,1,2,3,4  索引值
           System.out.println(arr[x])  ;
       }
       System.out.println("---------------------------------");
       //上面的这个5:数出来的,不太好
       //假设有一个数组:
       //int[] arr2 = {10,20,11,22,66,5,3,12,15,99,45,32,12,44} ;
       //当数组的元素比较多:---数组提供了属性:length属性 :获取数组长度的
       //数组名称.length---获取数组长度  ---数组的最大索引值 = 数组长度-1
       //System.out.println(arr.length);
      // System.out.println(arr2.length);
       for(int x = 0 ; x < arr.length ; x ++){ //0,1,2,3,4  索引值
           System.out.println(arr[x])  ;
       }

       System.out.println("--------------------------------------------------");
       //继续优化----我们昨天学习了方法----->将数组遍历的操作----使用方法改进!
       //单独调用
       printArray(arr);
       System.out.println("---------------------最终版代码---------------------------");
       printArray2(arr);

   }
   /*
   * 定义一个方法:方法最终输出数组的格式:
   * [元素1, 元素2, 元素3, 元素4, 元素5, ....]
   * */
   public static void printArray2(int[] arr){ //类型是一个数组类型
       //[元素1, 元素2, 元素3, 元素4, 元素5, ...元素n]
       //1在同一个行上-不换行输出"["
       System.out.print("[");

       //2)遍历数组,获取到每一个元素
       for(int x = 0 ; x < arr.length ;x++){
           //完成逻辑判断
           //如果角标值 == 数组长度-1 :
           // 说明当前已经取到最大角标值,数组的元素已经到达末尾,应该最后一个元素以及右"]"输出,换行
           if(x== arr.length-1){
               System.out.println(arr[x]+"]");
           }else{
               //说明没有取到最大角标值,中间对应的元素应该  元素内容 + ", "  ,在同一行上
               System.out.print(arr[x]+", ");
           }
       }

   }

   /*
   * 定义一个方法:遍历数组元素---将元素的内容输出控制台
   * 两个明确
   *       1)明确返回值类型:没有具体返回值 void
   *       2)明确参数类型以及参数个数:
   *           参数类型---int类型数组,1个参数
   * */
   public static void printArray(int[] arr){//参数是数组类型 arr是形式参数
       for(int x = 0 ; x < arr.length ; x ++){ //0,1,2,3,4  索引值
           System.out.println(arr[x])  ;
       }
   }

最值问题

public static void main(String[] args) {
        //已知一个数组,静态初始化
        int[] arr = {24,67,98,12,56} ;
        //定义一个参照物,将arr[0]看成是最大值
        int max = arr[0] ;
        //从角标1开始遍历后的元素
        for(int x = 1 ; x < arr.length ;x ++){
            //一一获取到元素了
            //进行判断
            //如果后面的元素比参照物还大max还打,那么将后面的元素赋值 给max
            if(arr[x] >max){//arr[1] > max  arr[2] > max  arr[3] > max不成立
                max = arr[x] ;
            }
        }
        System.out.println("数组中的最大值是:"+max);
        System.out.println("----------------------------------------------") ;
        //调用方法
        int max2 = getArrayMax(arr);
        System.out.println("使用方法改进获取的数组最大值是:"+max2);
    }
    /**
     * 定义一个方法:获取数组中的最大值
     *  两个明确
     *          1)明确返回值类型 :int类型
     *          2)明确参数类型以及参数个数
     *                  int[] 数组,1个参数
     */
    public static int getArrayMax(int[] arr){//需要传递数组对象---在main中创建一个数组,静态初花了
        //定义参照物
        int max = arr[0] ;
        //从角标1开始遍历后面的元素
        for (int i = 0; i < arr.length; i++) {
            //如果后面元素比参照物大,将后面元素赋值给max
            if(arr[i]>max){
                max = arr[i] ;
            }
        }
        return max ;
    }

假设思想
在这里插入图片描述

数组的基本查找

特点:数组无序或者有序都可以,从头查到尾部,如果查不到,返回负数(找不到,-1)

后面将高级查找 (二分搜索法,也称为"折半查找":前提条件,数组必须有序!)
jdk工具类—Arrays—>binarySearch(int[] arr,int target)—>获取元素第一次出现索引值

 public static void main(String[] args) {
        //已知一个数组:静态初始化
        int[] arr = {24,87,15,69,45} ;

        //查询87这个元素在数组第一次出现的索引值
        //使用方法来完成
        int index = getIndex(arr,87) ;
        System.out.println("87这个元素第一次出现的索引值是:"+index) ;

        int index2 = getIndex(arr,99) ;
        System.out.println("99这个元素第一次出现的索引值是:"+index2) ;

        System.out.println("------------------------------------------------------------");

        //调用方法
        int index3  = getIndex2(arr,120) ;
        System.out.println(index3);
        int index4 = getIndex2(arr,45) ;
        System.out.println(index4);

    }

    //方式2实现 假设思想

    /**
     * 获取数组的元素第一次出现索引值
     * @param array 要查找指定数组
     * @param target 要查找的指定元素
     * @return 返回的内容就是该元素的索引值
     */
    public static int getIndex2(int[] array,int target){
        //假设找不到就是-1
        int index = -1 ; //索引值-1
        //遍历数组
        for(int i = 0 ; i < array.length;i++){
            //一一获取数组元素,如果target == array[i],将index的值修改了,将i值赋值给index ,循环结束
            if(target== array[i]){
                //找到了这个元素
                //修改index值
                index = i ;
                break ;
            }
        }
        return index;
    }

    //方式1
    //定义一个方法:获取数组的中的元素索引值
    /**
     * 两个明确
     *      明确返回值类型:  int
     *      明确参数类型以及参数个数:
     *                  2个参数需要
     *                  1一个数组
     *                  1一个是找的元素
     */
    public static int getIndex(int[] array,int target){//array:指定的数组中查询,target:找的元素
        //1)直接遍历数组
        for(int i = 0 ; i < array.length; i ++){
            //2)一一获取到数组元素,如果这个target就是跟array[i]一致,说明target就是我们要找的元素
            if(target == array[i]){
                //返回角标值即可;
                return  i ;
            }
        }


        //如果找了一圈,for结束了,还找不到,返回-1
        return  -1 ;
    }

数组的高级排序——冒泡排序

两两比较,将较大的值往后放,第一次比较完毕,最大值就出现在最大索引处
依次这样比较,可以得到一个排好序的数组;

规律:
1)两两比较,较大的值往后放
2)第一次有0个不比,
第二次有1个不比
第三次有2个不比

比较的次数:数组长度-1次

public static void main(String[] args) {
        //已知数组,静态初始化
        int[] arr = {24,69,87,56,13} ;
        System.out.println("排序前原始数组是:");
        //调用数组的遍历方法---将数组 [元素1, 元素2, 元素3,.... 元素n] 输出,展示
        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]){//arr[0]  arr[0+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: 第二次比较有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-3;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);

         */

        //将上面的重复性代码进行优化:冗余度太大
        //循环了四次
        /*for(int x = 0 ; x < 4;x++){//x=0,1,2,3      4是数的 (控制次数)
            //x=0,0<4,
            for(int y = 0 ;y < arr.length-1-x;y++){
                //arr[0] ; y< arr.length-1-0 :第一次有0 个不比
                if(arr[y] > arr[y+1]){  //arr[0]  arr[1]
                    int temp = arr[y] ;
                    arr[y] = arr[y+1] ;
                    arr[y+1] = temp;
                }
            }
        }
        System.out.println("排序之后:");
        //调用遍历
        printArray(arr);*/
        System.out.println("-----------------------------------------------");
        //上面的4的次数,数的,----优化----4-就是比较次数:数组长度-1次
        for(int x = 0 ; x < arr.length-1;x++){//x=0,1,2,3
            //x=0,0<4,
            //arr.length-1-x:就是为了减少比较的次数
            for(int y = 0 ;y < arr.length-1-x;y++){
                //arr[0] ; y< arr.length-1-0 :第一次有0 个不比
                if(arr[y] > arr[y+1]){  //arr[0]  arr[1]
                    int temp = arr[y] ;
                    arr[y] = arr[y+1] ;
                    arr[y+1] = temp;
                }
            }
        }
        System.out.println("排序之后:");
        //调用遍历
        printArray(arr);

        System.out.println("-------------------------最终版代码---------------------------");
        //使用方法来调用排序的代码--->只是排序的方法
        bubbleSort(arr);
        //在调用遍历功能,展示数据
        printArray(arr);

    }
    /*
    * 定义一个冒泡排序的方法:
    *   两个明确
    *       明确返回值类型: 没有具体返回值 --直接元素里面互换  void
    *       明确参数类型  以及参数个数
    *               指定数组,1个
    * */
    public static void bubbleSort(int[] arr){
        for(int x = 0 ; x < arr.length-1;x++){//控制比较的次数
            // arr.length-1-x:为了减少比较的次数
            for(int y = 0 ; y < arr.length-1-x; y++){
                //如果前面的元素比后面元素大
                if(arr[y]> arr[y+1]){
                    int temp = arr[y] ;
                    arr[y] = arr[y+1] ;
                    arr[y+1] = temp;
                }
            }
        }
    }

    /**
     * 遍历数组的方法
     * @param arr 对已知的数组遍历
     */
    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]+", ");
            }
        }
    }

在这里插入图片描述

面向对象

面向对象的思想特点

  • 更符合现实生活中的思想行为习惯
  • 让复杂的事情简单化
  • 角色发生了改变:从执行者(面向过程)—>变成指挥者(面向对象)

面向对象的设计理念

不断的创建对象,使用对象,指挥对象做事情!(面对对象的宗旨)
一直用的Scanner:键盘录入
Scanner sc = new Scanner(System.in) ;
//sc.nextInt() ; sc.nextLine();
sc.nextBoolean();

面向对象的三大特征

封装,继承,多态(面向对象重点)

什么是类

类:是Java语言中最基本的单元;能够描述现实世界事物的一组事物的属性和行为的集合!
类和现实世界事物是一一对应的关系;

举例:

现实世界事物—学生事物
属性:学生的姓名,学生的年龄,学生的性别…
行为:主要就是学习
使用Java语言来描述出来的学生事物------>定一个类----学生类

class Student{
//描述学事物的属性---(代码里面--->成员变量)
//成员变量:是在类中,方法外!
String name ;
int age ;
String sex ;
//描述学事物的行为---->代码中书写--->成员方法
//今天开始写成员方法--之前怎么写,现在还怎么写,自己分析有没有具体返回值类型
//有没有参数,几个参数...
//去掉static (一般类中的成员方法:称为 "非静态方法")
public void study(String className){ //JavaEE
System.out.println("正在学习"+className) ;
}
}

什么是对象

对象:描述现实世界的具体事物!(具体事物的具体的属性和行为)

现实世界的事物—是很概括性的;
学生事物----->姓名,年龄,性别----是谁? 不知道,
需要描述具体的事物------> 具体学生 张三 25 男 / 李四 20 女
在代码中体现出来具体事物----->需要记住Java中的创建类对象的格式

创建类对象的格式:
类名 对象名 = new 类名() ;
对象名.成员变量名 = 值 (根据成员变量的类型赋值); 访问成员变量 赋值
对象名.方法名(); 访问我们自己的定义的成员方法,去使用它,展示数据或者实现具体业务需求

创建类对象的内存图解

  • 创建一个类对象的内存图解
    在这里插入图片描述
  • 创建两个类对象的内存图解
    在这里插入图片描述
  • 创建多个类对象的内存图解
    在这里插入图片描述

形式参数: 基本数据类型和引用类型 —调用该方法,实际参数?

形式参数是基本类型和引用类型,实际参数传递问题! (重点要就引用类型)
形式参数是基本类型,调用该方法,实际参数传递对应类型的数据值即可(简单,数据值传递)
形式参数是引用类型(如果是类),调用这个方法,实际参数传递需要传递当前类的具体对象 (创建类对象)

匿名对象

匿名对象:  没有名字的对象!
有名字的对象---描述具体事物 ---创建对象格式

类名 对象名 = new 类名() ;
匿名对象格式:
new 类名();

  • 特点:
    • 可以作为"参数传递"
    • 实际用的过程,匿名对象不要多次,一般使用一次即可,使用完毕立即被回收!
      在android中匿名对象使用居多 (移动端内存小,节省内存)

关于封装的概念 (重点)

private关键字的特点:可以修饰成员变量/成员方法,只能在当前类中访问,外界类不能直接访问;但是,可以间接的通过公共的方法访问

 //非私有的成员变量
    public int num = 20 ;
    //私有的成员变量
    private int num2 = 50 ;

    //定义一个的公共的成员方法
    public void show(){

        System.out.println(num) ;
        System.out.println(num2); //间接本类中的公共方法访问
    }

    //私有的成员方法
    private void method(){
        System.out.println("method Demo...");
    }

    //定义一个公共的成员方法
    public void function(){
        System.out.println("function Demo....");
        method();//间接调用本类的私有方法
    }
}

//测试类
public class PrivateDemo {
    public static void main(String[] args) {
            //要访问Demo类的num成员变量 以及num2
        Demo d = new Demo() ;
        System.out.println(d.num) ;
        System.out.println("--------------------------");
        //System.out.println(d.num2) ;num2在Demo类中已经私有控制了
        d.show();

       // d.method() ;//method方法已经被私有控制了
        d.function();
    }
}

this关键字 (重点)

this的含义: 代表当前类对象的地址值引用 
this.变量名 :  访问的是本来的成员变量名
加入this---->标准类的写法    (描述学生事物/描述手机事物)  
在标准类(属性私有化,对外提供公共访问setXXX(xx)/getXXX()).给成员变量赋值形式参数必须见名知意, 局部变量和成员变量名称一致,局部变量会隐藏成员变量,导致成员变量无法赋值!Java提供了关键字"this"

JavaBean规范:
1)类是具体类 class 类名{}
2)类的属性必须私有化
3)类中必须提供setXXX()/getXXX() 对成员变量的公共的访问方法(赋值/获取值)

标识符:给变量,类,接口,方法,以及常量等等起名字的一个字符序列!起名字----“见名知意”
setXXX(XXX)公共的成员方法要给成员变量赋值,里面的形式参数名称应该"见名知意"
public void setName(String name) :name就是传入姓名

public class Student {

    //属性私有化
    private String name ;//姓名
    private int age ; //年龄
    private String gender ; //性别

    //对外提供公共的成员方法
    //赋值的方法setXXX()  ---->传入形式参数
    //给成员name赋值
    //public void setName(String n){ //  高圆圆     n
   /*
        name = n ; //高圆圆
    }*/
    //给成员name赋值,优化
    public void setName(String name){  //形式参数也是 name
        //name = name ;  //提供this 区分成员变量和局部变量
        this.name = name ;
    }

    //所有的getXXX()--->return 隐藏了this关键字(可以省略不写)
    //获取成员变量name的值--考虑返回值类型
    public String getName(){
        return  name ; //高圆圆

    }


    //给age赋值
   /* public void setAge(int a){  //44     a
        age = a ; //44
    }*/

    //优化
    public void setAge(int age) {  //44
        this.age = age;
    }

        //获取age的值
    public int getAge(){
        return  age ;  //44
    }

    //给性别赋值
    /*public void setGender(String g){  //"女"   g
        gender = g ; //"女"
    }*/
    public void setGender(String gender){
        this.gender = gender ;
    }
    //获取性别的值
    public String getGender(){
        return  gender ; //"女"
    }

    //其他成员方法
    //行为:学习
    public void study(String className){//JavaSE
        System.out.println("正在学习"+className);
    }
}

 /*属性:姓名,年龄,性别
   行为:学习
使用面向对象的编程方式来描述学生事物,并且在测试类中对学生事物进行测试--创建具体的学生对象出来!
加入封装!(将全部私有化,对外提供公共的访问方法setxxX()/getXxx())
*/
//测试类
public class StudentTest {
    public static void main(String[] args) {

        //创建学生对象
        //类名 对象 = new 类名() ;
        Student s = new Student() ;

        //成员变量私有化了:不能直接访问
        //s.name= "高圆圆" ;
       // System.out.println("姓名是:"+s.name);

        //通过公共的setXXX(xxx)赋值
        s.setName("高圆圆") ;
        s.setAge(44) ;
        s.setGender("女") ;
        //通过getXXX()方法获取值
        System.out.println("这个学生的姓名是"+s.getName()+",年龄是:"+s.getAge()+",性别是:"+s.getGender());
        s.study("JavaSE之面向对象");
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱学Java的小宇宙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值