前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java程序设计(Java9版):第4章 简单复合类型

Java程序设计(Java9版):第4章 简单复合类型

作者头像
程裕强
发布2018-01-02 16:51:38
1.1K0
发布2018-01-02 16:51:38
举报

第4章 简单复合类型

4.1 数组

在C语言中,数据类型除了基本数据类型之外,还存在着大量复合数据类型。数组就是一类最简单且非常重要的复合数据类型,数组是具有相同类型变量的顺序存储的集合。几乎所有的程序设计语言都把数组设定为固有的类型,同样Java语言也有数组类型。与C语言一致,Java语言的数组也是通过数组名和下标来表示每个数组单元(也就是一个变量),数组下标从0开始。

在Java语言中,创建基本数据类型的变量与C语言格式一致,直接使用“数据类型 变量名”格式即可,比如“int i”即定义了一个int型变量i。由于创建复合数据类型的变量,相对创建基本数据类型的变量要复杂、计算机系统消耗要大,所以Java语言在创建复合数据类型的变量时要分两步完成。第一步先通过“数据类型 变量名”声明变量,只在栈内存中为变量名分配一个很小的空间,但是并没有开辟具体的数据空间;比如某一复合数据类型声明了变量a,如图2.44所示。第二步,通过new关键字在堆内存中开辟一个复合“数据类型”大小的存储空间,用于存储具体是数据实体;然后将该存储空间的地址赋值到变量名的栈存储空间内。

4.1.1 数组定义

数组是复合数据类型,所以分为数组变量声明与数组创建两步完成。

(1)声明数组名

一维数组的声明格式如下: 元素类型[] 数组名; 其中,“元素类型[]”是数组类型,比如“int[]”就是整数数组类型,这是与C语言不一样的;“数组名”就是数组类型定义的变量,与“数据类型 变量名”声明格式一致,而C语言的数组名则是常量。比如声明“int[]”型数组a,语句如下: int[] a; 实际上还有有一种声明数组的方法,就是大家熟悉的C语言格式,如下: 元素类型 数组名[]; Java保留此格式,可以使用但不建议使用,C#等语言不再支持这种古老格式,只支持第一种格式。

(2)开辟元素空间

通过new操作符在内存中为数组申请存储空间,格式如下:

代码语言:javascript
复制
数组名=new 元素类型[长度];

new是Java关键字,作用类似与C语言的动态存储分配函数(比如malloc函数),可以从内存中为数组申请“长度”个存储空间,然后将这些存储空间的首地址赋值给数组名。注意,这里的地址不同于C语言的地址或指针,Java语言没有指针。 比如开辟5个int型元素类型的空间,如图2.45所示。

代码语言:javascript
复制
a=new int[5];

实际上,可以将数组声明和开辟空间两步合并为:

代码语言:javascript
复制
元素类型[] 数组名=new 元素类型[长度];

此外,Java语言允许使用int型变量来指定数组的长度,C语言是不允许的。 比如:

代码语言:javascript
复制
int size=5;
int a=new int[size];

如果我们再声明一个整型数组b,并将数组a赋值给b,代码如下:

代码语言:javascript
复制
int[] b=a;

如图2.46所示,数组b和数组a共享同一个数组实体。数组实体相当于一个人,而数组名a相当于这个人的姓名,数组名b相当于这个人的别名,两个名字均指向同一个实体人。数据实体只有一个,而该数据实体的名字可以有多个,每个名字只是引用了数据实体。这就是Java语言中的复合数据类型的变量被称为引用变量的原因。

在Java语言,内存是可以分为栈内存和堆内存。栈内存,存储基本类型的数据和引用变量;堆内存存放复合数据类型的数据实体。数组是引用类型,所以数组名存储在栈内存中,而数组元素存储在堆内存中。

4.1.2 数组操作

(1)数组初始化

数组初始化就是为数组的元素分配内存空间,并为每个数组元素指定初始值。数组初始化有静态初始化和动态初始化两种方式。 静态初始化时只需指定每个数组元素的初始值,并由系统决定数组长度,格式如下: 元素类型[] 数组名={值1,值2,…,值n}; 比如:int[] a={1,2,3,4,5,6}; 动态初始化,即是new的工作过程,根据指定的数组长度开辟内存空间,并为每个元素分配初始值。其中,对数组元素赋初值,即是为每个数组单元指定默认值。整型的默认值是0,小数型默认值是0.0,char型默认值是’\u0000’,复合数据类型的初始值是null。

(2)length属性

与C语言的数组不同的是,Java数组提供了length属性,表示数组元素的个数。比如“int a=new int[size];”,a.length的值就是5。通过length属性可以安全访问数组,可以避免访问数组出现越界问题。

(3)访问数组元素

与C语言一致,Java数组下标从0开始。一维数组下标范围:0~数组名.length-1。通过具体的数组下标即可访问数组元素。

