JAVA中的数组

1.定义数组
type[] arrayName; //int array;

  • 定义数组只是定义了一个引用变量,未指向任何有效的内存,定义数组时不能指定数组大小,只有对数组初始化后才能使用。

2.数组的初始化
为数组元素分配内存空间,并为每个数组元素赋初始值。数组的初始化分两种:

  • ①静态初始化:初始化时指定每个元素的初始值,由系统决定数组长度 静态:arrayName = new type[]{element1,element2,…}
    此处的type必须与定义时的type类型一样,也可以是定义时的type类型的子类。
    eg:array = new int[]{1,2,3,…};
    实际开发中,习惯将定义和初始化同时完成:int[] a={1,2,3};
  • ②动态初始化:初始化时只指定数组长度,由系统为数组元素分配初始值
    ayyayName = new type[length];此处的type必须跟定义时的type类型一样,或者是它的子类。
    int[] price = new int[15];
    Object[] books=new String[4];String 是Object的子类。
    动态初始化:
    整型(byte,short,int,long),数组元素的值为0
    浮点型(float,double)值为0.0
    字符型(char)值为‘\u0000’
    布尔型(boolearn)值为false
    引用型(类,接口,数组)值为null
    注意:静态初始化和动态初始化不能同时使用,也就是说,不能在进行数组初始化的时候,既指定数组长度,又为每个数组元素分配初值。

3.foreach循环

  • foreach循环自动遍历数组和集合的每个元素,无须获得数组和集合长度,无须根据索引来访问数组元素和集合元素。

注意:当使用foreach来迭代访问数组元素时,foreach中的循环变量相当于一个临时变量,系统会把数组元素依次赋值给这个临时变量,临时变量只是保存了数组元素的值。如果希望改变数组元素的值,则不能使用foreach循环。
for(type variableName : array|collection){
variableName;
}

public class ForEachTest
{
	public static void main(String[] args)
	{
	      String[] books = {"Java1","Java2"};
	      for( String book:books)
	      {//不要对循环变量book赋值
	      System.out.println(book);
	 }
 }

4.深入数组

  • 数组是一种引用数据类型,数组元素和数组变量是分开存放的。
  • 数组引用变量只是一个引用,这个引用变量只有指向任何有效的内存,才能通过数组变量来访问数组元素。
  • 实际的数组对象被存放在堆(heap)内存中,如果引用变量是一个局部变量,则它存在栈(stack)内存中。

在这里插入图片描述
堆内存中的数组元素,只能通过p[index]的形式实现,数据引用变量(p)是访问堆内存中数据元素的根本方式。

堆内存和栈内存的区别

  • 1.所有在方法中定义的局部变量都被存放在栈内存中。当一个方法执行时,每个方法会建立一个自己的内存栈,在这个方法中定义的变量都被存放在栈内存中,随着方法的结束,这个方法的内存栈也会销毁。
  • 2.创建对象时会有堆内存。在程序中创建一个对象时,这个对象将被保存在运行时数据区中,以便反复使用,这个运行时的数据区是堆内存。只有当一个对象没有任何引用变量引用它时(成为垃圾),系统的垃圾回收器才会在合适的时候回收它。
  • 注意:如果堆内存中数组不再有任何引用变量指向它,则这个数组成为垃圾,该数组所占的内存将被系统的垃圾回收机制回收。可以将该数组变量赋为null(p=null),也就切断了数组引用变量和实际数组之间的引用关系,实际的数组就成为了垃圾。
  • 牢记:定义并初始化一个数组后,在内存中分配了两个空间,一个存放数组的引用变量(栈内存),一个存放数组本身(堆内存)。
public class ArrayInRam
{
	public static void main(String[] args)
	{
		int[] a={5,7,20};
		int[] b=new int[4];
		b=a;
	}
}

在这里插入图片描述

