欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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("");
}

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