Java程序设计(Java9版):第4章 简单复合类型
来源:互联网 发布:巨灵数据库账号 编辑:程序博客网 时间:2024/06/05 12:01
第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操作符在内存中为数组申请存储空间,格式如下:
数组名=new 元素类型[长度];
new是Java关键字,作用类似与C语言的动态存储分配函数(比如malloc函数),可以从内存中为数组申请“长度”个存储空间,然后将这些存储空间的首地址赋值给数组名。注意,这里的地址不同于C语言的地址或指针,Java语言没有指针。
比如开辟5个int型元素类型的空间,如图2.45所示。
a=new int[5];
实际上,可以将数组声明和开辟空间两步合并为:
元素类型[] 数组名=new 元素类型[长度];
此外,Java语言允许使用int型变量来指定数组的长度,C语言是不允许的。
比如:
int size=5;int a=new int[size];
如果我们再声明一个整型数组b,并将数组a赋值给b,代码如下:
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,代码如下。
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数列的每一项,编写程序如下。
jshell> int n=12;n ==> 12jshell> 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 ==> 1jshell> 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 二维数组
二维数组是一维数组的扩展,可以把二维数组看作特殊的一维数组,其每一个元素是一个一维数组。一维数组和二维数组使用较多,多维数组很少使用,所只讲解到二维数组。二维数组定义格式如下:
数组元素类型[][] 数组名=new 数组元素类型[长度1][长度2];
例4-3:用二维数组很容易解决杨辉三角问题。杨辉三角如下所示:
11 11 2 11 3 3 11 4 6 4 11 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]公式对其他元素进行赋值。具体代码如下。
jshell> int n=10n ==> 10jshell> 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 1jshell>
4.1.5 Java5的foreach
在VB语言中有foreach循环语句,方便对数据集合遍历,C#语言也继承了foreach循环语句。Java 5增加了for循环功能扩展,实现了foreach循环功能,格式如下:
for( 元素类型 元素变量名:数组名或集合名){ 循环体语句;}
例4-4:比较普通的for循环与foreach循环。
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;字符串可以通过“+”运算实现字符串连接,代码如下。
jshell> String s="Hello"; //定义一个字符串变量s ==> "Hello"jshell> System.out.println(s)Hellojshell> System.out.printf("%s,World!\n",s);Hello,World!$26 ==> java.io.PrintStream@3e6fa38ajshell> System.out.println(s+",world!")Hello,world!jshell>
4.2.2 遍历字符串
jshell> String s="Hello"; //定义一个字符串变量s ==> "Hello"jshell> for(int i=0;i<s.length();i++) ...> System.out.println(s.charAt(i))Hellojshell>
4.3枚举
C语言中具有枚举类型,Java语言一开始不具有枚举类型,直到Java 5才重新引入枚举类型enum。
4.3.1 枚举定义
所谓“枚举”即是这种类型的变量值只能是若干指定的值之一。枚举类型通过enum关键字定义,格式如下:
enum 枚举名{ 枚举常量列表}
其中,枚举常量名要符合标识符规定,与一般常量不同的是可以将枚举常量名小写。枚举常量之间用逗号分割,例如:
enum Season{//季节 spring,summer,autumn,winter}
Season就是一个枚举类型,它有4个常量值,可以通过“枚举类型名.枚举常量名”形式访问枚举常量。
声明一个枚举类型的变量格式与一般声明变量格式相同,例如声明一个上面定义的Season枚举型变量:
Season season;
枚举变量的值只能是枚举常量,比如:
season=Seaon.spring;
可以将一个枚举类型定义在Java源文件中,编译后得到字节码文件。
4.3.2枚举与for循环
枚举类型有一个values()方法,可以返回一个枚举常量数组。Java 5之后,可以使用for遍历枚举数据,语法上与增强的for循环变量数组一致。
例37:通过下面程序EnumTest.java测试枚举类型简单用法,代码如下。
jshell> enum Season{//季节 ...> spring,summer,autumn,winter ...> }| created enum Seasonjshell> Season season=Season.spring;//定义一个枚举变量,取值只能是枚举常量之一season ==> springjshell> System.out.println(season);springjshell> for(Season s:Season.values())//遍历输出枚举类型的常量 ...> System.out.println(s);springsummerautumnwinterjshell>
4.3.3枚举与switch
从Java 5开始,允许switch语句的表达式是枚举类型。
例38:下面程序定义了一个Color枚举类型,然后测试switch语句对枚举类型的支持,代码如下。
jshell> enum Color{//颜色 ...> red,yellow,blue,white,black ...> }| created enum Colorjshell> Color c=Color.blue;c ==> bluejshell> 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>
- Java程序设计(Java9版):第4章 简单复合类型
- Java程序设计(Java9版):第3章 流程控制
- Java程序设计(Java9版):第0章 绪论(Introduction)
- Java程序设计(Java9版):第1章 Java开发环境配置 (Set up Java development environment)
- Java程序设计(Java9版):第2章 数据类型与运算符(Data types and Operators)
- 第4章 复合类型
- 第4章 复合类型
- 第4章——复合类型
- C++学习第4章 复合类型
- [c++primeplus6th]-第4章.复合类型
- C++ primer plus 第4章 复合类型
- 【C++】第4章 复合类型 知识总结
- 【读书笔记:C++ primer plus 第六版 中文版】第4章 复合类型
- c++ primer第五版(中文)习题答案 第二章第三节-复合类型
- 第三天(复合类型 · 一)
- Hadoop 高级程序设计(一)---复合键 自定义输入类型
- 第四章 复合类型(4)
- Java基本类型(传值)复合类型(引用)
- 直方图最大矩形问题
- 多线程_创建方式
- 谷歌的新CNN特征可视化方法,构造出一个华丽繁复的新世界
- 深度学习系列之一:基础入门与全连接神经网络 | 公开课
- javaSe算法之冒泡排序
- Java程序设计(Java9版):第4章 简单复合类型
- 解决Nginx无法开启 和 80端口被占用
- Effective Java
- CentOS7.x中mysql的安装
- 从 Liberty 到 Ocata 的 OpenStack 版本升级之旅
- Spark-shell 启动报错Error occurred during initialization of VMToo small initial heap
- Nova环境下的GPU集成
- 子类继承父类
- C++对C功能扩展的小结