方法加强练习
此需求和代码在文章最下面。
1、方法参数传递
1.1 什么是方法参数传递
概念:在使用方法的时候,传入值或者变量就是参数传递。
1.2 参数传递的本质:
Java的参数传递:
基本数据类型传递的是:值本身。
引用数据类型传递的是:变量在堆中的引用地址。
1.3 值传递
/**
* 堆栈分析:
* 基本类型是"值"的传递
* 引用类型是引用地址的传递
*/
public class _04StackHeap {
public static void main(String[] args) {
int a = 1;
System.out.println("改变前:" + a); // 1
// 调用change方法
change(a);
System.out.println("改变后================ :" + a); // 1
}
public static void change(int a) {
a = 2;
System.out.println("改变中-------:" + a); // 2
}
}
内存分析图:
1.4 引用地址传递
/**
* 堆栈分析:
* 基本类型是"值"的传递
* 引用类型是引用地址的传递
*/
public class _05StackHeap {
public static void main(String[] args) {
int[] arr = {1, 2};
System.out.println("改变前:" + arr[0]);// 1
System.out.println("改变前:" + arr[1]);// 2
// 调用change方法
change(arr);
System.out.println("改变后================ :" + arr[0]);// 6
System.out.println("改变后================ :" + arr[1]);// 9
}
public static void change(int[] arr) {
arr[0] = 6;
arr[1] = 9;
System.out.println("改变中-------:" + arr[0]);// 6
System.out.println("改变中-------:" + arr[1]);// 9
}
}
内存分析图:
2. 可变参数
大家先来看几个需求
需求:求2个int变量的和,并且返回,设计一个方法实现
/**
* 求变量a和b的和
* @param a int参数
* @param b int参数
* @return 返回和
*/
public static int getSum(int a, int b) {
return a + b;
}
需求:求3个int变量的和,并且返回,设计一个方法实现
/**
* 求变量a、b、c的和
* @param a int参数
* @param b int参数
* @param c int参数
* @return 返回和
*/
public static int getSum(int a, int b, int c) {
return a + b + c;
}
大家可以看到,求和的需求是类似的,如果这样的需求有很多,按照我们之前的处理的方式就是要声明很多对应的方法处理。这样的话会有代码重复、可读性不好、并且程序员需要花时间去记忆等缺点,所以我们要用数组优化代码。
public class _03ChangeMethod {
public static void main(String[] args) {
// 需求:求2个int变量的和,并且返回,设计一个方法实现
// 需求:求3个int变量的和,并且返回,设计一个方法实现
// 调用getSum(int[] arr) 方法
int[] arr;
arr = new int[]{1, 2};
// 求3个int参数的和,现在参数就相当于是一个静态创建的数组
int sum2 = getSum(new int[]{1, 2, 3});
System.out.println(sum2);
// 求4个int参数的和,现在参数就相当于是一个静态创建的数组
int sum3 = getSum(new int[]{1, 2, 3, 69});
System.out.println(sum3);
}
/**
* 求int[]所有元素的和
* @param arr int[]参数
* @return 返回和
*/
public static int getSum(int[] arr) {
int sum = 0;
for (int e : arr) {
sum += e;
}
return sum;
}
}
现在虽然用数组优化了参数个数不定的情况,但是有存在另外一个问题,就是传入参数的时候,需要我们程序员将参数作为元素创建一个数组,也非常麻烦,所以,我们接下来用可变参数来最终解决这些问题。
1. 概念:就是将方法参数个数不定的需求,简化的一种语法,其本质是数组。
2. 作用:简化代码,将数组的创建工作交给了编译器。
3. 语法:
修饰符 返回值类型 方法名(其他数据类型 变量, 数据类型... 变量){ 方法体 } |
代码案例:
public class _03ChangeMethod {
public static void main(String[] args) {
// 调用getSum(int... arr) 方法
// 求3个int参数的和,现在参数就相当于是一个静态创建的数组
int sum = getSum(1, 2);
System.out.println(sum);
// 调用getSum(int... arr) 方法
// 求3个int参数的和,现在参数就相当于是一个静态创建的数组
int sum2 = getSum(1, 2, 3);// 现在数组创建交给了编译器,编译器会根据传入的参数临时静态创建一个数组
System.out.println(sum2);
// 求5个int参数的和,现在参数就相当于是一个静态创建的数组
int sum3 = getSum(1, 2, 3, 4, 5);// 现在数组创建交给了编译器,编译器会根据传入的参数临时静态创建一个数组
System.out.println(sum3);
}
/**
* 可变参数语法:
修饰符 返回值类型 方法名(其他数据类型 变量,数据类型... 变量){
方法体
}
* 求多个int类型参数的和
* @param arr 可变参数
* @return 返回和
*/
public static int getSum(int... arr) {
System.out.println(arr);// 地址
System.out.println(arr.length);// 数组长度
int sum = 0;
for (int e : arr) {
System.out.println("元素:" + e);
sum += e;
}
return sum;
}
}
注意事项:
1. 可变参数本质就是一个数组,只不过这个数组是编译器帮我们程序员创建的。
2. 一个方法只能有一个可变参数,并且只能在形参列表最末尾。
3、Arrays工具类&API文档的使用
3.1 什么是工具类
- 概念:简单的认为,就是JDK、或者其他程序员已经帮我们写好的类而已。
- 作用:可以将它看成是现成的轮子,可以直接使用,节约了程序员设计类的时候,提高了开发效率。
Arrays就是JDK设计的用来专门操作数组的工具类。
3.2 工具类怎么使用?
使用他人设计的类,最好的方式是通过自带的API手册(即,相当于说明书)或者百度来学习怎么使用。
使用API手册步骤:
1. 点击索引,在搜索栏,输入要使用的类Arrays 2. 简单看一下该类的介绍,能看懂就看,看不懂的就不用管 3. 直接看下这个类中的方法,然后看一下方法的介绍和使用方式 Modifier(修饰符)有static的调用方式是:类名.方法名(实参); Type(返回值类型) :决定可以用什么类型变量接受方法调用结果 Method (方法名):看形参列表,调用的时候,必须传入对应的实参 Description (方法的描述和介绍) 4. 看不懂方法的描述,就直接调用一下方法,来看效果 看是否有static修饰,如果有用:类名.方法名(实参); 看是否有static修饰,如果没有用:对象名.方法名(实参); |
Arrays类中常用方法:
1. public static String toString(int[] arr)拼接数组中元素,格式:[值1,值2...] 2. public static void sort(int[] arr)将数组中的元素排序,默认升序。从小到大 3. public static int binarySearch(int[] arr,int a)查询变量a在数组arr中第一次出现的下标。如果没有找到返回负数。 注意:建议数组是排好顺序且不重复的,否则查询结果不准确(升序和降序都可以 4. public static int[] copyOf (int[] arr,int newLength)数组的扩容和缩容方法 扩容:如果newLength大于arr数组中用来的长度,就是扩容,扩容后,arr数组所有的元素都已经复制到新数组中 缩容:如果newLength小于arr数组中用来的长度,就是缩容,缩容后,arr数组从后向前缩 5. static int[] copyOfRange(int[] arr, int from, int to) 将指定数组arr的指定下标范围从from到to之间的元素,复制到新数组中。【含头不含尾】 6. public static void fill(int[] arr,int a)将数组arr中的元素批量初始化为a |
代码案例:
public class _06API {
public static void main(String[] args) {
// 1. 调用Arrays类中的 public static String toString(int[] arr)拼接数组中元素,格式:[值1,值2...]
int[] arr = {1, 69, 33, 12, 5};
// 调用toString,因为是static修饰,所以用Arrays类名调用,返回值是String类型,所以,用String变量接收结果
String str = Arrays.toString(arr);// 报错是因为找不到该类Arrays,需要导包
// 打印返回值str即可
System.out.println(str);
// 排序:2. public static void sort(int[] arr)将数组中的元素排序,默认升序。从小到大
Arrays.sort(arr);
// 重新拼接排序后的数组字符串
String str2 = Arrays.toString(arr);
System.out.println("排序后:" + str2);
/*
* 3. public static int binarySearch(int[] arr,int a)查询变量a在数组arr中出现的下标。如果没有找到返回 负数。注意:建议数组是排好顺序的并且不重复的元素(升序和降序都可以)
[1, 5, 12, 33, 69]
*/
int binarySearch = Arrays.binarySearch(arr, 12);// [1, 5, 12, 33, 69]
System.out.println("下标:" + binarySearch);
/*
* 4. public static int[] copyOf (int[] arr, int newLength)数组的扩容和缩容方法
扩容:如果newLength大于arr数组中用来的长度,就是扩容,扩容后,arr数组所有的元素都已经复制到新数组中
缩容:如果newLength小于arr数组中用来的长度,就是缩容,缩容后,arr数组从后向前缩
都是从下标0开始扩容或者缩容
*/
int[] arr2 = {1, 69, 33, 12, 5};
// 扩容
int[] newArr = Arrays.copyOf(arr2, 7);// 因为7 > arr2.length ,所以是扩容
// 将数组newArr拼接字符串,用String变量str3接收
String str3 = Arrays.toString(newArr);
System.out.println("扩容后新数组 :" + str3);
// 缩容
int[] newArr2 = Arrays.copyOf(arr2, 3);// 因为3 < arr2.length,所以是缩容
// 将数组newArr2拼接字符串,用String变量str4接收
String str4 = Arrays.toString(newArr2);
System.out.println("====缩容后新数组 :" + str4);
/*
* 5. static int[] copyOfRange(int[] arr, int from, int to)
将指定数组arr的指定下标范围从from到to之间的元素,复制到新数组中。 【含头不含尾】
*/
int[] arr3 = {1, 69, 33, 12, 5};
int[] newArr3 = Arrays.copyOfRange(arr3, 1, 3);// 截取数组arr3中包含下标1,到不包含下标3之间的元素,返回到新数组中
// 将数组newArr3拼接字符串,用String变量str5接收
String str5 = Arrays.toString(newArr3);
System.out.println("复制指定下标1~3区间的新数组 :" + str5);
// 6. public static void fill(int[] arr, int a)将数组arr中的元素批量初始化为a
Arrays.fill(arr3, 996);// 将数组arr3中全部元素批量修改为996
// 将数组arr3拼接字符串,用String变量str6接收
String str6 = Arrays.toString(arr3);
System.out.println("批量初始化后的数组 :" + str6);
}
}
方法加强练习(需求)
/**
* 方法练习题
*/
public class _01Homework {
public static void main(String[] args) {
// 1.定义一个方法getMax,接收两个int参数,返回最大的一个数(低级)建议使用三目运算
/*
* 2 方法的调用:(最重要)
看要调用方法是否有static修饰:
1 有static修饰,用:当前类名.方法名(实参(变量/值));
2 没有static修饰,用:当前类的对象名.方法名(实参(变量/值));
特殊情况:
如果调用方(目前就是指main方法)和被调用方都在同一个类中,且都有或者都没有static修饰,可以简写为:
方法名(实参(变量/值));
*/
int max = getMax(1, 2);
System.out.println(max);
System.out.println(getMax(2, 3));// 可以直接打印一个方法,但是该方法返回值类型必须不是void。
// 2.定义一个方法,接收三个int参数,返回最小的一个数(低级)
// 3.设计一个求3个int类型积的方法,并返回这个积(低级)
// 4.设计一个方法,传入一个int的数组,返回该数组中最大的值(中级)
int[] arr = {1, 9, 96, 9, 6, 66};
// 调用getMaxInArray方法
int maxInArray = getMaxInArray(arr);
System.out.println("数组中最大值:" + maxInArray);
// 5.设计一个方法,传入一个参数姓名name、一个参数爱好hobby,打印输出一句话:name的爱好是:hobby
// ===============================选做==========================
/*
* 6.设计一个方法,查询并返回一个字符在字符数组中第一次出现的位置(高级)
char[] arr2 = {'a', 'b', 'c', 'a', 'g'};
char c = 'a';
四要素:
返回值类型:int
方法名:getIndexInArray()
形参列表:char c, char[] arr
方法体:
遍历整个数组,将c 和 arr[i] 如果相等,返回下标i
如果遍历完,没有找到,返回 -1 下标范围:0,n
*/
char[] arr2 = {'a', 'b', 'c', 'a', 'g'};
char c = 'g';
int indexInArray = getIndexInArray(arr2, c);
System.out.println("下标:" + indexInArray);
// 7.设计一个方法,统计返回一个字符在字符数组中出现的次数(高级)
// 8.设计一个方法,已知这样的整形数组 int[] arr = {1,2,3,4,5,6,7,8,9,11,12}返回其中的奇数和
int[] arr3 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12};
// 调用方法: getOddSum
int oddSum = getOddSum(arr3);
System.out.println("奇数和:" + oddSum);
/*
* 9.现在有数组 double[] scores = {11,34,76,77,88,99,58,97,56};定义一个方法统计并打印出每一个阶段学生人
* 数(分段方式:0-60;60-80;80-100)(高级)
*/
double[] scores = {11, 34, 76, 77, 88, 99, 58, 97, 56};
printScores(scores); // 返回值是void,直接调用执行即可
// 10.设计一个方法,传入一个int数组,翻转该数组中的元素,并且返回反转后的数组(牛皮做)
// 调用方法:reverse
int[] reverse = reverse(arr3);
for (int e : reverse) {
System.out.println(e);
}
// 打印数组是,没有意义。所以,有了该需求
// 11.需求:请设计一个方法toString,传入一个int[],将该数组进行字符串拼接,格式如下:[元素1, 元素2, 元素3....],返回拼接后的字符串
System.out.println(reverse);
// 调用:toString方法
String str = toString(reverse);
System.out.println(str);
}
/**
* 1.定义一个方法getMax,接收两个int参数,返回最大的一个数(低级)建议使用三目运算
* 方法的声明(定义):(最重要)
1. 在当前类中,main方法下方,写public + alt + / 选择第三个
2. 根据需求分析方法的四要素:
1. 返回值类型:int
2. 方法名:getMax
3. 形参列表:int a, int b
4. 方法体:三目运算,找最大值,并且返回
3. 根据实际需求,修改方法的四要素
* @return
*/
public static int getMax(int a, int b) {
// 如果用if else语句
// if (a > b) {
// return a;
// } else {
// return b;
// }
return a > b ? a : b;// 是优先级最低的运算,会在执行完三目运算后执行return返回结果
}
/**
* 4.设计一个方法,传入一个int的数组,返回该数组中最大的值(中级)]
* 方法的声明(定义):(最重要)
1. 在当前类中,main方法下方,写public + alt + / 选择第三个
2. 根据需求分析方法的四要素:
1. 返回值类型:int
2. 方法名:getMaxInArray
3. 形参列表:int[] arr
4. 方法体:
foreach遍历数组arr,找一个临时变量保存最大值max,每次循环都有跟数组元素e对比,如果比max大,则重新给max赋值为e,循环结束后,就找到最大值了,然后返回最大值max
3. 根据实际需求,修改方法的四要素
* @return
*/
public static int getMaxInArray(int[] arr) {
// 先判断参数arr是否非null,如果非null才能继续执行
// 声明一个int类型max,赋值第一个元素arr[0],保存遍历到的最大值
int max = arr[0];
// foreach遍历数组arr
for (int e : arr) {
// 每次循环max都有跟数组元素e对比
if (e > max) {// 如果e比max大,则重新给max赋值为e
max = e;
}
}
// 循环结束后,就找到最大值了,然后返回最大值max
return max;
}
/**
* 6.设计一个方法,查询并返回一个字符在字符数组中第一次出现的位置(高级)
* @return
*/
public static int getIndexInArray(char[] arr, char c) {
// 先判断参数arr是否非null,如果非null才能继续执行,否则就可能发生空指针异常。
if (arr == null) {
return -1;// 任意负数表示未找到
}
// 遍历数组
for (int i = 0; i < arr.length; i++) {
// 判断每一个元素arr[i]跟参数c是否相等
if (c == arr[i]) {
return i;// 如果相等直接返回当前下标
}
}
// 循环结束还没有返回,证明没有找到,返回-1
return -1;
}
/**
* 8.设计一个方法,已知这样的整形数组 int[] arr = {1,2,3,4,5,6,7,8,9,11,12}返回其中的奇数和
* @return
*/
public static int getOddSum(int[] arr) {
// 非null判断,以后通过抛出异常的方式解决,现在不管
int sum = 0;
// 遍历数组arr
for (int e : arr) {
// 判断当前e是否是奇数
if (e % 2 != 0) {
sum += e;
}
}
return sum;
}
/**
* 9.现在有数组 double[] scores = {11,34,76,77,88,99,58,97,56};定义一个方法统计并打印出每一个阶段学生人
* 数(分段方式:0-60;60-80;80-100)(高级)
* @return
*/
public static void printScores(double[] scores) {
// 非null判断不写了
int countC = 0;// 声明0-60计数器
int countB = 0;// 声明60-80计数器
int countA = 0;// 声明80-100计数器
// 遍历数组 scores
for (double e : scores) {
// 判断元素e属于哪个阶段
if (e >= 0 && e < 60) {
countC++;
} else if (e >= 60 && e < 80) {
countB++;
} else if (e >= 80 && e <= 100) {
countA++;
} else {
System.out.println("分数错误!");
}
}
System.out.println("0-60人数:" + countC + " 60-80人数:" + countB + " 80-100人数:" + countA);
}
/**
* 10.设计一个方法,传入一个int数组,翻转该数组中的元素,并且返回反转后的数组(牛皮做)
* @return
*/
public static int[] reverse(int[] arr) {
// 非null判断不写了
// 普通for循环遍历数组arr
for (int i = 0; i < arr.length / 2; i++) {// 通过画图得知循环次数
// 通过画图得知交换的下标关系
// 交换收尾的元素即可
int temp = arr[i];// 声明一个临时变量temp,赋值为arr[i]
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = temp;
}
// 返回数组arr
return arr;
}
/**
* 11.需求:请设计一个方法toString,传入一个int[],将该数组进行字符串拼接,
* 格式如下:[元素1, 元素2, 元素3....],返回拼接后的字符串
* 思路:要遍历数组,将数组元素进行字符串拼接
* 步骤:
* 1. 声明一个String类型str,赋值为"[",用来拼接字符串的
* 2. 遍历数组nums,初始化条件,从下标0开始,循环结束条件到倒数第二个元素
* 每次循环,都将获取到的元素nums[i]拼接到str中,然后在继续拼接一个逗号
* 3. 循环结束后,再将最后一个元素nums[nums.length - 1]拼接上,拼接 结尾]
* @param arr
* @return
*/
public static String toString(int[] arr) {
// 非null判断不写了
// 1. 声明一个String类型str,赋值为"[",用来拼接字符串的
String str = "[";
// 2. 遍历数组arr,初始化条件,从下标0开始,循环结束条件到倒数第二个元素
for (int i = 0; i <= arr.length - 2; i++) {
// 每次循环,都将获取到的元素arr[i]拼接到str中
str += arr[i] + ", ";
}
// System.out.println(str);
// 3. 循环结束后,再将最后一个元素arr[arr.length - 1]拼接上,拼接 结尾]
str += arr[arr.length - 1] + "]";
return str;
}
}
下一章 《面向对象》