数组

理解数组:数组也是一种类型

Java的数组要求所有的数组元素具有相同的数据类型。因此,在一个数组中,数组元素的类型是唯一的;

一旦数组的初始化完成,数组在内存中所占的空间将被固定下来,因此数组的长度将不可改变。即使把某个数组元素的数据清空,但它所占的空间依然被保留,依然属于该数组,数组的长度依然不变;

Java的数组既可以存储基本类型的数据,也可以存储引用类型的数据,只要所有的数组元素具有相同的类型即可。

定义数组

type[] arrayName            //强烈推荐第一种
type arrayName[]

数组是一种引用类型的变量,因此使用它定义一个变量时,仅仅表示定义了一个引用变量,这个引用变量还未指向任何有效的内存,因此定义数组时不能指定数组的长度。而且由于定义数组只是定义了一个引用变量,并未指向任何有效的内存空间,所以还没有内存空间来存储数组元素,因此这个数组也不能使用,只有对数组进行初始化后才可以使用;

数组的初始化

Java语言中数组必须先初始化,然后才可以使用。所谓初始化,就是为数组的数组元素分配内存空间,并为每个数组元素赋初始值;

数组的初始化有如下两种方式:

  • 静态初始化:初始化时由程序员显式指定每个数组元素的初始值,由系统决定数组长度;
  • 动态初始化:初始化时程序员只指定数组长度,由系统为数组元素分配初始值;

1:静态初始化

arrayName = new type[]{element1,element2,element3,element4...}
        //定义一个int数组类型的变量,变量名为intArr.
		int[] intArr;		
		//使用静态初始化,初始化数组时只指定数组元素的初始值,不指定数组长度。
		intArr = new int[]{5, 6, 8 , 20};
		
		//定义一个Object数组类型的变量,变量名为objArr.
		Object[] objArr ;		
		//使用静态初始化,初始化数组时数组元素的类型是定义数组时数组元素类型的子类
		objArr = new String[] {"Java" , "李刚"};
		
		Object[] objArr2 ;		
		//使用静态初始化
		objArr2 = new Object[] {"Java" , "李刚"};

静态初始化还有如下简化格式:

type[] arrayName = {element1,element2,element3,element4...}

//数组的定义和初始化同时完成,使用简化的静态初始化写法
int[] a = {5, 6 , 7, 9};

2:动态初始化
动态初始化只指定数组的长度,由系统为每个数组元素指定初始值。语法格式如下:

arrayName = new type[length];


//数组的定义和初始化同时完成,使用动态初始化语法
int[] prices = new int[5];
//数组的定义和初始化同时完成,初始化数组时元素的类型是定义数组时元素类型的子类
Object[] books = new String[4];

执行动态初始化时,程序员只需指定数组的长度,即为每个数组元素指定所需的内存空间,系统将负责为这些数组元素分配初始值。指定初始值时,系统按如下规则分配初始值:

  • 数组元素的类型是基本类型中的整数类型(byte、short、int和long),则数组元素的值是0;
  • 数组元素的类型是基本类型中的浮点类型(float、double),则数组元素的值是0.0;
  • 数组元素的类型是基本类型中的字符类型(char),则数组元素的值是’\u0000’;
  • 数组元素的类型是基本类型中的布尔类型(boolen),则数组元素的值是false;
  • 数组元素的类型是引用类型(类、接口和数组),则数组元素的值是null;

使用数组

//输出objArr数组的第二个元素,将输出字符串"李刚"
System.out.println(objArr[1]);

//为objArr2的第一个数组元素赋值
objArr2[0] = "Spring";

//所有的数组都提供了一个length属性,通过这个属性可以访问到数组的长度
//使用循环输出prices数组的每个数组元素的值
for (int i = 0; i < prices.length ; i ++ )
{
	System.out.println(prices[i]);
}

foreach循环

使用foreach循环变量数组和集合元素时,无须获得数组和集合长度,无须根据索引来访问数组元素和集合元素,foreach循环自动遍历数组和集合的每个元素;

for(type variableName : array | collection)
{
	//variableName 自动迭代访问每个元素...
}
public class TestForEach
{
	public static void main(String[] args) 
	{
		String[] books = {"轻量级J2EE企业应用实战" , 
			"Struts2权威指南",
			"基于J2EE的Ajax宝典"};
		//使用foreach循环来遍历数组元素,其中book将会自动迭代每个数组元素
		for (String book : books)
		{
			System.out.println(book);
		}
	}
}

当使用foreach来迭代访问数组元素时,foreach中的循环变量相当于一个临时变量,系统会把数组元素依次赋给这个临时变量,而这个临时变量并不是数组元素,它只是保存了数组元素的值:

