方法
方法定义:
【修饰符】返回值类型 方法名(参数列表){
方法体
return 返回值;
}
自定义方法
1.修饰符可以省略,目前统一写成public static
2.方法名,给方法起名字,遵循标识符命名规范
3. 参数列表:为方法传递的参数
1)(数据类型1 参数名1,数据类型2 参数名2)
2) 根据需求,参数列表可以为空
4.方法体(函数体),用来完成方法的主要功能“ 干活的”
5.返回值表示方法给外界的输出
1)如果没有返回值,最后的return语句可以省略,或者写成“return ;” 。
2)返回值必须和返回值类型兼容
6.返回值类型表示方法返回的数据类型,如果方法没有返回值,返回值类型定义为void
7. 方法要定义在类中,并且和main方法平级(不能被main方法包裹 要不在main方法上面要不下面)
/*
定义方法,求两个整数的和
*/
import java.util.Scanner;
public static int add(int a, int b){
//求和
return a + b;
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
for(; ;){
int num1 = sc.nextInt();
int num2 = sc.nextInt();
System.out.println( add(num1 + num2) );
}
}
方法重载
在 同一类 中,允许存在一个以上的 同名 方法,只要它们的 参数个数或者参数类型 不同即可
特点:
1.方法重载和返回值类型没有关系
2.参数列表不同
1)类型不同
2)顺序不同
3)和参数的名字没有关系
递归调用
递归调用:方法调用方法本身
注意:要有明确的退出语句
没有退出语句 编译没有错误正常运行 但是运行会异常错误----StackOverflowError 栈溢出错误
典型案例:斐波那契数列
/*
斐波那契数列
1 1 2 3 5 8 13.....
f(1) = 1;
f(2) = 1;
f(n) = f(n-1) + f(n-2);
*/
public class MyTest2{
public static int f(int n){
if(n==1 || n == 2)
return 1;
return f(n-1) + f(n-2);
}
public static void main(String[] args){
System.out.println(f(10));
}
}
数组 — 引用数据类型
引入:统计学生成绩
5 10 1000
问题:如何春芳大量相同的类型的数据?
解决:数组
public class MyTest{
public static void main(String[] args){
/*
数组定义:
数据类型【】 数组名;
或者 数据类型 数组名【】;
1)数据类型是数组中存放的元素的类型
2)数组名,起名要符合标识符命名规范
int【】 a;
只是定义,数组中没有元素,要有元素 需要进行初始化
*/
int[] arr;
int arr1[];
/*
数组初始化
分类:
1。动态初始化
初始化时,我们指定数组的长度,由系统为数组元素初始化赋初值
数据类型【】 数组名 = new 数据类型【数组长度】;
动态初始化元素的初始值:
byte short int long 0
double float 0.0
char '\u0000'
boolean false
引用数据类型 null
2.静态初始化
数据类型【】 数组名 = new 数据类型【】{元素1,元素2,元素3....};
数据类型【】 数组名 ={元素1,元素2,元素3....};
*/
//动态初始化举例
int[] arr2 = new int[10];
/*
数组的长度:数组名。length
访问数组的元素:数组名【下标】,下标的范围:0~数组的长度-1;
*/
System.out.println("arr2的长度:" + arr2.length);
System.out.println("arr2的0号元素:" + arr2[0]);
System.out.println("arr2的9号元素:" + arr2[9]);
long[] arr3 = new long[10];
System.out.println("arr3的5号元素:" + arr3[5]);
double[] arr4 = new double[10];
System.out.println("arr4的5号元素:" + arr4[5]);
boolean[] arr5 = new boolean[10];
System.out.println("arr5的5号元素:" + arr5[5]);
char[] arr6 = new char[10];
//char类型数据可以参与算数运算
System.out.println("arr6的5号元素:" + (arr6[5] + 0));
String[] arr7 = new String[10];
System.out.println("arr7的5号元素:" + arr7[5]);
}
}
数组的遍历
1.for
2.while
3.增强for循环 - for Each
for(数据类型 变量名 : 数组名){
}
for(int item : arr){
//本质是将每次循环都将数组元素赋值给变量 如第1次循环 将arr【0】赋值给item
System,out.println(item);
}
数据类型是数组元素的类型
4.java8新特性
将数组转换成Stream流,通过流中的forEach方法遍历
import java.util.Arrays;
public class MyTest{
public static void main(String[] args){
int[] arr8 = new int[10]
arr8[0] = 100;
//打印数组 Arrays。toString(数组名) 作用:返回数组的字符串表示形式
System.out.println(Arrays.toString(arr8));
}
}
数组的长度不可变 以及数组的本质
数组长度不可变 – 数组一旦初始化,其长度不可变
本质:new的内容是存放在堆上的 而数组的名字只是用来存放堆上数组本身在堆上的地址
内存(RAM):
|— 栈:
|— 基本数据类型的变量及其值
|— 引用数据类型(数组,类,接口)及其对应内容在堆上的地址
如数组arr int【】 arr = new int[3]; //存放的只是arr这个数组名 以及后面【3】对应内容在堆里的地址(十六进制地址)如
|—堆:
|— new出来的东西
int a = 10;
int b = 100;
int[] arr = nw int[3];
arr[0] = 1;
int[] arr1 = arr; //arr1只是和arr里存放的数组地址相同 所有访问的是堆里的同一个数组
arr1[0] = 20;
System.out.println(arr[0]); //20 因为arr1存放地址对应数组和arr是一个 该数组的第一个元素已经被上一个语句改变
arr = new int[5]; // 在堆里又新建了一个数组 将该数组的地址存放在栈里的arr中覆盖之前arr存放的地址
//垃圾回收 只是清空了栈中arr与arr1存放的地址(即与堆中数组的联系) 并没有清除堆内的数组 但是java会自动清除堆内没有建立联系的内容 这也是java强大之处
arr = null;
arr1 = null;
数组类型的参数和返回值
方法的格式:
【修饰符】返回值类型 方法名(参数列表){
方法体
return 返回值;
}
public class MyTest{
//定义方法,打印每个数组的元素---数组类型可以作为方法的参数
public static void printArray(int[] arr){
for(int a : arr){
System.out.println(a);
}
}
//定义方法,生成具有特定长度的保存int类型数据的数组---数组类型可以作为方法的返回值
public static int[] creatArray(int length){
return new int[length];
}
public static void main(String[] args){
int textArr = new int[] {1,3,5};
printArray(textArr);
System.out.println("-----------------------------");
int[] arr = creatArray(5);
System.out.println(arr.length);
}
}
int[length];
}
public static void main(String[] args){
int textArr = new int[] {1,3,5};
printArray(textArr);
System.out.println(“-----------------------------”);
int[] arr = creatArray(5);
System.out.println(arr.length);
}
}