数组的基本用法
要使用数组那首当其冲的自然是要创建数组啦!
有两种形式的数组创建方法:
1,动态的数组的创建
数据类型[] 数组名称 = new 数据类型 [] { 初始化数据 }; 比如说:
int[] arr = new int[]{1, 2, 3};
//或者
int[] arr = new int[3];//未初始化的数组
各位可能会奇怪,为什么不是 int arr[] ?
其实数组也是有类型的,而int[] 就是这个数组的类型,再者有 char[] 型, double[] 型, 等等。
上面那个例子就是 int[3] 型的数组,意思是一个存放了3个整型元素的数组。
当然我们也可以写成 int arr[] 的形式也是没有问题的,只是在java编程当中我们更推荐使用代码块内的风格。
2,静态的数组初始化
int[] arr = {1, 2, 3};
相信各位一定不陌生,就不多赘述了。
但是请各位注意,[ ] 里面可千万不要加数字哦,是不允许的;
然后我们就可以使用数组啦!
3,获取数组的长度,比如说:
int[] arr = {1, 2, 3};
// 获取数组长度
System.out.println("length: " + arr.length); // 执行结果: 3
java当中一切皆对象,以上的arr就是对象,里面封装了一些成员变量,成员方法,比如{1,2,3}就是储存于里面的变量,而length则是一个可以计算长度的方法,如果不理解方法是什么,其实与C语言当中的函数大同小异啦!甚至对象都可以了解成为一个C语言当中,封装了可以处理自身的函数的结构体。
4,数组转字符串
import java.util.Arrays
int[] arr = {1,2,3,4,5,6};
String newArr = Arrays.toString(arr);
System.out.println(newArr);
// 执行结果
[1, 2, 3, 4, 5, 6]
Java 中提供了 java.util.Arrays 包, 其中包含了一些操作数组的常用方法,如上的toString方法。
数组作为方法的参数
1,数组的打印方法:
一般的我们会这样:
int[] array = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i = 0; i < array.length; i++)
{
System.out.println(array[i]);
}
但是java为我们提供了丰富的方法,比如遍历:
int[] array = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int x : array)//循环遍历
{
//int是指这个数组里面的数据是int型,
//我们每次用x这个变量来接收单个值。
System.out.println(x);//输出x
}
2, 理解引用类型
public static void main(String[] args) {
int num = 0;
func(num);
System.out.println("num = " + num);
}
public static void func(int x) {
x = 10;
System.out.println("x = " + x);
}
// 执行结果
x = 10
num = 0
我们发现, 修改形参 x 的值, 不影响实参的 num 值 这其实就是传值调用。
看看传址调用:
public static void main(String[] args) {
int[] arr = {1, 2, 3};
func(arr);
System.out.println("arr[0] = " + arr[0]);
}
public static void func(int[] a) {
a[0] = 10;
System.out.println("a[0] = " + a[0]);
}
// 执行结果
a[0] = 10
arr[0] = 10
我们发现, 在函数内部修改数组内容, 函数外部也发生改变.。 此时数组名 arr 是一个 "引用" 。当传参的时候, 是按照引用传参,而 [ ] 就是对arr的“解引用”。而这就需要我们接下来从内存说起。
JVM的划分
JVM 内存区域划分
![](https://i-blog.csdnimg.cn/blog_migrate/b1c42b883cd75f7c2efba56431e153f3.png)
程序计数器 : 只是一个很小的空间, 保存下一条执行的指令的地址。 java虚拟机栈: 重点是存储局部变量表(当然也有其他信息). 我们刚才创建的 int[] arr 这样的存储地 址的引用就是在这里保存。 本地方法栈: 本地方法栈与虚拟机栈的作用类似。只不过保存的内容是Native方法的局 部变量。在有些版本的 JVM 实现中, 本地方法栈和虚拟机栈是一起的。 堆区: JVM所管理的最大内存区域。使用 new 创建的对象都是在堆上保存 (例如前面的 new int[]{1, 2, 3} ) 方法区: 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数 据。方法编译出的的字节码就是保存在这个区域。
简而言之,数组名是一个引用变量,本质存放的是对象的地址,也称为引用指向一个对象
而引用存放在栈当中,对象存放在堆当中,如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/22419abdd96fdef229ba2abeb1e550ee.png)
局部变量和引用保存在栈上, new 出的对象保存在堆上. 堆的空间非常大, 栈的空间比较小. 堆是整个 JVM 共享一个, 而栈每个线程具有一份(一个 Java 程序中可能存在多个栈).
数组作为方法的返回值
比如,写一个方法, 将数组中的每个元素都 * 2
// 直接修改原数组
class Test {
public static void main(String[] args) {
int[] arr = {1, 2, 3};
transform(arr);
printArray(arr);
}
public static void printArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
public static void transform(int[] arr) {
for (int i = 0; i < arr.length; i++) {
arr[i] = arr[i] * 2;
}
}
}
这个代码固然可行, 但是破坏了原有数组. 有时候我们不希望破坏原数组, 就需要在方法内部创建一个新的数组, 并由 方法返回出来。
// 返回一个新的数组
class Test {
public static void main(String[] args) {
int[] arr = {1, 2, 3};
int[] output = transform(arr);
printArray(output);
}
public static void printArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
public static int[] transform(int[] arr) {
int[] ret = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
ret[i] = arr[i] * 2;
}
return ret;
}
}
这样的话就不会破坏原有数组了。 另外由于数组是引用类型, 返回的时候只是将这个数组的首地址返回给函数调用者, 没有拷贝数组内容, 从而比较高 效。
二维数组
二维数组本质上也就是一维数组, 只不过每个元素又是一个一维数组。
基本语法:
//数据类型[][] 数组名称 = new 数据类型 [行数][列数] { 初始化数据 };
int[][] arr = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
二维数组中,每个元素是其中每一个一维数组的地址,即引用。
它与C语言二维数组不同的是,该数组在内存中并不是连续储存的,因为每一个一维数组在堆中是以不同的片段储存的,进而导致存入主数组的地址差异较大。这就导致了java数组必须规定行数,但不可以强制规定列数,形成了不规则的二维数组。
比如说:
int[][] array = new int[][]{{1, 2}, {3, 4, 5}, {6, 7, 8, 9}, {10}};
int[][] array = new int[4][];
//以上定义是被允许的
int[][] array = new int[][2];
//这种定义是被禁止的
谢谢各位的围观,这次就到这里。
求求给个赞吧!