目录
第一节:初识方法
1.1. 方法概念引入
方法:一段具有固定功能的代码片段
当程序中需要这个功能时,可以直接调用该代码片段,不需要将代码反复编写
固定的功能 形成模块
减少重复代码的编写
减少程序的维护工作
1.2. 方法的语法
1.3. 方法的调用
自定义一个方法 定义一个方法 用于返回两个整数的和
主方法调用其他方法
1.4. 方法的分类
静态方法 >>> 类方法 有static修饰的
成员方法 >>>实例方法 没有static修饰的
是否有返回值和参数
无参数无返回值
无参数有返回值
有参数无返回值
有参数有返回值
第二节:方法的应用
2.1. 方法的各种训练
定义一个方法 向控制台输出99乘法表
定义一个方法 向控制台输出一个整数的阶乘
定义一个方法 返回a的b次方
有参数有返回值
定义一个方法 返回一个浮点数保留两位小数 考虑四舍五入的结果
有参数有返回值
定义一个方法 返回一个整数数组的元素和
参数 一个整数数组
返回值 整数int
定义一个方法 返回一个整数数组的元素最大值
参数 一个整数数组
返回值 整数int
定义一个方法 返回一个整数数组的元素最小值
定义一个方法 返回一个整数数组的元素平均值
参数整数数组
返回值 double
2.2. 方法之间相互调用
不仅仅是主方法可以调用其他方法,自定义方法也是可以调用其他方法的
方法不能相互调用或者形成循环调用 只能是成单链式调用
数组元素求和
数组元素求平均值
方法不能循环或者互相调用
Stact 栈 >>> 栈内存
栈内存溢出
下面的方法OK
定义一个方法 返回一组双色球彩票数
双色球的规则
前六位 红球 1-33 不能重复 升序排列
最后一位 蓝球 1-16 可以和前六位重复
public static int[] getLottery(){
int[] lottery={1,5,….};
return lottery;
}
public class Test3 {
public static void main(String[] args) {
int[] lottery = getLottery();
System.out.println(Arrays.toString(lottery));
}
/*双色球的规则
前六位 红球 1-33 不能重复 升序排列
最后一位 蓝球 1-16 可以和前六位重复
*/
public static int[] getLottery(){
int[] lottery=new int[6];
for (int i = 0; i <6 ; i++) {
/*生成随机数*/
int num =(int)(Math.random()*33+1);
//判断 生成的数字是否已经包含了
while(isContain(lottery,num)){
/*重新生成数字 */
num =(int)(Math.random()*33+1);
}
lottery[i]=num;
}
// 数组工具类排序 OK
Arrays.sort(lottery);
int[] lottery2=new int[7];
// 数组的复制
System.arraycopy(lottery,0,lottery2,0,6);
// 处理第7位
lottery2[6]=(int)(Math.random()*16+1);
return lottery2;
}
/**
* 该方法用于判断给定的数组中是否包含指定的元素
* @param arr 给定的数组
* @param b 要查找的元素
* @return 找到返回true 未找到返回false
*/
public static boolean isContain(int[] arr,int b){
boolean flag= false;
for (int x:arr){
if(x==b){
flag=true;
break;
}
}
return flag;
}
}
2.3. 方法的执行的内存流程
栈内存
方法运行的区域
堆内存
数据存放的区域
方法区
Java代码存储的区域
主方法调用其他方法时如a 方法, a方法的代码会被加载进栈内存执行
当方执行结束后 栈内存中会自动清除a方法 但是 方法区中的a方法仍然在
第三节:方法的参数处理
3.1. 按值传递和按引用传递
概念引入
参数分两种
形式上的参数
实际运行的参数
实参将数据传递给形参的两种方式
按值传递
实参传递给形参的数据是值 内存上形参和实参是不同的,是独立的,修改形参不会对实参产生影响
你去饭馆吃饭 看见旁边一桌点了一份水煮鱼 你和服务员说 给我来一份一样的
服务员会复制一份水煮鱼给你 你把 自己的水煮鱼吃光了 对旁边的水煮鱼没有影响
按引用传递
实参传递给形参的不是真实的数据 是数据所在地址 是引用的堆内存中的地址
形参和实参指向的是内存中的同一个数据
修改形参会对实参产生影响 形参和实参事实上是同一个数据
当参数是基本数据类型时 数据不占用堆内存 按值传递
当参数是引用类型时 数据占用堆内存 按引用传递
应用案例 定义一个方法 对一个整数类型的数组进行升序排列
定义排序方法
调用排序方法
方法的跨类和跨包调用不会影响按值和按引用传递
3.2. 可变参数
可变参数的引入
public class Test1 {
/*
* ... 可变参数
* 当 ... 作为形参时 传入的实参是可变的
* 在方法体内部 任然将可变参数当成数组使用
* 如果传入的实参是多个单独的变量 程序会自动将多个单独的变量放入数组
*
* 可变参数的好处
* 1 传入数组OK
* 2 传入多个单独的变量OK
* 3 传入的多个单独的变量的数量没有要求 可以变化的
* */
// 定义一个方法 遍历一个整数数组
public static void showArray(int... arr){
System.out.println("showArray 方法执行了");
for (int i = 0; i <arr.length ; i++) {
System.out.println(arr[i]);
}
}
public static void main(String[] args) {
int[] arr={1,2,3,4,5,6,7,8,9};
int a=11;
int b=22;
int c=33;
int d=44;
int e=55;
int f=66;
int g=77;
showArray(a,b,c,d);
showArray(arr);
}
}
可变参数的使用的注意事项
3.3. 方法的重载 overload
概念引入
定义一个方法求两个byte变量的和
定义一个方法求两个short变量的和
定义一个方法求两个int变量的和
… …
上述的方法可以归为一类 他们的功能相同或者相似
但是他们需要的参数是不同的 那么这六个方法 方法命名是否可以有一些让我们舒服的处理方式吗? 如果是六十个? 如果是六百个? 怎么才能最简单呢? 使用同一个方法名
方法重载:在一个类中 多个同名方法的定义
方法重载没有减少代码量,仅仅是减少了相同或者相似功能方法的大量命名,方便我们记忆和调用
public class Test1 {
public static void main(String[] args) {
//a(10.0,10);
int[] arr={1,2,3};
b(arr);
}
/*
* 在一个类中 让多个方法同名是允许的 但是有条件
* 方法重载是有条件的
* 方法名必须相同
* 参数必须不同
* 在调用同名方法时无法根据方法名区分多个同名方法
* 但是可以根据传入的实参去匹配多个同名方法中的某一方法
* 参数可以有哪些不同 1个数不同 2数据类型不同 3顺序不同(数据类型)
* 在方法重载时 可变参数和数组作为方法参数认为是相同参数
* */
public static void a(double i){
System.out.println("方法1");
}
public static void a(int i){
System.out.println("方法2");
}
public static void b(int[] arr){
}
public static void b(String... arr){
}
}
应用案例
定义一个方法 返回一个圆的周长 半径
定义一个方法 返回一个圆的面积 半径
定义一个方法 返回一个矩形的周长 长 宽
定义一个方法 返回一个矩形的面积 长 宽
定义一个方法 返回一个三角形的周长 三个边
定义一个方法 返回一个三角形的面积 三个边 海伦公式(百度)
要求 所有求周长的方法使用同一个方法名
所有求面积的方法使用同一个方法名
package demo3;
public class Test3 {
public static void main(String[] args) {
double perimeter = getPerimeter(4,5,3);
System.out.println(perimeter);
double areas = getAreas(3,4,5);
System.out.println(areas);
}
// 定义一个方法 返回一个圆的周长 半径
public static double getPerimeter(int r){
return 2*Math.PI*r;
}
// 定义一个方法 返回一个圆的面积 半径
public static double getAreas(int r){
return Math.PI*r*r;
}
// 定义一个方法 返回一个矩形的周长 长 宽
public static double getPerimeter(int a,int b){
return (a+b)*2;
}
// 定义一个方法 返回一个矩形的面积 长 宽
public static double getAreas(int a,int b){
return a*b;
}
// 定义一个方法 返回一个三角形的周长 三个边
public static double getPerimeter(int a,int b,int c){
// 任意两边值和大于第三边 任意两边之差 小于第三边
if (a+b>c&&a+c>b&&b+c>a) {
return a+b+c;
}
return 0;
}
// 定义一个方法 返回一个三角形的面积 三个边 海伦公式(百度)
public static double getAreas(int a,int b,int c){
// 任意两边值和大于第三边 任意两边之差 小于第三边
if (a+b>c&&a+c>b&&b+c>a) {
// 得到p值 三边和的一半
double p =(a+b+c)/2.0;
// 求s值
double s=p*(p-a)*(p-b)*(p-c);
// 对s进行开平方
return Math.sqrt(s);
}
return 0;
}
}
数组工具类的封装
package demo3;
public class ArraysUtil {
// 6个
/**
* 升序排列一个byte数组
* @param arr 要排序的byte数组
*/
public static void sortASC(byte[] arr){
for (int i = 0; i <arr.length-1 ; i++) {
for (int j = 0; j <arr.length-1-i ; j++) {
if(arr[j]>arr[j+1]){
byte temp =arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
/**
* 升序排列一个short数组
* @param arr 要排序的short数组
*/
public static void sortASC(short[] arr){
for (int i = 0; i <arr.length-1 ; i++) {
for (int j = 0; j <arr.length-1-i ; j++) {
if(arr[j]>arr[j+1]){
short temp =arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
/**
* 升序排列一个int数组
* @param arr 要排序的int数组
*/
public static void sortASC(int[] arr){
for (int i = 0; i <arr.length-1 ; i++) {
for (int j = 0; j <arr.length-1-i ; j++) {
if(arr[j]>arr[j+1]){
int temp =arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
/**
* 升序排列一个long数组
* @param arr 要排序的byte数组
*/
public static void sortASC(long[] arr){
for (int i = 0; i <arr.length-1 ; i++) {
for (int j = 0; j <arr.length-1-i ; j++) {
if(arr[j]>arr[j+1]){
long temp =arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
/**
* 升序排列一个float数组
* @param arr 要排序的float数组
*/
public static void sortASC(float[] arr){
for (int i = 0; i <arr.length-1 ; i++) {
for (int j = 0; j <arr.length-1-i ; j++) {
if(arr[j]>arr[j+1]){
float temp =arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
/**
* 升序排列一个double数组
* @param arr 要排序的double数组
*/
public static void sortASC(double[] arr){
for (int i = 0; i <arr.length-1 ; i++) {
for (int j = 0; j <arr.length-1-i ; j++) {
if(arr[j]>arr[j+1]){
double temp =arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
// 6个
/**
* 降序排列一个byte数组
* @param arr 要排序的byte数组
*/
public static void sortDESC(byte[] arr){
for (int i = 0; i <arr.length-1 ; i++) {
for (int j = 0; j <arr.length-1-i ; j++) {
if(arr[j]<arr[j+1]){
byte temp =arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
/**
* 降序排列一个short数组
* @param arr 要排序的short数组
*/
public static void sortDESC(short[] arr){
for (int i = 0; i <arr.length-1 ; i++) {
for (int j = 0; j <arr.length-1-i ; j++) {
if(arr[j]<arr[j+1]){
short temp =arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
/**
* 降序排列一个int数组
* @param arr 要排序的int数组
*/
public static void sortDESC(int[] arr){
for (int i = 0; i <arr.length-1 ; i++) {
for (int j = 0; j <arr.length-1-i ; j++) {
if(arr[j]<arr[j+1]){
int temp =arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
/**
* 降序排列一个long数组
* @param arr 要排序的byte数组
*/
public static void sortDESC(long[] arr){
for (int i = 0; i <arr.length-1 ; i++) {
for (int j = 0; j <arr.length-1-i ; j++) {
if(arr[j]<arr[j+1]){
long temp =arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
/**
* 降序排列一个float数组
* @param arr 要排序的float数组
*/
public static void sortDESC(float[] arr){
for (int i = 0; i <arr.length-1 ; i++) {
for (int j = 0; j <arr.length-1-i ; j++) {
if(arr[j]<arr[j+1]){
float temp =arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
/**
* 降序排列一个double数组
* @param arr 要排序的double数组
*/
public static void sortDESC(double[] arr){
for (int i = 0; i <arr.length-1 ; i++) {
for (int j = 0; j <arr.length-1-i ; j++) {
if(arr[j]<arr[j+1]){
double temp =arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
// 查找第一次 8个
/**
* 在给定的int数组中查找指定的int元素第一次出现的位置
* @param arr 给定的int数组
* @param b 要查找的int元素
* @return 如果找到元素,返回元素的索引;如果未找到元素,返回-1;
*/
public static int firstIndexOf(int[] arr,int b){
for (int i = 0; i < arr.length; i++) {
if(arr[i]==b){
return i;
}
}
return -1;
}
/**
* 在给定的byte数组中查找指定的byte元素第一次出现的位置
* @param arr 给定的byte数组
* @param b 要查找的byte元素
* @return 如果找到元素,返回元素的索引;如果未找到元素,返回-1;
*/
public static int firstIndexOf(byte[] arr,byte b){
for (int i = 0; i < arr.length; i++) {
if(arr[i]==b){
return i;
}
}
return -1;
}
// short long float double char boolean
// 查找最后一次 8个
/**
* 在给定的byte数组中查找指定的byte元素最后一次出现的位置
* @param arr 给定的byte数组
* @param b 要查找的byte元素
* @return 如果找到元素,返回元素的索引;如果未找到元素,返回-1;
*/
public static int lastIndexOf(byte[] arr,byte b){
for (int i = arr.length-1; i >= 0; i--) {
if(arr[i]==b){
return i;
}
}
return -1;
}
/**
* 在给定的int数组中查找指定的int元素最后一次出现的位置
* @param arr 给定的int数组
* @param b 要查找的int元素
* @return 如果找到元素,返回元素的索引;如果未找到元素,返回-1;
*/
public static int lastIndexOf(int[] arr,int b){
for (int i = arr.length-1; i >= 0; i--) {
if(arr[i]==b){
return i;
}
}
return -1;
}
// short long float double char boolean
// 判断包含 8个
/**
* 判断给定的int数组是否包含指定的int元素
* @param arr 给定的int数组
* @param b 指定的int元素
* @return 包含则返回true,不包含则返回false
*/
public static boolean isContain(int[] arr,int b){
int index = firstIndexOf(arr, b);
return index>=0?true:false;
}
/**
* 判断给定的byte数组是否包含指定的byte元素
* @param arr 给定的byte数组
* @param b 指定的byte元素
* @return 包含则返回true,不包含则返回false
*/
public static boolean isContain(byte[] arr,byte b){
int index = firstIndexOf(arr, b);
return index>=0?true:false;
}
// byte short int long float double boolean char
//判断给定数组 包含指定元素多少次 8个
/**
* 判断给定int数组 包含指定int元素多少次
* @param arr 给定的int数组
* @param b 指定的int元素
* @return 元素在数组中出现的次数
*/
public static int containTimes(int[] arr,int b){
int t =0;
for (int i = 0; i <arr.length ; i++) {
if(arr[i]==b){
t++;
}
}
return t;
}
// 判断给定数组 是否包含且仅包含一次给定的元素 8个
/**
* 判断给定int数组 是否包含且仅包含一次给定int的元素
* @param arr 给定的int数组
* @param b 要查找的in元素
* @return 包含且仅包含一次返回true 不包含或者包含多次返回false
*/
public static boolean isOne(int[] arr,int b){
int i = containTimes(arr, b);
return i==1?true:false;
}
}