数组简介
数组: 存储相同类型的一组数据,数组也是一种数据类型,是引用数据类型。
-
定义格式一
数据类型[] 数组名 =new 数据类型[数组的长度];如:int[] arr=new int[10];
new 是在内存中分配空间,空间的大小由数组的长度和数据类型决定,在数组的内存分配完成后,会将内存的首地址返回给数组名,因此数组名是指向内存空间首地址的引用。
-
定义格式二
int[] arr={9,1,4,6,9,10};
数组案例
图解
重点,值传递还是引用传递
/***
* 基本数据类型与引用数据类型的区别
*/
public class Demo {
//显示一个数
static void show(int a) {
a += 5;
}
static void show(int[] nums) {
nums[0] += 5;
}
public static void main(String[] args) {
int a = 10;
show(a);
System.out.println(a);//10 并不是15
int[] nums = {9, 5, 2};
show(nums); //将数组的首地址传给了方法中的数组引用
System.out.println(nums[0]);//14 并不是9
//////////////////////////////////
//字符串的常量对象: 保存在常量池中
String str = "hihi";
String str2 = "hihi";
System.out.println(str == str2);//结果:true
show(str);//将str变量的内容“hihi”传给方法
System.out.println(str);//输出:hihi
String str3 = new String("hihi");
String str4 = str3;
str3 = "hehe"; //hehe在常量池不存在,则会在常量池中创建对象,str3就指向这个对象
System.out.println(str4);//输出: hihi
}
}
在Java中,变量分为以下两类:
- 对于基本数据类型变量(int、long、double、float、byte、boolean、char),Java是传值的副本。
- 对于一切对象型变量,Java都是传引用的副本。其实传引用副本的实质就是复制指向地址的指针(对于对象参数变量则传对象的地址)
需要注意的是:String类型也是对象型变量,所以它必然是传引用副本。String类是final类型的,因此不可以继承和修改这个类。
不管Java参数的类型是什么,一律传递参数的副本。
数据交换
/**
* 数据交换
*/
public class Demo{
public static void main(String[] args) {
int a = 10, b = 30;
System.out.println(a + "," + b);
swap(a, b);
int[] nums = {100, 200};
swap(nums);
}
//交换a和b的数值
static void swap(int a, int b) {
/*int c=a;
a=b;
b=c;
*/
a = a + b;
b = a - b;
a = a - b;
System.out.println(a + "," + b);
}
//方法参数: 引用类型
static void swap(int[] nums) {
swap(nums[0], nums[1]);
System.out.println(nums[0] + "," + nums[1]); //此时数组中的数值不会改变
int c = nums[0];
nums[0] = nums[1];
nums[1] = c;
System.out.println(nums[0] + "," + nums[1]); //此时,两个数值已交换
}
}
增强for循环
格式
for(数据类型 变量名:数组名){ 循环体 }
过程: 将数组中数从0的位置依次读取, 不好之处在于在循环体中无法访问 当前读取的索引值。
增强for 循环举例
public class Demo{
public static void main(String[] args) {
//动态生成10个随机数(1~100),并读取(打印)
int[] nums = new int[10];
for (int i = 0; i < nums.length; i++) {
nums[i] = (int) (Math.random() * 100 + 1); //生成1~100之间的随机数
}
//打印
for (int n : nums) {
System.out.print(n + "\t");
}
}
}
二维数组
定义格式:
数据类型[][] 数组名 = new 数据类型[行大小][列大小];
数据类型[][] 数组名 =new 数据类型[][]{{1,3,2},{2,3,4},{},{0,9,2}}
数据类型[][] 数组名 ={{1,3,2},{2,3,4},{},{0,9,2}}
二维数组案例
public class Demo{
public static void main(String[] args) {
int[][] scores = new int[][]{{90, 80, 100}, {92, 90, 100}, {91, 95, 96}, {95, 100, 100}, {97, 98, 100}};
//循环一维数组:行
for (int i = 0; i < scores.length; i++) {
System.out.print("第 " + (i + 1) + " 人的成绩:");
//循环二维数组: 列
for (int j = 0; j < scores[i].length; j++) {
if (j != scores[i].length - 1)
System.out.print(scores[i][j] + ",");
else
System.out.print(scores[i][j] + "\n");
}
}
}
}
方法补充
递归方法
自己调用自己的方法,递归方法要求有两个点,一是递归公式,另一个是递归条件。
-
例子一 递归求阶乘
/** * 递归求阶乘 * * @param n */ private static int fun(int n) { if (n == 0 || n == 1) { return 1; } return n * fun(n - 1); }
-
例子二 兔子生兔子的问题
3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?/** * 古典兔子 * * @param x * @return */ public static int getNums(int x) { int nums = 1; if (x == 1 || x == 2) { return nums; } return getNums(x - 1) + getNums(x - 2); }
考点
当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?(值传递还是引用传递)
是值传递。Java语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对对象引用的改变是不会影响到调用者的。