public class TestForEachError
{
	public static void main(String[] args) 
	{
		String[] books = {"轻量级J2EE企业应用实战" , 
			"Struts2权威指南",
			"基于J2EE的Ajax宝典"};
		//使用foreach循环来遍历数组元素,其中book将会自动迭代每个数组元素
		for (String book : books)
		{
			book = "Ruby On Rails敏捷开发最佳实践";
			System.out.println(book);
		}
		System.out.println(books[0]);
	}
}

//输出
Ruby On Rails敏捷开发最佳实践
Ruby On Rails敏捷开发最佳实践
Ruby On Rails敏捷开发最佳实践
轻量级J2EE企业应用实战

内存中的数组

实际的数组对象被存储在堆内存中;而数组对象的引用被存储在栈内存中;
在这里插入图片描述

如果堆内存中的数组不再有任何引用变量指向自己,则这个数组将成为垃圾,该数组所占的内存将会被系统的垃圾回收机制回收。因此,为了让垃圾回收机制回收一个数组所占的内存空间,可以将该数组变量赋为null,也就切断了数组引用变量和实际数组之间的引用关系,实际的数组也就成了垃圾;

public class ArrayInRam
{
	public static void main(String[] args) 
	{
		//定义并初始化数组,使用静态初始化
		int[] a = {5, 7 , 20};
		//定义并初始化数组,使用动态初始化
		int[] b = new int[4];
		//输出b数组的长度4
		System.out.println("b数组的长度为:" + b.length);
		//循环输出a数组的元素
		for (int i = 0 ; i < a.length ; i++ )
		{
			System.out.println(a[i]);
		}
		//循环输出b数组的元素
		for (int i = 0 ; i < b.length ; i++ )
		{
			System.out.println(b[i]);
		}
		//因为a是int[]类型,b也是int[]类型,所以可以将a的值赋给b。
		//也就是让b引用指向a引用指向的数组
		b = a;
		//再次输出b数组的长度变为3
		System.out.println("b数组的长度为:" + b.length);
	}
}

运行结果数组b的长度由4变为3,看起来数组长度似乎是可变的,但这只是一个假象;
牢记:定义并初始化一个数组后,在内存中分配了两个空间,一个用于存放数组的引用变量,另一个用于存放数组本身;
在这里插入图片描述

由图可知,a变量和b变量都引用了第一个数组。此时第二个数组失去了引用,变成垃圾,只有等待垃圾回收机制来回收它------但它的长度依然不会改变,直到它彻底消失;

基本类型数组的初始化

public class TestPrimitiveArray
{
	public static void main(String[] args) 
	{
		//定义一个int[]类型的数组变量。
		int[] iArr;    
		//动态初始化数组,数组长度为5。
		iArr = new int[5];
		//采用循环方式为每个数组元素赋值。
		for (int i = 0; i <iArr.length ; i++ )
		{
			iArr[i] = i + 10;
		}
	}
}

对应图解:
在这里插入图片描述
在这里插入图片描述

引用类型数组的初始化

public class Person
{
	//年龄
	public int age;
	//身高
	public double height;
	//定义一个info方法
	public void info()
	{
		System.out.println("我的年龄是:" + age + ",我的身高是:" + height);
	}
}
public class TestReferenceArray
{
	public static void main(String[] args) 
	{
		//定义一个students数组变量,其类型是Person[]。
		Person[] students;
		
		//执行动态初始化。
		students = new Person[2];
		
		//创建一个Person实例,并将这个Person实例赋给zhang变量
		Person zhang = new Person();
		//为zhang所引用的Person对象的属性赋值
		zhang.age = 15;
		zhang.height = 158;
		//创建一个Person实例,并将这个Person实例赋给lee变量
		Person lee = new Person();
		//为lee所引用的Person对象的属性赋值
		lee.age = 16;
		lee.height = 161;
		
		//将zhang变量的值赋给第一个数组元素
		students[0] = zhang;
		//将lee变量的值赋给第二个数组元素
		students[1] = lee;
		
		//下面两行代码的结果完全一样,因为lee和students[1]指向的是同一个Person实例。
		lee.info();
		students[1].info();
	}
}

对应图解:
在这里插入图片描述

多维数组

//同时初始化二维数组的2个维数
int[][] b = new int[3][4];

在这里插入图片描述

//使用静态初始化的语法来初始化一个二维数组
String[][] str1 = new String[][]{new String[3]  , new String[]{"hello"}};
//使用简化的静态初始化语法来初始化二维数组
String[][] str2 = {new String[3]  , new String[]{"hello"}};

在这里插入图片描述

书籍:疯狂Java讲义
学习所做的笔记,特此记录下来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值