J2SE学习笔记3 — Java基本语法(9)数组和枚举

3.11 数组和枚举

3.11.1 数组

1)数组的声明

数组是一种数据结构,用来存储同一类型值的集合。

   在声明数组变量时,需要指出数组类型(也就是数组中数据元素的类型)和数组变量的名字,有两种声明数组的方式:

   int[] a; 或

   int  a[]

注:大多数程序员喜欢第一种风格,因为它将类型int[](整型数组)与变量名a区分开来。

   以上语句只是声明了变量a是一个数组,并没有将a初始化为一个真正的数组(即没有分配内存空间给它),应该使用new运算符来创建数组,如:

   int[] a =new int[100]//创建一个可以存储100个整数的数组

数组可以通过下标值访问其中任何一个元素,数组的下标从0开始。一旦创建了数组,就可以给数组元素赋值。在访问数组时不允许越界访问,即如果创建了100个元素的数据而试图访问a[100](任何在0~99之外的下标),程序就会引发“array index out of bounds”异常而终止。

可以通过for each循环方便地遍历数组,如:

       /*声明并初始化一个有100个元素的整型数组*/

int[] a = new int[100];

/*数组赋值*/

       for (int i=0;i<a.length ;i++ )  //可以使用array.length获得数组中元素的个数

          a[i]=i+1;

       /*for each遍历访问数组*/

       for (int element:a )

          System.out.println(element);

       /*用常规for循环遍历访问数组*/

       for (int i=0;i<a.length ;i++ )

          System.out.println(a[i]);

注意:一旦创建了数组,就不能再改变它的大小(可以改变每个数组元素)。如果经常需要再运行过程中扩展数组的大小,就应该使用另一种数据结构—数组列表(array list)。

 

2)数组初始化以及匿名数组

Java中,提供了一种创建数组对象并同时赋予初始值的简化书写形式,如:

int[] smallInt = {2,3,5,6,7,8,9}; //不需要调用new

new int[] { 2,3,5,6,7,8,9 }可初始化一个匿名数组,数组的大小就是初始值的个数,用这种语法形式可在不创建新变量的情况下重新初始化一个数组。如

        int[] smallInt=new int[100];

        System.out.println("Array Size:"+smallInt.length);

        smallInt=new int[]{1,2,3,4,5,6,7,8};   //用匿名数组重新初始化smallInt

        System.out.println("Array Size:"+smallInt.length);

        // smallInt=new int[100]{1,2,3,4,5,6,7,8}; ->注意是语法错误

输出结果:

Array Size:100

Array Size:8

注:在Java中,允许数组长度为0,在编写一个返回结果为数组的方法时如果碰巧结果为空,则这种语法形式就有用了,可创建一个长度为0的数组:new eleType[0];注意:数组长度为0null不同。

 

3)数组拷贝

先看以下代码:

int[] luckyNumbers = smallPrimes;

luckyNumbers[5]=12; //smallprimes[5] is also 12

 

拷贝数组变量

这里将一个数组变量拷贝给另一个数组变量,如上图所示仅是变量引用的拷贝,即将两个变量引用到同一个数组空间。

   注意:

如果希望将一个数组的所有值拷贝到一个新的数组中(另一块内存区域),就要用到java.util.Arrays类的copyOf方法:

int[] copiednumbers = Arrays.copyOf (luckynumbers,luckynumbers.length);

其中第2个参数是新数组的长度,这个方法通常用来增加数组的大小,如下例:

   lukyNumbers = Arrays.copyOf (luckNumbers,2*luckyNumbers.length);

如果数组元素是数值型,那么多余元素将被赋值为0;如果数组元素是布尔型,则多余元素被赋值为false。相反如果长度小于原始数组的长度,则只拷贝原始数组最前面的数据元素。

int[] old1={1,2,3,4};

      int[] old2={11,22,33,44,55};

      old2=Arrays.copyOf(old1,old2.length); //需要在程序顶部import java.util.Arrays;

      for(int ele:old2)

          System.out.printf("%d ",ele);

输出:1 2 3 4 0

注释:在Java SE6之前,用System类的arraycopy方法将一个数组的元素拷贝到另一个数组中。调用这个方法的语法格式为:

System.arraycopy(from,fromIndex,to,toIndex,count);

数组to必须有足够的空间存放拷贝的元素。

int[] arr1={1,2,3,4,5,6};

      int[] arr2={1001,1002,1003,1004,1005,1006,1007,1008};

      System.arraycopy(arr1,2,arr2,2,4);

      for(int ele:arr2)

          System.out.printf("%d ",ele);

      System.out.println();

输出:1001 1002 3 4 5 6 1007 1008

注意:Java数组与C++数组在堆栈上有很大不同,但基本上与分配在堆(heap)上的数组指针一样,也就是说:

     int[] a = new int[100]; //java

不同于

     int  a[100]; //C++

而等同于

     int* a = new int[100];//C++ 数组指针

java中的[]运算符被预定义为检查数组边界,而且没有指针运算,即不能通过a+1得到数组的下一个元素。

 

