当前位置:首页>>Java中的数组

Java中的数组

  • 2022-07-16 08:24:45

一、 什么是数组

数组就是相同数据类型的集合。
是有序的元素序列。 若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按无序的形式组织起来的一种形式。 这些无序排列的同类数据元素的集合称为数组。

二、一维数组

定义: 一维数组是由数字组成的以单纯的排序结构排列的结构单一的数组。一维数组是计算机程序中最基本的数组。
数组的初始化:
一维数组的初始化包含以下几种

  • 数组类型 [ ] 数组名={初始化数据};
  • 数组类型 [ ] 数组名= new {数据类型 {初始化数据};
  • 数组类型 [ ] 数组名= new 数据类型 [数组长度];

代码示例:

int[] arr1= {1,2,3,4};
int[] arr2=new int[]{1,2,3,4};
int[] arr3=new int[4];

注意:
new:产生一个对象。(数组本身就是一个对象)。
引用:用来尊饭对象的地址。(如上面的arr)。
数组定义后未初始化时,默认值时0;如果数组中时引用类型则默认值为 null。
数组下标越界异常:
java.lang.Array indexOutOfBoundsException
数组的遍历:
数组名.length: 作用是求数组长度(length不是方法,而是数组的属性
for 循环遍历数组:

int[] arr = {1, 2, 3};
for (int i = 0; i < arr.length; i++) {
  System.out.print(arr[i]+" ");
}
// 执行结果
1 2 3

for-each 遍历数组:
for(变量:数组名)
for-each 是 for 循环的另外一种使用方式. 能够更方便的完成对数组的遍历. 可以避免循环条件和更新语句写错。

int[] arr = {1, 2, 3};
for (int i = 0; i < arr.length; i++) {
  System.out.println(arr[i]+" ");
}
// 执行结果
1 2 3

Arrays.toString(数组名):

import java.util.Arrays   //Arrays的导入
	int[] arr = {1,2,3,4,5,6};
	String newArr = Arrays.toString(arr);
	System.out.println(newArr);
// 执行结果
[1, 2, 3, 4, 5, 6]

数组的拷贝:
数组拷贝的几种方法:

  • System.arraycopy()
  • Arrays.copyof()
  • arraycopy()
  • 数组名.clone()

数组拷贝时分为浅拷贝和深拷贝
深拷贝:数组中存放的是简单类型,对拷贝后的数组修改不影响原数组。
浅拷贝:数组中存放的是引用类型,如果是两个引用同时执行一个对象,那么通过一个引用修改一个对象时另一个引用也会受到影响。
在数组的使用时我们经常用到Arrays方法
Arrays的导入包:import.java.util.Arrays(快捷键:alt+enter)。
这里我们需要注意System.arraycopy()和Arrays.copyof()的区别。
System.arraycopy():是被native修饰的方法。
Arrays.copyof():方法内部调用了System.arraycopy()。
数组元素查找:
数组元素查找即在数组查找所有查找的元素,并返回该元素下标。
简单的查找方法有两种:顺序查找和二分查找
顺序查找:

public static int find(int[] arr, int toFind) {
	for (int i = 0; i < arr.length; i++) {
		if (arr[i] == toFind) {
			return i;
		}
	}
	return -1; // 表示没有找到
}

二分查找:

public static int binarySearch(int[] arr,int key) {
    int left =0;
    int right = arr.length-1;
    int mid=0;
    while(left<=right) {
        mid = (left+right)/2;
        if(key<arr[mid]) {
            right=mid-1;
        } else if(key>arr[mid]) {
            left=mid+1;
        } else {
            return mid;
        }
    }
    return -1;
}

JVM的内存区域划分:
Java中的数组

  1. 程序计数器 (PC Register): 只是一个很小的空间, 保存下一条执行的指令的地址. 虚拟机栈(JVM Stack): 重点是存储局部变量表(当然也有其他信息). 我们刚才创建的 int[] arr 这样的存储地址 的引用就是在这里保存.
  2. 本地方法栈(Native Method Stack): 本地方法栈与虚拟机栈的作用类似. 只不过保存的内容是Native方法的局部 变量. 在有些版本的 JVM 实现中(例如HotSpot), 本地方法栈和虚拟机栈是一起的.
    native方法:底层由c/c++实现,运行快.
  3. 堆(Heap): JVM所管理的最大内存区域. 使用 new 创建的对象都是在堆上保存 (例如前面的 new int[]{1, 2, 3} )
  4. 方法区(Method Area): 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据. 方法编译出的的字节码就是保存在这个区域.
  5. 运行时常量池(Runtime Constant Pool): 是方法区的一部分, 存放字面量与符号引用

注意:
局部变量和引用保存在栈上, new 出的对象保存在堆上.
堆的空间非常大, 栈的空间比较小.
堆是整个 JVM 共享一个, 而栈每个线程具有一份(一个 Java 程序中可能存在多个栈)

三、维数组:

规则的数组定义:

  • 数据类型 [ ] 数组名称 = new 数据类型 [行数][列数] { 初始化数据 };
  • 数据类型 [ ] 数组名称 = new 数据类型 [行数][ ] { 初始化数据 };
int[] arr=new int[2][2]{{1,2},{3,4}};
int[] arr=new int[2][];

不规则的数组定义:

  • 数据类型 [ ] 数组名称 = new 数据类型 [ ][ ] { 初始化数据 };
int[] arr=new int[][]{{2},{3,4}};

打印二维数组:

for (int row = 0; row < arr.length; row++) {
	for (int col = 0; col < arr[row].length; col++) {
		System.out.printf("%d\t", arr[row][col]);
	}
	System.out.println(" ");
}

这种方法规则和不规则二维数组的打印都可以使用。

for (int row = 0; row < arr.length; row++) {
	for (int col = 0; col < arr[0].length; col++) {
		System.out.printf("%d\t", arr[row][col]);
	}
	System.out.println("");
}

这种方法只适用于规则的二维数组打印。

猜你喜欢