数组
数组是一种容器,可以用来存储同种数据类型的多个值
静态初始化
完整格式如下:
int[] array = new int[]{11,22,33};
double[] array = new double[]{11.1,22.2,33.3};
但我们一般采用简化格式:
int[] array = {11,22,33};
double[] array = {11.1,22.2,33.3};
数组的地址值
执行下面的代码,可以发现:
int[] arr = {1,2,3,4,5};
System.out.println(arr);
程序输出是类似于[D@568db2f2之类的一串看不懂的东西
你可能会纳闷了,这是为啥啊。别急,有没有可能其实这是数组的地址值。
具体分析:
[代表是一个数组
D代表double
类型
@是一个间隔符号(固定格式)
568db2f2
是数组真正的地址值(16进制)
我们习惯把整体叫做数组的地址值
数组元素的访问
索引对应的值一旦被覆盖,原来的值就不存在了
数组遍历
数组的长度属性.length
for (int i = 0;i < arr.length; i ++) {
Systemout.println(arr[i]);
}
数组名.fori
+ 回车(IDEA提供的快速生成数组的方法)
一个循环最好只做一件事情
数组动态初始化
动态初始化:初始化时只指定数组长度,由系统为数组分配初始值
格式如下:
数据类型[] 数组名 = new 数据类型[数组长度]
例如:
String[] arr = new String[50];
arr[0] = "zhangsan";
arr[1] = "lisi";
默认初始化值的规律:
类型 | 默认值 |
---|---|
整数类型 | 0 |
小数类型 | 0.0 |
字符类型 | ‘/u0000’ (打印出来就是空格) |
布尔类型 | false |
引用数据类型 | null |
数组动态初始化与静态初始化的区别
动态初始化:手动指定数组长度,系统给出默认初始化值
静态初始化:手动指定数组元素,系统计算出数组长度
动态初始化适用于只明确元素个数,但是不明确具体数值,而静态初始化适用于已经明确要操作的具体数据
数组常见操作
求最值
max
初始化的值总是数组中的值总是用
max
记录最新的最大值求和
交换数据
定义一个temp变量
打乱数据
利用随机数可以得到随机索引
在使用System.out.println
打印的时候会自动换行,若使用System.out.print
打印不会自动换行
数组的内存图
Java内存分配
栈 方法运行时使用的内存,比如main方法运行进入方法栈中执行
堆 存储对象或者数组,new来创建的都存储在堆内存
方法区 存储可以运行的class文件
本地方法栈 JVM在使用操作系统功能的时候使用,与开发无关
寄存器 给CPU使用,与开发无关
在变量的内存图中直接存储数据
在数组的内存图中
在栈内存中只记录数组的地址值,而数组被存储在堆内存中
例如打印arr[1],需要先在栈内存中找到arr的地址,再从堆内存中找到这块地址的索引1即可
在堆中的每块空间之间没有任何影响
两个数组指向同一个空间的内存图
arr2 = arr1;
本人感觉和C++中的引用类似,就像是给数组起了个别名,修改数组1也会修改数组2
方法
程序当中最小的执行单元
-
提高代码复用性
-
提高代码可维护性
最简单的方法定义和调用
public static void 方法名 () {
方法体(打包起来的代码);
}
例如:
public static void playgame() {
sout;
sout;
sout;
……
}
注意方法的定义要写到main方法的外边,类的里边
调用后要回到断点
带参数的方法定义和调用
参数的数量与类型必须与方法中定义的一致,否则报错
形参和实参
形参:方法定义的参数
实参:方法调用的参数
带返回值方法的定义和调用
根据方法产生的结果去编辑其他的代码逻辑
return
关键字
public statc 返回值类型 方法名 (参数) {
方法体;
return 返回值;
}
方法的注意点
方法不调用就不执行
方法与方法之间是平级关系,不能互相嵌套定义
方法的编写顺序与执行顺序无关
返回值类型为
void
return语句不写,如果要写后面不能跟具体的数据(称为结束方法)
return
语句后面不能编写代码,因为执行不到,属于无效代码
return
关键字
方法没有返回值可以缺省,如果书写表示结束方法
方法由返回值,必须要写,表示结束方法和返回结果
方法的重载
方法重载:在同一个类中,方法名相同,参数不同的方法,与返回值无关
那何为参数不同?
个数不同
类型不同
顺序不同
参数的顺序不同可以构成重载,但是不建议
Java虚拟机会根据参数的不同来区分同名的方法
拷贝数组
方法的基本内存原理
方法占用的是栈内存(先进后出,后进先出)
基本数据类型与引用数据类型
基本数据类型
整数类型
浮点数类型
布尔类型
字符类型
引用数据类型就是除了上边的其他类型
本质区别还是内存空间:
当一个变量存储的值不是数据本身,而是数据的地址值的时候,我们就称它为引用数据类型
方法的值传递
来看一段代码:
public class Demo {
public static void main(String[] args) {
int number = 100;
sout("调用change方法前:" + number);
change(number);
sout("调用change方法后"+ number);
}
public static void change(int number) {
number = 200;
}
}
传递基本数据类型的时候,传递的是真实的数据,形参的改变不影响实际参数的值
从内存的角度分析,在栈内存中,change方法中的number确实被改成了200,但是随着change方法的结束,main方法打印的number仍然是原来的number,未被修改过
再看一段代码:
public class Demo {
public static void main(String[] args) {
int[] arr = {10,20,30};
sout("调用change方法前:" + arr[1]);
change(arr);
sout("调用change方法后:" + arr[1]);
}
public static void change(int[] arr) {
arr[1] = 200;
}
}
传递引用数据类型的时候,传递的是地址值,形参的改变,会影响实际参数的值
同样从内存的角度分析,这里要用到栈内存和堆内存,虽然有main和change两个方法,但是他们使用的都是同一个堆地址空间,因此数组会被修改