4)命令行参数

     每个Java应用程序都有一个带String[] arg参数的main方法,该方法将可以接收一个字符串数组作为命令行参数:

     public static void mainString[] args

     args[0]    ->第一个参数(程序名不存储在args数组中)

     args[1]    ->第二个参数

    

     args.length ->参数个数

     例如:执行“java Message –g jack world”,则

     args[0]:“-g

     args[1]:“jack

     args[2]:“world

 

5)数组排序

要想对数值型数组进行排序,可以使用java.util.Arrays类中的sort方法:

int[] a = new int[10000];

Arrays.sort(a);

这个方法使用了优化的快速排序算法。

程序示例:

用数组产生一个抽彩游戏中的随机数值组合,假如抽彩是从49个数值中随机抽取6个,那么程序可能的输出结果为:

Bet the following combination.It’s make you rich

478212234

首先设置两个数组:numbers存放数值1,2,3…,n;另一数组result存放抽取出来的数值;

然后开始抽取k个数值,Math.random方法(java.lang.Math类)将返回一个01之间(包含0但不包含1)的随机浮点数,用n乘以这个浮点数,再经过强制类型转换就可以得到从0n-1之间的一个随机整数。抽取数值时通过抽取数组下标r来进行。

现在必须确保不会再次抽取到那个数值,因此这里用数组中的最后一个数值改写numbers[r],并将n-1。在抽取了k个数值之后,就可以对result数组进行排序。

import java.util.Arrays;  //java.lang.Math默认导入

public class SecondSample

{

    public static void main(String[] args)

    {

      int n=49;

      int k=6;  //随机抽取6

     

      //初始化numbersresult数组

      int[] numbers=new int[n];

      int[] result=new int[k];

     

      //numbers数组进行赋值并显示

      for (int i=0;i<numbers.length ;i++ )

          numbers[i]=i+1;

      System.out.println("numbers:");

      for (int ele:numbers )

         System.out.printf("%d ",ele);

      System.out.println();

      //随机生成不重复的下标r,将抽取元素保存到result数组

      int r=0;

      for (int i=0;i<result.length ;i++ )

      {

          r=(int)(Math.random()*n);  //随机抽取下标

          result[i]=numbers[r];

          numbers[r]=numbers[n-1];

         n-=1;                      //修正抽取下标范围

      }

      //对抽取元素进行排序并显示

      Arrays.sort(result);           //对抽取数组排序

      System.out.println("Bet the following combination.Its make you rich");

      for (int ele:result )

         System.out.printf("%d ",ele);

      System.out.println();

    }//end main()

}

 

java.util.Arrays常用API

static String  toStringtype[] a   ——jdk5.0

返回包含a中数据元素的字符串,这些数据元素被放在括号内,并用逗号分隔;

参数a类型为intlongshortcharbytebooleanfloatdouble数组

static type copyOftype[] aint length

static type copyOftype[] aint startint end   ——jdk6.0

返回与a类型相同的一个数组,其长度为length或者end-start,数组元素为a的值

typeintlongshortcharbooleanfloat

start:起始下标(包含这个值)

end  终止下标(不包含这个值),这个值可能大于a.length,这种情况下结果为0false

length:拷贝的数据元素长度,如果length大于a.length结果为0false;否则数组中只有前面length个数据元素的拷贝值;

static  void  sorttype[] a

采用优化的快速排序算法对数组进行排序

static  int  binarySearchtype[] atype v       ——jdk6.0

static  int  binarySearchtype[] aint startint endtype v

采用二分搜索算法查找值v,如果查找成功,则返回相应的下标值;否则,返回一个负数值r(-r)-1是为保持a有序v应插入的位置。

数组a:注意数组应是有序数组(二分法的前提),可先用Arrays.sort()排序;

start:起始下标(包含这个值)

end  终止下标(不包含这个值)

v:同a的数据元素类型相同的值,待查值

static  void  fill type[] atype v

将数组的所有数据元素值设置为v

static  boolean  equalstype[] atype[] b

如果两个数组大小相同,并且下标相同的元素都对应相等,返回true,否则返回false

此外,在java.lang.System类中还提供了一个arraycopy方法

static void  arraycopyObject fromint fromIndexObject toint toIndexint count)—jdk1.1

将第一个数组from中的元素拷贝到第二个数组to

from:任意类型数组

formIndex:原始数组from中待拷贝元素的起始下标

to:与from同类型的数组

toIndex:目标数组to放置拷贝元素的起始下标

count:拷贝的元素数量

 

(6) 多维数组

    多维数组使用多个下标访问数组元素,它适用于表示表格或更加复杂的排列形式。

可以使用二维数组(也称矩阵)存储这些信息,在java中声明一个二维数组如下:

double[][] balances

与一维数组一样,在调用new对多维数组进行初始化之前不能使用它,初始化如下:

balances=new double[lines][cols]

如果知道数组元素,可以不调用new,直接用简化的方式对数组进行初始化,如:

int[][] magicSquare=

