什么是方法?
循环操作(while,do while , for循环):
解决的是代码重复的问题,重复做某一件事情.
此时得重复:有规律的,语句格式是相同的,有规律的.
循环操作真的能解决所有的重复吗?
针对于某一种功能的重复操作,循环解决不了,此时得使用方法.
方法就是一段特定功能的代码块
{
代码块
}
为什么要有方法?
提高程序的复用性和可读性
例如:愤怒的小鸟中有发射小鸟的代码,那么每发射一次,我们就需要写一次,这样程序的整体长度,可读性和可扩展性大大的降低,当前的发射代码我们就可以进行一定修改,
将这段代码写在一个代码块中,这个代码块在其一个名字,每次调用的时候直接调用代码块的名字,就可以调用当前这段功能代码了,提高了当前程序的复用性和可读性
ps:方法与函数的关系.
在某些语言中把当前功能代码块成为函数,那么函数与方法本质上是没有区别的.所以
在Java中我们既可以称当前代码块是函数,也可以叫做方法名称中不做区分,但是在实际使用和开发中推荐称呼为"方法"
java面向对象语言 --> 方法 --> 面向过程 --> 函数
方法的格式
语法:
访问权限修饰符 [其他的修饰符 如static] 返回值类型 方法名(参数类型1 形参1,参数类型2 形参2,...){//形参列表
//方法体
return 返回值;
}
方法的格式说明:
修饰符:public,static等,static修饰的方法属于类,直接使用类名调用即可
ps:类名.方法名 --> 当前类的方法
同一个类中(同一个文件中),可以直接调用静态方法:方法名即可
现在都使用static修饰.
返回值类型: 方法其实是在完成一个功能,该功能操作完毕之后,是否需要给调用者返回一个结果.如果不需要给调用者返回结果,此时使用关键字void来声明,无返回的意思.
ps:可以省略return关键字,千万不要使用[return 返回值] 的形式书写
void类型 --> 基本数据类型 --> 引用数据类型(new)
栈空间 堆空间
方法名称:遵循标识符的规范,使用动词表示,首字母小写,若是多个单词组成,使用驼峰表示法,以后的每一个单词首字母都大写,getEmployeeName.
参数列表:参数列表 == 参数的类型 + 参数的个数 + 参数的顺序.
ps: () 可以没有任何参数 --> 什么都不要写
可以有多个参数 ---> 数据类型 名字, 数据类型 名字 ....
就近原则--> 方法中同样适用
定义了一些变量,这些变量是为了方法内部提供使用的
定义的变量其实有一个名词 --> 形参
形式参数:形参就是一个变量,
ps:要使用定义的变量进行操作,需要给参数进行赋值 --> 实参
实际参数:实参就是一个值,传参就是把一个值给一个形参赋值
ps:形参名可以和实参名相同
int a = 10;
(int a)
调用方法(a)
方法签名:方法签名 == 方法名称 + 方法参数列表;
在同一个类中,方法签名是唯一的,否则编译报错.
方法体:方法的{}中的代码,表示具体完成该功能的代码.
返回值: 在方法内部,使用return关键字;
功能1:给调用者返回一个结果值,此时该方法不能使用void修饰.
ps:若使用return时 return 返回值;此时方法不能使用void修饰
功能2.结束方法,若有返回值类型,方法必须使用return关键 +返回值,若是void不需要使用return,写也可以但是不行添加返回值
ps:若使用return带有返回值,调用方法者可选择接收,也可以不接收
若使用return没有返回值,调用方法者绝对不能接收
只要方法在打印语句中能输出结果,方法就一定带有返回值
System.out.println(方法名());
方法的位置:
1):在类中定义,在Java中最小的程序单元是类.
2):方法定义在其他方法之外,方法和方法是兄弟关系.(在方法体中是不能定义方法的)
ps:Java中没有方法声明,定义即可用
3):方法定义的先后顺序不影响.(你到饭店先上宫保鸡丁和糖醋排骨影响你吃吗)
方法的内存图和方法调用过程
ps:Java面向对象的语言
封装,继承,多态
方法:其实就是封装特性的一种体现
方法的重载 -- 多态的
同一个事物,被不同的对象所触发,得到的结果是不同
重载:方法名相同,参数列表不同(数据类型, 个数不同, 顺序不同其中一个满足即可),称为重载
拓展:递归方法(算法):
从前有座山,山里有座庙,庙里有一个老和尚和一个小和尚,小和尚要睡觉,老和尚给小和尚讲故事..............
方法自身调用自身(自己调用自己),需要给定一个停止的条件
递归就是在完成一个隐式的循环
递归效率很高,占用资源,没有明确前提下不建议写
一般的递归都使用循环的方式完成
逆向思维:求和 1~10 之间数的和
有六个人,第六个人说他比第五个人大3岁
五 四 3岁
四 三 3岁
依次类推:最后一个(第一个人)说自己13岁 求第六个多大
JVM内存图
JVM内存划分,人为根据不同内存空间存储特点和存储的数据划分
程序计数器:当前线程执行到字节码文件的行号指示器
本地方法栈: native方法提供支持(java中某些方法时直接调用c++或C的库来完成)
虚拟机栈(栈空间):描述java方法执行的内存模型,每个方法执行的时候都会创建一个栈帧,用于存储局部变量(参数列表,在方法体中声明变量),栈的操作,动态链接,方法出站等信息
堆:被锁有线程所共享的内存区域,在虚拟机启动的时候所创建,所有的对象实例和数组都是分配在堆空间
(使用new关键字,在堆中开辟空间)
方法区: 线程共享一块区域.存储着已经被虚拟机加载的类的信息,常量,静态变量,即时编译的一些数据
Java 数组的定义
为什么要有数组?
声明变量的时候每一个单独的变量都需要对应一个变量,但是我们要处理一组比较大的相同数据类型的数据量:
班级 38名学生,存储所有学生的年龄
创建38个变量--> 数据类型相同int,38变量的名字
一次性存储38个值,并且可以方管理 ---> 数组
数组就是存储着大量相同数据类型的集合,可以方便我们来完成增删改查
定义数组
// 定义数组 -->数组中存储的而是相同数据类型
//1.标准方法
//数组中元素的数据类型[] 数组名 = new 数组中元素的数据类型[数组中元素的个数];
//int 不是数组的数据类型 -->数组中元素的数据类型
//数组的数据类型 --> 数据类型[]
int[] age = new int[38];
//2.先声明数组,然后在进行赋值
//ps:多用于在类中所声明的成员属性(变量)
//数组是一个引用数据类型,开辟的存储空间是在堆中
//若使用下面这种方式声明数组,数组声明完后是有默认值的,是null
int[] age2; //栈中
age2 = new int[38]; //堆中
//3.在声明数组的同时进行初始化
//需要注意:不能指定数组中存储元素的个数
//数组会通过赋值的个数,推断出数组中元素的个数
int[] age3 = new int[] {1,2,3,4,5};
//4.第三中写法的简化版本
int[] age4 = {1,2,3,4};
//这样也行但是不推荐
int age5[] = new int[1];
数组中可以使用的数据类型:
值类型:
整数byte,short,int,long 数组中的默认值是 0
小数float double 数组中的默认值是 0.0
字符char 数组中的默认值是 u0000 --> 表示空
ps:是一个不可见的字符,但是不是空格
布尔 boolean 数组中的默认值是 false
引用数据类型 数组中的默认值是 null
ps:在堆中存储的就是引用数据类型
数组单个元素的访问
下标:当前数组中元素对应存储的序号
下标第一是从0开始,数组的长度-1(最后一位)
数组中元素的个数 == 数组的长度
语法:
数组名[下标]
向数组中某一个元素赋值
数组名[对应下标] = 对应数据类型的值
ps:必须满足数组中元素的数据类型所对应的值
取出数组中某一个元素的值
数组名[对应下标]
ps:取出值后,给其他变量或数组进行赋值,当做方法参数传递,进行一些运算符之间的运算
数组的静态赋值和数组的动态赋值
数组的静态赋值,就是在创建数组的同时对数组进行赋值
int[ ] age = {1,2,3,4};
动态赋值:数组中每一个元素的值都是通过某种方式(输入,随机数,某种计算)得来,动态赋值
1.Scanner 2.Math.random()
数组的遍历访问
第一种:普通for循环
for(数组中第一个元素的下标;数组长度;下标自增){
}
第二种:增强for循环(foreach循环)
将数组中的元素之取出,然后存储给变量,通过变量就可以看到数组中存储的元素,并且可以做一些操作()
for(数组中元素的数据类型 变量名:数组名){
}
结论:普通for循环即可以对数组进行取值和赋值操作
增强for循环只能对数组进行取值,不能进行赋值操作
ps:数组是一个集合(容器),定长的集合(容器)
数组一旦指定了存储元素的个数,就不能再进行增加或减少
1 package day04ketang; 2 3 public class MethodDemo { 4 5 public static void main(String[] args) { 6 // TODO Auto-generated method stub 7 int a=(int)(Math.random()*100); 8 System.out.println(a); 9 int b=(int)(Math.random()*100); 10 System.out.println(b); 11 int max =SelectMax(a,b); 12 double s=Math.max(12, 99); 13 System.out.println(s); 14 int z=addnum(10); 15 int b1=fun(6); 16 System.out.println(b1); 17 } 18 /** 19 * 20 * @param a 定义一个变量 21 * @param b 定义一个变量 22 * @return 返回最大值 23 */ 24 public static int SelectMax(int a,int b) { 25 // TODO Auto-generated method stub 26 if(a<b) { 27 System.out.println(b); 28 return b; 29 }else { 30 System.out.println(a); 31 return a; 32 } 33 // return a>b?a:b; 34 } 35 /** 36 * 递归调用 37 */ 38 39 public static int addnum(int num) { 40 if(num==1) { 41 return 1; 42 }else { 43 return num +addnum(num-1); 44 } 45 } 46 /** 47 * 计算上一个人比下一个人大3岁 48 * @param a1人数 49 * @return 年龄 50 */ 51 public static int fun(int a1) { 52 if(a1==1) { 53 return 13; 54 }else { 55 return fun(a1-1)+3; 56 } 57 } 58 /**void 型递归 59 * 60 * @param n 61 * @param x 62 * @param y 63 * @param z 64 */ 65 public static void move(int n,int x,int y,int z) { 66 if(n==1) { 67 System.out.println(x); 68 }else { 69 move(n-1,x,y,z); 70 } 71 } 72 73 }
数组的排序
数组排序有很多种:冒泡,选择,插入,快速,堆,归并排序
冒泡排序:
排序都是升序排序(从小到大) ,降序(逆序)从大到小
数组中的元素进行两两相比,大移动到数组的末尾,每次排序完成都会有一个数放到正确的位置
例子: 9 4 6 3 1
第一次比较
数组中第一个元素和数组中第二个元素进行比较,若第一个元素大于第二个元素,交换两个元素的位置,然后继续比较直到数组的最后一个元素
4 6 3 1 9
第二次
数组中第一个元素和数组中第二个元素进行比较,若第一个元素大于第二个元素,交换两个元素的位置,然后继续比较直到数组的最后一个元素
4 3 1 6 9
第三次
数组中第一个元素和数组中第二个元素进行比较,若第一个元素大于第二个元素,交换两个元素的位置,然后继续比较直到数组的最后一个元素
3 1 4 6 9
第四次
数组中第一个元素和数组中第二个元素进行比较,若第一个元素大于第二个元素,交换两个元素的位置,然后继续比较直到数组的最后一个元素
1 3 4 6 9
选择排序
会先固定一个位置,然后依次和后面每一个元素进行比较,若当前固定位置的元素大于后面比较的元素,交换讲个元素的位置,然后继续比较直到数组的最后一个元素为止
例子:9 4 6 3 1
第一次:固定数组第一个元素,依次和后面每一个元素比较
1 9 6 4 3
第二次:固定数组第二个元素,依次和后面每一个元素比较
1 3 9 6 4
第三次:固定数组第三个元素,依次和后面每一个元素比较
1 3 4 9 6
第四次:固定数组第三个元素,依次和后面每一个元素比较
1 3 4 6 9
冒泡排序:
1 package day04ketang; 2 3 public class Maopao { 4 5 public static void main(String[] args) { 6 // TODO Auto-generated method stub 7 int[] array= new int[10]; 8 for(int i=0;i<array.length;i++) { 9 array[i]=(int)(Math.random()*100); 10 } 11 System.out.println("排序之前"); 12 for(int i=0;i<array.length;i++) { 13 System.out.println(array[i]); 14 } 15 System.out.println(); 16 for(int i=0;i<array.length-1;i++) { 17 for(int j=0;j<array.length-1-i;j++) { 18 if(array[j]>array[j+1]) { 19 array[j+1]=array[j+1]^array[j]; 20 array[j]=array[j]^array[j+1]; 21 array[j+1]=array[j+1]^array[j]; 22 } 23 } 24 System.out.println("排序之后"); 25 for(int k=0;k<array.length;k++) { 26 System.out.println(array[k]+" "); 27 } 28 } 29 } 30 31 }
选择排序:
package day04ketang; public class Xuanze { public static void main(String[] args) { // TODO Auto-generated method stub int[] array= new int[10]; for(int i=0;i<array.length;i++) { array[i]=(int)(Math.random()*100); } System.out.println("排序之前"); for(int i=0;i<array.length;i++) { System.out.println(array[i]); } System.out.println("排序之后"); for(int i=0;i<array.length;i++) { for(int j=i+1;j<array.length;j++) { if(array[i] > array[j]) { array[i]=array[i]^array[j]; array[j]=array[j]^array[i]; array[i]=array[i]^array[j]; } } } System.out.println(); for(int k=0;k<array.length;k++) { System.out.println(array[k]+" "); } } }