例4-1:遍历数组。遍历数组就是访问数组的每一个元素,这是数组最常用的操作,编写程序ArrayTest.java,代码如下。

代码语言:javascript
复制
jshell> int[] a=new int[10];
a ==> int[10] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }

jshell> for(int i=0;i<a.length;i++) //输出默认值
   ...>    System.out.print(a[i]+" ");
0 0 0 0 0 0 0 0 0 0 
jshell> for(int i=0;i<a.length;i++) //为每个元素赋值
   ...>    a[i]=i+1;

jshell> for(int i=0;i<a.length;i++)
   ...>    System.out.print(a[i]+" ");
1 2 3 4 5 6 7 8 9 10 
jshell> 

习惯上,人们也将定义数组后,第1次为数组元素显式赋值的过程称为数组初始化。

4.1.3 简单应用

例4-2:前面通过程序Fib.java求解Fibonacci数列过程中,存在一个问题,无法保存这个数列的每一项。可以通过一维数组来保存Fibonacci数列的每一项,编写程序如下。

代码语言:javascript
复制
jshell> int n=12;
n ==> 12

jshell> int[] fib=new int[n];
fib ==> int[12] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }

jshell> fib[0]=fib[1]=1;
$13 ==> 1

jshell> for(int i=2;i<fib.length;i++)
   ...>     fib[i]=fib[i-1]+fib[i-2];  //第i项等于前两项之和

jshell> for(int i=0;i<fib.length;i++)
   ...>     System.out.print(fib[i]+" ");
1 1 2 3 5 8 13 21 34 55 89 144 
jshell> 

4.1.4 二维数组

二维数组是一维数组的扩展,可以把二维数组看作特殊的一维数组,其每一个元素是一个一维数组。一维数组和二维数组使用较多,多维数组很少使用,所只讲解到二维数组。二维数组定义格式如下:

代码语言:javascript
复制
数组元素类型[][] 数组名=new 数组元素类型[长度1][长度2];

例4-3:用二维数组很容易解决杨辉三角问题。杨辉三角如下所示:

代码语言:javascript
复制
1
1   1
1   2   1
1   3   3   1
1   4   6   4  1
1   5  10  10  5   1
..   ..   ..   ..  ..   ..  ..

杨辉三角是个二维图形,可以使用二维数组存储。很容易发现杨辉三角的规则:第一列和斜边都为1;其他元素值等于上一行的同列元素与前一列的元素之和,用数组表示为a[i][j]=a[i-1][j]+a[i-1][j-1]。按照这个思路编写程序Young.java:首先定义一个10行10列的二维数组,然后对第1列和对角线赋值1,再按a[i][j]=a[i-1][j]+a[i-1][j-1]公式对其他元素进行赋值。具体代码如下。

代码语言:javascript
复制
jshell> int n=10
n ==> 10

jshell> int[][] y=new int[n][n];//数组维数可以是变量
y ==> int[10][] { int[10] { 0, 0, 0, 0, 0, 0, 0, 0, 0,  ... 0, 0, 0, 0, 0, 0, 0, 0 } }

jshell> for(int i=0;i<n;i++) 
   ...>    y[i][0]=y[i][i]=1;//初始化第1列和对角线

jshell> for(int i=2;i<n;i++)
   ...>    for(int j=1;j<i;j++)
   ...>        y[i][j]=y[i-1][j-1]+y[i-1][j];

jshell> for(int i=0;i<n;i++){
   ...>    for(int j=0;j<=i;j++)
   ...>        System.out.printf("%5d",y[i][j]);
   ...>    System.out.println();
   ...> }
    1
    1    1
    1    2    1
    1    3    3    1
    1    4    6    4    1
    1    5   10   10    5    1
    1    6   15   20   15    6    1
    1    7   21   35   35   21    7    1
    1    8   28   56   70   56   28    8    1
    1    9   36   84  126  126   84   36    9    1

jshell> 

4.1.5 Java5的foreach

在VB语言中有foreach循环语句,方便对数据集合遍历,C#语言也继承了foreach循环语句。Java 5增加了for循环功能扩展,实现了foreach循环功能,格式如下:

代码语言:javascript
复制
for( 元素类型  元素变量名:数组名或集合名){
    循环体语句;
}

例4-4:比较普通的for循环与foreach循环。

代码语言:javascript
复制
jshell> String[] str={"Java","C#","PHP","C++"};//字符串数组
str ==> String[4] { "Java", "C#", "PHP", "C++" }

jshell> for(String s:str)
   ...>    System.out.print(s+" ");
Java C# PHP C++ 
jshell> for(int i=0;i<str.length;i++)
   ...>    System.out.print(str[i]+" ");
Java C# PHP C++ 
jshell> 

显然遍历数组时foreach循环更方便。

4.1.6 Java8 增强型工具类Arrays

