【6】java之数组的定义和使用

一、数组的定义与使用

1.1 数组的基本概念

数组指的就是一组相关变量的集合。

数组的定义:

  • 声明并开辟数组

    数据类型 数组名称 [] = new 数据类型[长度];

    数据类型 [] 数组名称 new 数据类型[长度];

  • 分步完成

    声明数组:数据类型 数组名称[] null;

    开辟数组: 数组名称 new 数据类型[长度];

1、当数组开辟空间后,可以采用 "数组名称[下标]" 的形式进行访问。如果超出数组长度,那么会出现数组越界异常(ArrayIndexOutOfBoundsException)。

2、以上给出的数组定义结构采用的是动态初始化方式,即:数组会先开辟内存空间,数据内容为其数据类型的默认值。

3、由于数组是一种顺序的结构,并且数组的长度都是固定的,那么可以使用循环的方式输出,很明显 for 循环,而且 java 里为了方便数组的输出提供有一个 “数组名称.length” 属性,可以取得数组的长度。

for(int i=0; i<data.length; i++){
	System.out.println( data[i]);
}

1.2 内存空间

​ 虽然数组比较简单,但是其麻烦的问题在于,它也属于引用类型,也有内存分配,与对象保存唯一的区别在于:对象中的堆内存保存的是属性内容,数组对象中的堆内存保存的是数组里的内容

举例:用内存关系来描述下面的关系

int data [] = new int [3];
data[0] = 10;
data[1] = 20;
data[2] = 30;

以上是第一种数组定义的语法,下面更换第二种:

int data [] = null;
data  = new int[3];
data[0] = 10;
data[1] =20;
data[2] =30;

1.3 数组的引用传递

既然数组属于引用数据类型,那么数组一定可以发生引用传递。

举例:数组的引用传递

int data [] = new int[3];
data[0] = 10;
data[1] =20;
data[2] =30;
int temp [] = data;
temp[0] =99;

1.4 数组的静态初始化

​ 以上数组的定义格式严格来讲是属于动态初始化,它的操作特点:先开辟数组空间,而后为数组中的内容进行赋值。

​ 和对象初始化相比,对象可以在定义时通过构造函数进行初始化。类似的:

在数组定义之中还提供有静态初始化的操作,即数组定义的同时就设置好了数组内容。

  • 格式一,简化格式: 数据类型 数组名称 [] = {值,值,值,...}

  • 格式二,完整格式: 数据类型 数组名称 [] = new 数据类型[] {值,值,值,...}

    int data [] = new int[]{10,20,30};
    for(int i=0; i<data.length; i++){
    	System.out.println( data[i]);
    }
    

在实际工作中,数组是会存在的,但是它的内容大部分情况下是通过传递的数据而动态生成的,很少使用这种先开辟数组而后去使用的情况。

​ 虽然数组支持顺序的数据访问操作,但是数组有一个最大的缺点——长度不能被改变,所以在开发之中才不会去应用数组,但是会使用到数组的概念。

二、数组与方法参数的传递

2.1 数组的引用传递

举例:一个数组传递的程序

public class ArrayDemo{
	public static void main(String args[]){
		int data [] = new int[]{11,12,13};
		changeData(data);
		for(int i=0;i<data.length; i++){
			System.out.println(data[i]);
		}
	}
	public static void changeData(int [] temp){
		for(int i=0;i<temp.length; i++){
			temp[i] = temp[i]*2;
		}
	}
}

2.2 数组排序

实现一个数组排序

下面给出(升序)排序的基本原理(冒泡排序):每次取一个数与其他数比较,如果大于则交换位置。

  • 原始数据:2,1,9,0,5,3,7,6,8;

  • 第一次排序:1、2、0、5、3、7、6、8、9 ;

  • 第二次排序:1、0、2、3、5、6、7、8、9;

  • 第三次排序:0、1、2、3、5、6、7、8、9。

    以上只是给出了排序的基础原理过程,但是会根据数据的不同会出现不同的排序次数,但是不管有多少个数据,总的排序次数不会超过数组的长度。所以只要排序的次数达到 长度*长度,那么所要排序的数组一定会排序成功。

基础的实现:

public class SortArray{
	public static void main(String args[]){
		int data [] = new int []{2,1,9,0,5,3,7,6,8};
		sort(data);
		print(data);

	}
	public static void sort(int[] arr){
		for (int i=0; i<arr.length-1; i++ ) {
			for (int j=0; j<arr.length-1 ;j++ ) {
				if (arr[j] > arr[j+1]) {
					int temp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = temp;
				}
			}
		}
	}
	public static void print(int[] arr){
		for (int i=0;i<arr.length ;i++ ) {
			System.out.print(arr[i] + "\\n");
		}
	}
}

2.3 数组转置

实现数组的转置(首尾交换)。

一维数组的实现:

原始数组:1、2、3、4、5、6、7、8;

