Java【第五篇】基本语法之--方法、数组
方法
方法简介
方法是实现特定功能的代码段的封装,在需要时可以多次调用方法来完成该功能,实现代码复用。
使用步骤
1. 定义方法
2. 调用方法
自定义方法
语法:
修饰符 返回值类型 方法名(参数){ //方法体 }
说明:
修饰符:对方法的修饰,本篇暂时都写为public static
返回值类型:方法执行后的返回值类型,如果没有返回值则指定为void
方法名:采用驼峰命名法,一般使用动词
参数:执行方法时所需要的信息,参数由参数类型和参数名组成,多个参数之间以逗号隔开
main方法是程序的入口,程序运行时会自动调用该方法。
方法返回值
结束方法执行,后面代码不执行
return关键字的作用:
* 1.返回方法执行后的结果
* 2.结束方法的执行
1 2 3 4 5 6 7 8 9 10 11 12 | if (age >= 18 ) { return "成年" ; } else { return "未成年" ; } 等价于 if (age >= 18 ) { return "成年" ; } return "未成年" ; |
方法的调用
在同一个类中,直接使用方法名()调用静态方法
在不同类中,需要使用类名.方法名()调用静态方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package com.qzcsbj; public class Test { public static void main(String[] args) { // Java提供了Math类 int a = 5 ; int b = 2 ; System.out.println(Math.max(a, b)); // 5 System.out.println(Math.min(a, b)); // 2 System.out.println(Math.random()); // 随机生成[0,1)之间的随机数 // 随机生成[1,100)之间的随机整数 System.out.println(( int )(Math.random()* 99 )+ 1 ); //[1,100) //随机生成[20,100]之间的随机整数 System.out.println(( int )(Math.random()* 81 )+ 20 ); //[20,100] getMsg(); } public static void getMsg(){ System.out.println( "hello" ); } } |
递归
方法自己调用自己,称为递归,该方法称为递归方法
必须有退出条件,否则可能会出现死循环,报栈溢出异常
示例:计算x的y次方,如2的5次方
常规方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public class Test { public static void main(String[] args) { System.out.println(calc( 2 , 5 )); } public static int calc( int x, int y) { if (y == 0 ) { return 1 ; } int result = x; for ( int i = 1 ; i < y; i++) { result = result * x; } return result; } } |
递归
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public class Test { public static void main(String[] args) { System.out.println(calc( 2 , 5 )); } /* * 计算x的y次方,如2的5次方 */ public static int calc( int x, int y) { if (y == 0 ) { return 1 ; } return x * calc(x, y - 1 ); } } |
其它方法举例
math
数组概述
数组是多个相同类型数据的组合,用来存储相同数据类型的一组数据,实现对这些数据的统一管理
数组属引用类型,数组型数据是对象(Object),数组中的每个元素相当于该对象的成员变量
数组中的元素可以是任何数据类型,包括基本类型和引用类型
声明一个变量就是在内存中划出一块空间
声明一个数组就是在内存中划出一串连续的空间
一维数组
基本用法
声明数组--分配空间--数组赋值--访问元素
声明数组
指定元素的类型
数据类型[] 数组名称; 或 数据类型 数组名称[]; 推荐前者
type var[] 或 type[] var;
例如:
int a[];
int[] a1;
double b[];
Mydate []c; //对象数组
Java语言中声明数组时不能指定其长度(数组中元素的数), 例如: int a[5]; // 非法
分配空间
指定数组长度(长度一旦指定,不能修改),即分配几个连续的空间
数组名称=new 数组类型[大小];
数组赋值
向数组中添加元素,数组名称[下标]=值;
数组元素的引用:访问元素
获取数组中的元素
数组名称[下标];
Java中使用关键字 new 创建数组对象
定义并用运算符 new 为之分配空间后,才可以引用数组中的每个元素;
数组元素的引用方式:数组名[数组元素下标]
数组元素下标可以是整型常量或整型表达式。如a[3] , b[i] , c[6*i];
数组元素下标从0开始;长度为n的数组合法下标取值范围: 0 - n-1;如int a[]=new int[3]; 可引用的数组元素为a[0]、a[1]、a[2],最后一个元素是a[a.lenth-1],如果报数组越界(ArrayIndexOutOfBoundsException),那么可能是下标大于等于数组长度、或者下标小于0
直接访问数组名称会显示数组在内存中的首地址
每个数组都有一个属性 length 指明它的长度,例如:a.length 指明数组 a 的长度(元素个数)
数组元素的默认初始化
数组是引用类型,它的元素相当于类的成员变量,因此数组一经分配空间,其中的每个元素也被按照成员变量同样的方式被隐式初始化。例如:
1 2 3 4 5 6 | public class Test { public static void main(String argv[]){ int a[]= new int [ 5 ]; System.out.println(a[ 3 ]); //a[3]的默认值为0 } } |
数组元素的默认初始值
1 2 3 4 5 6 7 8 9 | byte 0 short 0 int 0 long 0 float 0.0 double 0.0 char 空字符 boolean false String null |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public class Test2 { public static void main(String[] args) { byte [] a = new byte [ 3 ]; short [] b = new short [ 3 ]; int [] c = new int [ 3 ]; long [] d = new long [ 3 ]; float [] e = new float [ 3 ]; double [] f = new double [ 3 ]; char [] g = new char [ 3 ]; boolean [] h = new boolean [ 3 ]; String[] str = new String[ 3 ]; System.out.println(a[ 0 ]); System.out.println(b[ 0 ]); System.out.println(c[ 0 ]); System.out.println(d[ 0 ]); System.out.println(e[ 0 ]); System.out.println(f[ 0 ]); System.out.println(g[ 0 ]); System.out.println(h[ 0 ]); System.out.println(str[ 0 ]); } } |
输出:
1 2 3 4 5 6 7 8 9 | 0 0 0 0 0.0 0.0 false null |
注意:局部变量没有默认值
1 2 | int aa; System.out.println(aa); |
Error:(6, 28) java: 可能尚未初始化变量aa
创建基本数据类型数组
Java中使用关键字new 创建数组对象
1 2 3 4 5 6 7 8 9 10 | public class Test{ public static void main(String args[]){ int [] s; s = new int [ 10 ]; for ( int i= 0 ; i< 10 ; i++ ) { s[i] = 2 *i+ 1 ; System.out.println(s[i]); } } } |
若访问数组的下标超过合法范围, 则在运行时会抛出 ArrayIndexOutOfBoundsException,编译时不会抛
创建对象数组
1 2 3 4 5 6 7 8 9 10 11 12 13 | class MyDate{ private int day; private int month; private int year; public MyDate( int d, int m, int y){ day = d; month = m; year = y; } public void display(){ System.out.println(day + "-" + month + "-" + year); } } |
1 2 3 4 5 6 7 8 9 10 | public class Test{ public static void main(String args[]){ MyDate[] m; m = new MyDate[ 10 ]; for ( int i= 0 ; i< 10 ; i++ ) { m[i] = new MyDate(i+ 1 , i+ 1 , 1990 +i); m[i].display(); } } } |
数组初始化
注意:
Java语言中声明数组时(等号左侧变量的声明)不能指定其长度(数组中元素的数)
new后面,如果同时初始化了值,此时不能指定数组长度(因为此时,长度由初始化值的个数决定),否则,必须指定数组长度
1 2 3 4 5 6 7 | int [] a ; a = new int [ 4 ]; a[ 0 ] = 1 ; int [] a2 = new int [ 3 ]; int [] a3 = new int []{ 1 , 2 , 3 }; int [] a4 = { 1 , 2 , 3 }; |
动态初始化
数组定义与为数组元素分配空间并赋值的操作分开进行。
1 2 3 4 5 6 7 8 9 10 11 12 | int a[]; a = new int [ 3 ]; a[ 0 ] = 3 ; a[ 1 ] = 9 ; a[ 2 ] = 8 ; MyDate dates[]; dates = new MyDate[ 3 ]; dates[ 0 ] = new MyDate( 22 , 7 , 1964 ); dates[ 1 ] = new MyDate( 1 , 1 , 2000 ); dates[ 2 ] = new MyDate( 22 , 12 , 1964 ); |
注意:不支持下面写法
1 2 | int [] a = new int [ 3 ]; a = { 1 , 2 , 3 }; |
静态初始化
在定义数组的同时就为数组元素分配空间并赋值。此时等号右侧不能指定数组长度。
1 2 3 4 | int [] d = new int []{ 2 , 3 , 4 , 5 , 6 };<br>可简写为: int [] d = ( 2 , 3 , 4 , 5 , 6 ); int a[] = { 3 , 9 , 8 }; <br>String[] hobbies = new String[]{ "游戏" , "运动" };<br><br>可简写为:String[] hobbies = { "游戏" , "运动" }; MyDate dates[] = { new MyDate( 22 , 7 , 1964 ), new MyDate( 1 , 1 , 2000 ), new MyDate( 22 , 12 , 1964 ) }; |
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | package com.uncleyong; public class TestArray { public static void main(String[] args) { //1. 数组的声明 //int i = 0; int [] a = null ; //推荐使用此种方式进行声明. int b [] = null ; //注意: Java语言中声明数组时不能指定其长度(数组中元素的数) //int [5] c = null; //注意: 若没有为数组变量分配指向的内存空间, 就调用其属性, 会在运行时发生 "空指针异常",也就是调用了地址为null的对象的属性 //System.out.println(a.length); //2. 为数组分配内存空间,new后面必须指定数组长度 a = new int [ 10 ]; //3. 获取数组的长度 System.out.println(a.length); //10 //5. 对数组元素进行初始化 for ( int i = 0 ; i < a.length; i++){ a[i] = 100 + i; } //4. 访问数组的元素: 数组名[数组元素下标]. 注意: 下标从 0 开始, 所以最大值是 lengh - 1, 而不是length; //数组元素会进行默认的初始化: for ( int i = 0 ; i < a.length; i++){ System.out.println(a[i]); } //若访问数组的下标超过合法范围, 则在运行时会抛出 ArrayIndexOutOfBoundsException,编译时不会抛 //a[10] = 10; //数组的静态初始化 int [] c = { 1 , 2 , 3 , 4 , 5 }; int [] d = new int []{ 2 , 3 , 4 , 5 , 6 }; for ( int i = 0 ; i < d.length; i++){ System.out.println(d[i]); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | package com.uncleyong; import java.util.Scanner; public class Score { public static void main(String[] args) { /** * 从键盘读入学生成绩,找出最高分,并输出学生成绩等级。 * 成绩>=最高分-10 等级为’A’ 成绩>=最高分-20 等级为’B’ * 成绩>=最高分-30 等级为’C’ 其余 等级为’D’ * 提示:先读入学生人数,根据人数创建int数组,存放学生成绩。 */ //1. 创建 Scanner 类 Scanner scanner = new Scanner(System.in); //2. 读入要录入的学生人数 System.out.print( "请输入学生人数:" ); int count = scanner.nextInt(); //3. 创建一个 int 类型的数组, 用于存放学员的成绩, 数组的长度为 2 所录入数值 int [] scores = new int [count]; //4. 利用循环录入学生的成绩, 同时得到最高分. 把学生成绩录入到 3 声明的数组中. int highScore = 0 ; for ( int i = 0 ; i < scores.length; i++){ System.out.print( "请输入score:" ); scores[i] = scanner.nextInt(); if (scores[i] > highScore){ highScore = scores[i]; } } //5. 遍历 3 声明的数组, 根据最高分, 获取学生的升级等级. for ( int i = 0 ; i < scores.length; i++){ if (scores[i] >= highScore - 10 ){ System.out.println( "student " + i + " score is " + scores[i] + " grade is A" ); } else if (scores[i] >= highScore - 20 ){ System.out.println( "student " + i + " score is " + scores[i] + " grade is B" ); } else if (scores[i] >= highScore - 30 ){ System.out.println( "student " + i + " score is " + scores[i] + " grade is C" ); } else { System.out.println( "student " + i + " score is " + scores[i] + " grade is D" ); } } } } |
增强for循环
增强for循环,用来对集合进行遍历操作,也称为foreach循环(foreach本身并不是java关键字)
语法:for(元素类型 循环变量:集合){ }
适用于遍历所有元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import java.util.Arrays; public class Test { public static void main(String[] args) { int [] nums = { 1 , 2 , 3 }; // 普通的for循环 for ( int i = 0 ; i < 5 ; i++) { System.out.println(nums[i]); } System.out.println(); // 增强for循环 for ( int n : nums) { System.out.println(n); } //Arrays类的toString()方法,将数组转换为字符串 System.out.println(Arrays.toString(nums)); // [1, 2, 3],数组元素以逗号隔开,放到中括号里 } } |
栈和堆
Java中内存的分类:栈内存、堆内存
区别是:
栈的存取速度比堆要快
栈内存要小于堆内存
基本数据类型和引用数据类型
根据存储方式的不同,数据类型主要分为两种:
基本数据类型(共8种)
byte short int long float double boolean char
定义方式: 数据类型 变量名=值;
引用数据类型
除了基本数据类型和null以外的其他数据类型,如String、数组、类、接口....
定义方式: 数据类型 变量名=new 数据类型(); 其中,String类型比较特殊,因为特别常用,所以JVM对其做了优化,String name = "jack"; 定义数组,new后面不是括号,是[],如:int[] nums = new int[3];
引用类型的默认值是null
基本数据类型和引用数据类型的存储方式
基本数据类型的值存储在栈内存中
引用数据类型的名称存储在栈内存中(堆中的内存地址)、值存储在堆内存中
数组,栈中存储的是堆中的首地址,首地址+偏移地址,就可以找到不同的数组元素
值传递和引用传递
对于基本数据类型,传递的是值
对于引用数据类型,传递的是内存地址
方法传参,与变量赋值是相同的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | import java.util.Arrays; public class Test { public static void main(String[] args) { /* * 基本数据类型 */ int a = 1 ; int b = a; // 将a的值传递给b b = 2 ; System.out.println(a); System.out.println(b); /* * 引用数据类型 */ int [] c = { 1 , 2 , 3 }; int [] d = c; // 将c的内存地址传递给d,本质上指向同一块内存空间 d[ 0 ] = 666 ; System.out.println(Arrays.toString(c)); System.out.println(Arrays.toString(d)); /* * 方法传参,与变量赋值是相同的 */ change(a,c); System.out.println(a); System.out.println(Arrays.toString(c)); } public static void change( int i, int [] arr) { i = 888 ; arr[arr.length - 1 ] = 999 ; } } |
多维数组
二维数组
二维数组可以认为是特殊的一维数组,一维数组中的每个元素又是一个一维数组
分类:
规则的二维数组:第二维长度相同
不规则的二维数组:第二维长度不同
二维数组举例
int [][] a = {{1,2},{3,4,0,9},{5,6,7}};
Java中多维数组被做为数组的数组处理
Java中多维数组的声明和初始化应按从高维到低维的顺序进行
int t [][] = new int [4][];//t有4行,第一个维数不空即可
t[0] = new int[5]; //每一行都是一个有5个元素的一维数组
t[1] = new int[5];
int t1[][] = new int [][4]; // 非法,等号右侧,一维必须指定,二维可以指定也可以不指定
Java中多维数组不必须是规则矩阵形式
int[][] tt = new int[4][];
tt[0] = new int[2];
tt[1] = new int[4];
tt[2] = new int[6];
tt[3] = new int[8];
int tt[][] = new int[4][5]; // tt是一个4行5列的二维数组
多维数组初始化
静态初始化
1 2 | int intArray[][] = {{ 1 , 2 },{ 2 , 3 },{ 3 , 4 , 5 }}; int intArray1[ 3 ][ 2 ] = {{ 1 , 2 },{ 2 , 3 },{ 4 , 5 }}; //illegal,等号左边不能指定维数 |
动态初始化
1 2 3 4 5 | int a[][] = new int [ 4 ][ 5 ]; int b[][] = new int [ 3 ][] b[ 0 ] = new int [ 2 ]; b[ 1 ] = new int [ 3 ]; b[ 2 ] = new int [ 5 ]; |
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package com.uncleyong; public class TestArray { public static void main(String[] args) { //声明一个二维数组 int [][] aa = new int [ 5 ][]; //对二维数组的元素进行初始化: 二维数组的元素是一个一维数组! //遍历需要使用嵌套的 for 循环. for ( int i = 0 ; i < aa.length; i++){ aa[i] = new int [i + 1 ]; // 初始化 for ( int j = 0 ; j < aa[i].length; j++){ aa[i][j] = 1 + i * j; } } //对二维数组进行遍历 for ( int i = 0 ; i < aa.length; i++){ for ( int j = 0 ; j < aa[i].length; j++){ System.out.print(aa[i][j] + " " ); } System.out.println(); } } } |
冒泡
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import java.util.Arrays; public class Test { public static void main(String[] args) { int [] nums = { 1 , 2 , 3 , 99 , 128 }; // 外层循环控制比较的轮数 for ( int i = 0 ; i < nums.length - 1 ; i++) { // 内层循环控制每一轮比较的次数 for ( int j = 0 ; j < nums.length - i - 1 ; j++) { if (nums[j] > nums[j + 1 ]) { int temp = nums[j + 1 ]; nums[j + 1 ] = nums[j]; nums[j] = temp; } } System.out.println( "第" + (i + 1 ) + "轮:" + Arrays.toString(nums)); } System.out.println( "排序后的数组:" + Arrays.toString(nums)); } } |
数组排序
Java.util.Arrays类的 sort() 方法提供了数组元素排序功能,升序
1 2 3 4 5 6 7 8 9 10 11 12 13 | package com.uncleyong; import java.util.Arrays; public class Sort { public static void main(String[] args) { int [] number = { 5 , 900 , 1 , 5 , 77 , 30 , 64 , 700 }; Arrays.sort(number); for ( int i = 0 ; i < number.length; i++) System.out.print(number[i] + " " ); } } |
1 5 5 30 64 77 700 900
不定长参数
数据类型... 表示不定长参数,特点:
只能是方法的最后一个参数
调用方法时参数的个数任意
一个方法最多只有一个不定长参数
本质上就是一种特殊的数组,只能作为方法的形参使用
调用的时候,不定长参数个数可以是0个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public class Test{ public static void main(String[] args) { // String[] names=new String[]{"tom","jack"}; m1( 6 , new String[] { "tom" , "jack" }); //参数个数固定 m2( 6 , "tom" , "jack" , "alice" ); //传递的参数个数任意 m2( 6 , "tom" ); m2( 6 ); //也可以不传 m2( 6 , new String[] { "tom" , "jack" }); // 和上面调用m1传参类似,所以不定长参数本质上就是数组 } // 使用数组作为参数 public static void m1( int n, String[] args) { System.out.println( "m1" ); } //使用不定长参数 public static void m2( int n,String... args){ System.out.println( "不定长参数个数:" +args.length); if (args.length > 0 ){ System.out.println( "不定长参数第一个:" +args[ 0 ]); } } } |
练习题
https://www.cnblogs.com/uncleyong/p/15828510.html
__EOF__

关于博主:擅长性能、全链路、自动化、企业级自动化持续集成(DevTestOps)、测开等
面试必备:项目实战(性能、自动化)、简历笔试,https://www.cnblogs.com/uncleyong/p/15777706.html
测试提升:从测试小白到高级测试修炼之路,https://www.cnblogs.com/uncleyong/p/10530261.html
欢迎分享:如果您觉得文章对您有帮助,欢迎转载、分享,也可以点击文章右下角【推荐】一下!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!