{

   {2,3,4,5},

{5,10,12,34},

{5,6,7,8},

{5,43,3,2}

}

注:for each循环不能自动处理二维数组的每一个元素,它是按照行(也就是一维数组)处理的,如果要访问二维数组a的所有元素,需要使用循环嵌套,如:

fordouble[] row:a

  for(double value:row)

     do something with value

要想快速打印一个二维数组的元素列表,可以调用:

 System.out.println(Arrays.deepToString(a))

输出格式为:

[{1,2,3,4,}{11,22,33,44}{123,4,}{1,2,3,5,}]

7)不规则数组

Java在数组方面的优势:Java实际上没有多维数组,只有一维数组。多维数组被解释为“数组的数组”。

例如二维数组的balances[i]引用第i个子数组,也就是二维表的第i行,它本身就是一个数组,balance[i][j]就是引用这个数组的第j项。

由于可以单独地存取数组的某一行,所以可以让两行交换。如:

double[] temp=balances[i];

balances[i] = balances[i+1];

balances[i+1] = temp;

同时这个特性还可方便地构造一个“不规则”数组,即数组每一行可以有不同的长度。

 

要想创建一个不规则的数组,首先需要分配一个具有所含行数的数组:

int[][] odds = new int[NMAX+1][]

接下来,分配这些行:

for(int n=0n<=NMAXn++)

    odds[n]  = new int [n+1]

在分配了数组之后,如果没有超出边界,就可以采用通常的方式遍历元素了,如:

for(int i=0;i< odds.length;i++)

   for (int j=0;i< odds[i].length;j++)

   {

        odds[i][j]=…;

    }

注意:

   Java中的声明-

   double[][] balances = new double [10][6]; //java

   不同于

   double balances[10][6]//c++

   也不同于

   double (*balances)[6]=new double[10][6]; //c++

   而是创建了一个包含10个指针的一个数组,如同:

   double** balances = new double* [10]; //c++

   然后,指针数组的每一个元素被分配了一个包含6个数值的数组:

   balances[i]= new double[6]; //i=0,1,…,9

当创建new double[10][6]时这个循环将自动执行。当需要不规则数组时,只能单独地创建行数组。

 

3.11.2 枚举类型

有时候变量的取值只在一个有限的集合内,超过这个集合的值即为错误值。例如销售的衣服只有红、绿、蓝三种颜色,如果变量保存了黑色即是一个错误值。

  JDK5.0开始,可以自定义枚举类型,枚举类型包括有限个命名的值,例如:

  enum Color { REDGREENBLUE}

  这样,就可以声明这样一种类型的变量:

  Color acolor=Color.GREEN

  Color类型的变量只能存储这个类型声明中给定的某个枚举值,或者null值,null表示这个变量没有设置任何值。

 

数组小结:

(一)   数组声明和初始化

声明:

int[] a

初始化:

int[] a =new int[100]

     int[] smallInt = {2,3,5,6,7,8,9};

通过匿名数组重新初始化:

     smallInt=new int[]{1,2,3,4,5,6,7,8};

(二)   数组拷贝

变量引用关系拷贝:

      int[] luckyNumbers = smallPrimes;

luckyNumbers[5]=12; //smallprimes[5] is also 12

  数组元素值的拷贝:

     int[] copiednumbers = Arrays.copyOf (luckynumbers,luckynumbers.length);

 System.arraycopy(from,fromIndex,to,toIndex,count);

(三)命令行参数

    public static void mainString[] args

     args[0]    ->第一个参数(程序名不存储在args数组中)

     args[1]    ->第二个参数

    

     args.length ->参数个数

(四)数组排序

要想对数值型数组进行排序,可以使用java.util.Arrays类中的sort方法:

int[] a = new int[10000];

Arrays.sort(a);

这个方法使用了优化的快速排序算法。

注:Math.random方法(java.lang.Math类)将返回一个01之间(包含0但不包含1)的随机浮点数,用n乘以这个浮点数,再经过强制类型转换就可以得到从0n-1之间的一个随机整数。

(五)多维数组和不规则数组

多维数组声明和初始化:

   double[][] balances

balances=new double[lines][cols];或

int[][] magicSquare=

{

     {2,3,4,5},

{5,10,12,34},

{5,6,7,8},

{5,43,3,2}

}

不规则数组:

首先需要分配一个具有所含行数的数组:

int[][] odds = new int[NMAX+1][]

接下来,分配这些行:

for(int n=0n<=NMAXn++)

    odds[n]  = new int [n+1]

Java实际上没有多维数组,只有一维数组。多维数组被解释为“数组的数组”。

例如二维数组的balances[i]引用第i个子数组,也就是二维表的第i行,它本身就是一个数组,balance[i][j]就是引用这个数组的第j项。

数组最常用相关类之一:java.util.Arrays

 

枚举类型小结:

自定义枚举类型:enum Color { REDGREENBLUE}

定义枚举变量:   Color acolor=Color.GREEN

Color类型的变量只能存储这个类型声明中给定的某个枚举值,或者null值,null表示这个变量没有设置任何值。

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值