4.2 字符串

4.2.1 字符串变量

字符串是一类非常重要的数据。C语言是通过字符数组来存储字符串,并以“\0”作为字符串结束标志;对字符串的操作也是通过字符数组或字符指针来实现的;C语言有字符串常量的概念,字符串常量用一对双引号(”“)括起来,但是没有字符串变量的概念。可见C语言没有真正意义上的字符串数据类型,而Java语言中的字符串已经是一个完备的数据类型。Java提供了String类型来处理字符串数据,同C语言一致,字符串常量用一对双引号(”“)括起来。 本节简单认识一下String类型,关于具体的String类型将在第8章详细介绍。 例36:测试字符串类型数据简单用法。先定义一个字符串常量”Hello”,然后赋值给字符串变量s;字符串可以通过“+”运算实现字符串连接,代码如下。

代码语言:javascript
复制
jshell>  String s="Hello";  //定义一个字符串变量
s ==> "Hello"

jshell> System.out.println(s)
Hello

jshell> System.out.printf("%s,World!\n",s);
Hello,World!
$26 ==> java.io.PrintStream@3e6fa38a

jshell> System.out.println(s+",world!")
Hello,world!

jshell> 

4.2.2 遍历字符串

代码语言:javascript
复制
jshell>  String s="Hello";  //定义一个字符串变量
s ==> "Hello"

jshell> for(int i=0;i<s.length();i++)
   ...>    System.out.println(s.charAt(i))
H
e
l
l
o

jshell> 

4.3枚举

C语言中具有枚举类型,Java语言一开始不具有枚举类型,直到Java 5才重新引入枚举类型enum。

4.3.1 枚举定义

所谓“枚举”即是这种类型的变量值只能是若干指定的值之一。枚举类型通过enum关键字定义,格式如下:

代码语言:javascript
复制
enum 枚举名{ 
   枚举常量列表
}

其中,枚举常量名要符合标识符规定,与一般常量不同的是可以将枚举常量名小写。枚举常量之间用逗号分割,例如:

代码语言:javascript
复制
enum Season{//季节
        spring,summer,autumn,winter
}

Season就是一个枚举类型,它有4个常量值,可以通过“枚举类型名.枚举常量名”形式访问枚举常量。 声明一个枚举类型的变量格式与一般声明变量格式相同,例如声明一个上面定义的Season枚举型变量:

代码语言:javascript
复制
Season season;

枚举变量的值只能是枚举常量,比如:

代码语言:javascript
复制
season=Seaon.spring;

可以将一个枚举类型定义在Java源文件中,编译后得到字节码文件。

4.3.2枚举与for循环

枚举类型有一个values()方法,可以返回一个枚举常量数组。Java 5之后,可以使用for遍历枚举数据,语法上与增强的for循环变量数组一致。

例37:通过下面程序EnumTest.java测试枚举类型简单用法,代码如下。

代码语言:javascript
复制
jshell> enum Season{//季节
   ...>      spring,summer,autumn,winter
   ...> }
|  created enum Season

jshell> Season season=Season.spring;//定义一个枚举变量,取值只能是枚举常量之一
season ==> spring

jshell> System.out.println(season);
spring

jshell> for(Season s:Season.values())//遍历输出枚举类型的常量
   ...>    System.out.println(s);
spring
summer
autumn
winter

jshell>

4.3.3枚举与switch

从Java 5开始,允许switch语句的表达式是枚举类型。 例38:下面程序定义了一个Color枚举类型,然后测试switch语句对枚举类型的支持,代码如下。

代码语言:javascript
复制
jshell> enum Color{//颜色
   ...>     red,yellow,blue,white,black
   ...> }
|  created enum Color

jshell> Color c=Color.blue;
c ==> blue

jshell> switch(c){
   ...>      case red:
   ...>           System.out.println("红色");
   ...>           break;
   ...>      case yellow:
   ...>           System.out.println("黄色");
   ...>           break;
   ...>      case blue:
   ...>           System.out.println("蓝色");
   ...>           break;
   ...>      case white:
   ...>           System.out.println("白色");
   ...>           break;
   ...>      case black:
   ...>           System.out.println("黑色");
   ...>           break;
   ...>      default: 
   ...>           System.out.println("其他颜色");
   ...> }
蓝色

jshell> 
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-11-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第4章 简单复合类型
    • 4.1 数组
      • 4.1.1 数组定义
      • 4.1.2 数组操作
      • 4.1.3 简单应用
      • 4.1.4 二维数组
      • 4.1.5 Java5的foreach
      • 4.1.6 Java8 增强型工具类Arrays
    • 4.2 字符串
      • 4.2.1 字符串变量
      • 4.2.2 遍历字符串
    • 4.3枚举
      • 4.3.1 枚举定义
      • 4.3.2枚举与for循环
      • 4.3.3枚举与switch
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档