Java 数组

数组是同一种类型数据的集合。其实数组就是一个容器。
数组的长度在创建时确定,并且创建后就不能改变。如果想存储不同类型的数据,同时存储的结构长度可以动态变化,那么就可以使用java.util包中的集合类(collection)。

数组的声明

可以声明任意类型的数组,包括基本类型和类类型的数组。数组声明包括两部分:数组的类型和数组的名字。java中数组的声明有两种格式:

  • 格式一:
int  a[] ;
Point  p[] ;
  • 列表内容
long[] m ;
Point[] p, q ;

第二种格式在数组标志“[]”后面出现的所有变量都将是数组变量,所以上面的p和q都是数组变量。
这里需要指明的是,在数组的声明中不指定数组的长度。
在java中数组是作为类来处理的,而类类型变量声明时并不创建该类的对象。所以数组声明时也不创建实例数组的数据空间,而只是给该数组变量分配了一个可用来引用该数组的引用空间。

数组的创建与初始化

new运算符创建数组
数组元素所需要的内存空间是通过new运算符或通过数组初始化分配的。new运算符创建数组的格式如下:

元素类型[] 数组名 = new 元素类型[元素个数或数组长度]
new  type[arraySize] ;

例如对前面声明的a数组进行创建它的数据空间,并指定其长度为10。

a = new int[10] ;

数组在创建后,其元素是被系统自动进行初始化的。初始化的数据跟之前讲的变量的初始化数据是一样的。通过new实例化一个数组后,就可以对数组进行赋值等操作了,如:

a[0] = 10 ;
a[1] = 5 ;

注意:
数组的索引是从0开始的,最长索引为数组长度减1。

通过初始化创建数组

java中可以在数组声明时直接给数组赋初值,如:

//声明并创建一个拥有三个元素的字符串数组name
String name[] = {"joy", "weey", "leo"} ;

等价于:

String[] name ;
name[0] = "joy" ;
name[1] = "weey" ;
name[2] = "leo" ;

或者这样创建

String name[] = new String[]{"joy", "weey", "leo"}

对象数组

声明并创建一个Point类型的对象数组:

Point[] p = new Point[3] ;
p[0] = new Point(0, 0) ;
p[1] = new Point(6, 7) ;
p[2] = new Point(12, 17) ;

p数组创建以后,让我们看一下p在内存中的布局:
1

从p数组在内存中的布局,可以看出p数组中存的都是Point类型对象的引用。

数组的长度

java中的所有数组都有一个特性变量length,它代表的是数组的元素个数,并且它被作为数组的一部分被存储起来了,通过访问该变量可以获得数组的长度,格式如下:

arrayName.length 

如获得上面name数组的长度:

len  = name.length ;

有了数组的长度,再加上数组一旦定义好,长度就不能改变的特性,我们可以由此来对数组进行越界检查。

多维数组

java语言的多维数组可以看作是数组的数组,即n维数组是n-1维数组的数组。下面以二维数组为例介绍一下多维数组。
多维数组的声明跟一维数组差不多,唯一不同的是数组标示符“[]”多了几个。

int a[][] ; 或 int[][] a ;

多维数组的实例化可以采用多种方式,并可以构造规则数组和不规则数组。

  • 直接为每一维分配内存空间

这种方法一般用于创建规则数组。

int[][] a ; //声明一个二维数组a
a = new int[3][3] ;//实例化一个6行6列元素的数组。

由于java中二维数组可以看成是一维数组中嵌套一维数组,所以创建的二维数组a实际上是分配了3个int型数组的引用空间,他们分别指向3个能容纳3个int型数值的空间。
a数组在内存中的布局如下图:
2

  • 从最高维起,分别为每一维分配空间
    这种方法可以构造不规则的数组,不规则数组的最高维(即第一维)长度必须指定,其他维可以不指定。如:
//创建一个不规则的二维数组a
int a[][] = new int[3][] ;
a[0] = new int[3] ;
a[1] = new int[5] ;
a[2] = new int[10] ;

不规则数组的实例:
创建一个二维数组,并打印出输出其中的元素。

public class ArrayTest{

    public static void main(String[] args){

        int[][] a = new int[4][]; 
        for (int i = 0; i < a.length ; i++){
            int len = (int)Math.pow(i + 1, 2) ;
            a[i] = new int[len] ;
            for (int j = 0; j < a[i].length; j++){
                a[i][j] = j ;
            }
        }
        for (int i = 0; i < a.length ; i++){
            for (int j = 0; j < a[i].length; j++){
                System.out.print(a[i][j] + " ");
            }
            System.out.println();
        }
    }
}

数组的复制

数组变量间的赋值是引用赋值,并不能实现数据的复制。如:

int[] a = new int[2] ;
int[] b ;
b = a;

上述实例实际情况如下如:
3

c从上图可以看出,a和b指向同意内存空间,对a数组中的元素进行更改,b数组中的元素也会跟着变。所以这种数组变量间的赋值,并不是真正意义上的数组复制。那什么才是真正意义上的数组复制呢?
这就要使用java.lang.System类中提供的数组复制方法了。该方法定义如下:

public static void arraycopy(Object source, 
                                     int srcIndex, 
                                     Object dest, 
                                     int desIndex, 
                                     int length)

参数解释:

source : 源数组;
srcIndex : 源数组开始复制的位置;
dest : 目的数组;
desIndex : 目的数组中开始存放复制数据的位置;
length : 复制元素的个数。

数组复制的实例:

public class ArrayCopy{
    public static void main(String[] args){
        int a[] = {1,2,3,4,5,6,7,8,9};
        int len = a.length;
        int b[] = new int[len];
        System.arraycopy(a, 0, b, 0, 5);
        for (int i = 0; i < len; i++){
            System.out.println(b[i]);
        }
    }
}

栈中存储的都是局部变量,并且变量所属的作用域一旦结束,该变量就自动释放。
特点:
后进先出

堆中存的都是数组等对象数据,凡是new创建的都存在堆中。
特点:

  1. 列表内容
  2. 堆内存中的每一个变量都有默认初始值,根据类型的不同而不同,遵循的还是变量默认初始化的规则。
public class Test{
    public static void main(String[] args){
        int b[] = new int[3];
        b[0] = 98 ;
        float x = 12.4f;
        int age[] = new int[3];  
    }
}

上面程序在内存中布局如下图所示:
4

主函数中,数组变量b,age和浮点型变量x都是局部变量,存在在栈中,而new开辟的数组b的实例,是对象,存储在堆中并且有一个首地址,然后在栈中的b变量中存储了这个首地址,表示b引用了堆内存中的一个存储。只要遇到new,就会在堆中开辟一段新的内存空间,所以对数组age又会开辟一段新的空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值