  • 栈内存中有两个引用变量:a,b;堆内存中有两块内存区域:分别存储a和b引用所指向的数组本身。
  • a和b都是引用类型变量,存储的是地址,b=a,就是把b指向a所指向的地址。第二个数组失去了引用,变成垃圾,等待垃圾回收机制来回收它。

注意:数组有两部分:一部分是数组引用,一部分是实际的数组对象,实际的数组对象在堆内存中,只能通过数组引用变量来访问。

int[] iArr;//存储示意图如图4.5
iArr = new int[5];//存储示意图如图4.6

在这里插入图片描述
5.引用类型数组的初始化


class Person{
	public int age;
	public double height;
	public void info(){
		System.out.println("我的年龄是:"+age+",我的身高是:"+height);
	}
}
public class ReferenceArrayTest {
	public static void main(String[] args) {
		Person[] students;//定义一个Person[]类型的students数组变量
		students = new Person[2];//动态初始化
		Person zhang = new Person();//创建一个Person实例
		zhang.age = 15;//为zhang所引用的Person对象的age,height赋值
		zhang.height = 158;
		Person lee = new Person();
		lee.age = 16;
		lee.height = 161;
		students[0] = zhang;
		students[1] = lee;
		lee.info();
		students[1].info();
	}
}

定义Person[] students时的内存空间如下
在这里插入图片描述
students = new Person[2];时的内存分配如下
在这里插入图片描述
Person zhang = new Person();
zhang.age = 15;
zhang.height = 158;
Person lee = new Person();
lee.age = 16;
lee.height = 161;
定义了zhang和lee两个Person实例,内存分配情况如下
在这里插入图片描述
students[0] = zhang;
student[1] = lee;时的内存分配情况如下
zhang和studetns[0]指向同一个内存区,它们都是引用类型变量。
在这里插入图片描述
6.没有多维数组,二维数组的实质还是一维数组
定义:type[][] arrName;
初始化:arrName = new type[length][];

  • 类似于定义了length个type[]类型的变量,这些type[]类型的变量都是数组类型,必须再次初始化这些数组。
public class TwoDimensionTest {
	public static void main(String[] args) {
		int[][] a;
		a = new int[4][];//a指向一块长度为4的数组内存,每个数组元素都是引用,默认初始值null。
		a[0] = new int[2];//初始化a数组中的第一个元素,动态初始化,默认值为0
		a[0][1] = 6;
	}
}

在这里插入图片描述

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

在这里插入图片描述
注意:如果向在JAVA中实现无限扩展的数组(一维数组,二维数组,三位数字…),需要定义一个Object[]类型的数组,这个数组的元素是Object类型,因此可以再次指向一个Object[]类型的数组,这样就可以从一维数组扩展到二维数组三维数组了.

7.Java8中增强的工具类:Arrays

Arrays类处于java.util包下,在程序中使用它时,需要在程序中导入java.util.Arrays类。

public class ArraysTest {
	public static void main(String[] args) {
		int[] a = new int[] {3,4,5,6};
		int[] a2 = new int[] {3,4,5,6};
		System.out.println("a,a2数组是否相等"+Arrays.equals(a, a2));//true
		int[] b = Arrays.copyOf(a, 6);//b=[3, 4, 5, 6, 0, 0]
		System.out.println("a,b数组是否相等"+Arrays.equals(a, b));//false
		//将数组转换成字符串
		System.out.println("b数组的元素为:"+Arrays.toString(b));
		Arrays.fill(b, 2,4,1);//b=[3, 4, 1, 1, 0, 0]
		System.out.println("b数组的元素为:"+Arrays.toString(b));
		Arrays.sort(b);//b=[0, 0, 1, 1, 3, 4]
		System.out.println("b数组的元素为:"+Arrays.toString(b));
	}
}

8.数组的应用举例

eg1.把一个浮点数转换成人民币读法字符串

import java.util.Arrays;

public class Num2Rmb {
	private String[] hanArr = {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
	private String[] unitArr = {"十","百","千"};
	private String[] divide(double num) {
		//long 和int都是整型,数据长度不同,int存放32字节长度,long存放64字节长度
		long zheng = (long)num;//获取整数部分
		//Math.round(x),获取与x最接近的整数
		long xiao = Math.round((num - zheng)*100);//获取两位小数部分
		//String.valueOf(long l) : 将 long 变量 l 转换成字符串 
		return new String[] {zheng + "", String.valueOf(xiao)};
	}
	private String toHanStr(String numStr) {
		String result = "";
		int numLen = numStr.length();
		for(int i = 0; i < numLen; i++) {
			//把char型数字转换成int型数字,它们的ASCII码差48;‘4’->4
			int num = numStr.charAt(i) - 48;
			//如果不是最后一位,并且数字不是零,则需要加单位(千,百,十)
			if(i != numLen - 1 && num != 0) {
				result += hanArr[num] + unitArr[numLen - 2 - i];
			}
			//否则不加单位
			else
				result +=hanArr[num];
		}
		return result;
	}
	public static void main(String[] args) {
		Num2Rmb nr = new Num2Rmb();
		System.out.println(Arrays.toString(nr.divide(236711125.123)));
		System.out.println(nr.toHanStr("6109"));
	}
}

注意

  • 1.long 和int都是整型,数据长度不同,int存放32字节长度,long存放64字节长度
  • 2.Math.round(x),获取与x最接近的整数
  • 3.String.valueOf(long l) : 将 long 变量 l 转换成字符串
  • 4.把char型数字转换成int型数字,它们的ASCII码差48;‘4’->4

eg2:五步棋

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值