转置后的数组:8、7、6、5、4、3、2、1;

如果要实现转置的操作,有两个思路:

  • 定义新的数组,将原始数组按照倒序的方式插入到新的数组中,随后改变原始数组引用。
public class ArrayDemo{
	public static void main(String args[]){
		int data [] = new int[]{1,2,3,4,5,6,7,8};
		int temp [] = new int[data.length];
		zhuanZhi(data,temp);
		data = temp;
		print(data);
	}
	public static void zhuanZhi(int[] arr1, int[] arr2){
		for(int i=0; i< arr2.length; i++){
			arr2[i] = arr1[arr2.length-1-i];
		}
		// arr1 = arr2;
	}
	public static void print(int [] arr){
		for(int i=0; i< arr.length; i++){
			System.out.print(arr[i]+ ",");
		}
	}
}

虽然以上的代码实现了转置,但是代码里会产生垃圾。下面看第2种方法:

  • 利用算法,在一个数组上完成转置操作:

    原始数组:1、2、3、4、5、6、7、8;

    第一次转置:8、2、3、4、5、6、7、1;

    第二次转置:8、7、3、4、5、6、2、1;

    …...

public class ArrayDemo{
	public static void main(String args[]){
		int data [] = new int[]{1,2,3,4,5,6,7,8};
		reverse(data);
		print(data);
	}
	public static void reverse(int[] arr){
		int len = arr.length/2;
		int head = 0;
		int tail = arr.length-1;
		for(int i=0; i< len; i++){
			int temp = arr[head];
			arr[head] = arr[tail];
			arr[tail] = temp;
			head++;
			tail--;
		}
	}
	public static void print(int [] arr){
		for(int i=0; i< arr.length; i++){
			System.out.print(arr[i]+ ",");
		}
	}
}

三、数组操作方法

java 本身针对于数组是有提供类库支持的。下面有两个与数组有关的操作:

3.1 数组拷贝

可以将一个数组的部分内容拷贝到另一数组中

语法: System.arraycopy(源数组名称,源数组拷贝开始索引,目标数组名称,目标数组拷贝开始索引,长度)

举例:实现数组拷贝

数组A: 1、2、3、4、5、6、7、8;

数组B: 11、22、33、44、55、66、77、88;

要求拷贝后的数组: 11、22、5、6、7、66、77、88

代码为

public class ArrayDemo{
	public static void main(String args[]){
		int dataA [] = new int[]{1,2,3,4,5,6,7,8};
		int dataB [] = new int[]{11,22,33,44,55,66,77,88};
		System.arraycopy(dataA,4,dataB,2,3);
		print(dataB);
	}
	public static void print(int [] arr){
		for(int i=0; i< arr.length; i++){
			System.out.print(arr[i]+ ",");
		}
	}
}

3.2 数组排序

​ 之前给出了排序的基本操作,但是在开发里面如果要进行排序,只需要使用如下代码即可。语法: Arrays.sort();

int data [] = new int []{3,6,1,8,0};
Arrays.sort(data);

四、对象数组(重点)

​ 数组是引用类型,对象也是引用类型,所以如果是对象数组的话表示一个引用类型里面嵌套了引用类型。之前使用的数组都是基于基本数据类型的数组,但是所有的引用数据类型也同样可以定义数组,这样的数组称为对象数组。如果要想定义对象数组(以类为例),可以采用如下的形式完成:

4.1 动态初始化

  1. 声明并开辟对象数组:

    类名称 对象数组名称[] = new 类名称[长度];

  2. 分步完成:

    • 先声明对象数组: 类名称 对象数组名称[] = null;
    • 开辟对象数组: 对象数组名称 = new 类名称[长度];

举例:对象数组的动态初始化

	Employee emp[] = new Employee[3];
	emp[0] = new Employee("Alice","Java 开发", 1000);
	emp[1] = new Employee("Bob","JSP 开发", 1000);
	emp[2] = new Employee("Candy","Android 开发", 1000);

对象数组实际上就是将多个对象交给数组管理。

4.2 静态初始化

类名称 对象数组名称[] new 类名称[]{实例化对象,...};

举例:对象数组的静态初始化

Employee emp[] = new Employee[]{	
	new Employee("Alice","Java 开发", 1000),
	new Employee("Bob","JSP 开发", 2000),
  	new Employee("Candy","Android 开发", 3000)
};

注意,这里不要写数组长度。

4.3 一段总结

  1. 数组用的很少,但是一定会用,而且数组的相关逻辑关系比较麻烦;
  2. 对象数组的定义语法,对象数组 = 多个对象。
  3. 数组有一个最大的天生短板:长度固定,这个限制了数组在开发中的出现。
  4. 数组的排序:Arrays.sort()。
posted @ 2022-06-16 19:42  才华充电中  阅读(382)  评论(0编辑  收藏  举报