JAVA从入门到精通
2023-06-08 20:48:10 0 举报
AI智能生成
JAVA思维导图
作者其他创作
大纲/内容
第一篇 基础知识
第一章 初识JAVA
JAVA简介
认识什么是JAVA
java是于1995年由Sun公司推出的一种极富创造力的面向对象的程序设计语言。
JAVA语言的特性
1.简单
2.面向对象
3.分布性
4.可移植性
5.解释性
6.安全性
7.健壮性
8.多线性
9.高性能
10.动态
搭建JAVA环境
JDK下载
打开浏览器,输入网址http://jdk.java.net,在页面下方的Reference implementations栏右侧单击11超链接,进入JDK11的详情页面。在JDK11的详情页中,单击Windows/x64 java Development Kit超链接,即可下载JDK11的压缩包,再将压缩包中所有的文件解压到计算机硬盘中
配置环境变量
右击桌面的“此电脑”的图标,选择“属性”命令,再单击“高级系统设置”。然后打开“系统属性”对话框,单击“变量”,选中“系统变量”中的path变量,再单击“编辑”按钮。之后单击“编辑环境变量”对话框中的“新建”按钮,将解压完成的JDK根目录路径下的bin路径填充到出现的空环境变量中,最后单击“确定”。
第二章 熟悉Eclipse开发工具
熟悉Eclipse
Eclipse简介
Eclipse基于JAVA语言编写,是目前最流行的JAVA集成开发工具之一。
下载Eclipse
打开浏览器,在地址栏输入https://www.eclipse.org/downloads/后按回车进入Eclipse官网,然后单击Download Package进入Eclipse IDE Downloads页面,在Eclipse IDE for java Developers下载列表中单击Windows 64-bit.再单击Download按钮
使用Eclipse
单击file,再单击New,再单击java project,project name是项目名,注意用英文,首字母大写,因为国际惯例。找到javaSE-11,点击nextsrc是我们所以Java程序放的地方,它会自己生成。点击Finish进入下一步。有些电脑会自动弹出,但有些不会,不会的进行下一步,自动弹出的忽略。点击Window,点击Window,点击src的下拉菜单删除src下的文件,右击New,选择class文件,新建class文件,新建文件名,将public static void main(String[] args)勾选上,这样等一下就会自动生成一串基础代码。点击finish进入下一步
程序调试
1.断点
设置断点是程序调试中必不可少的手段,Java调试器每次遇到程序断点时都会将当前线程挂起,即暂停当前程序的运行。可以在Java编辑器中显示代码行号的位置双击添加或删除当前行的断点,或者在当前行号的位置右击,在弹出的快捷菜单中选择“切换断点”命令实现断点的添加与删除。
2.以调试方式运行JAVA程序
要在Eclipse中调试HelloJava程序,可以在“包资源管理器”视图中的HelloJava文件处右击,在弹出的快捷菜单中选择“调试方式”/“Java应用程序”命令。
3.程序调试
程序执行到断点被暂停后,可以通过“调试”视图工具栏上的按钮执行相应的调试操作,如运行、停止等
下面对“调试”视图中的两个关键操作进行简要介绍:
单步跳过。在“调试”视图的工具栏中按F6键,将执行单步跳过操作,即运行单独的一行程序代码,但是不进入调用方法的内部,然后跳到下一个可执行点并暂挂线程。说明:不停地执行单步跳过操作,会每次执行一行程序代码,直到程序结束或等待用户操作
单步跳入。在“调试”视图的工具栏中单击[插图]按钮或按F5键,将跳入调用方法或对象的内部,单步执行程序并暂挂线程。
第三章 JAVA语言基础
主类结构
包声明
一个Java应用程序是由若干个类组成的
成员变量与局部变量
通常将类的属性称为类的全局变量(成员变量),将方法中的属性称为局部变量。全局变量声明在类体中,局部变量声明在方法体中。全局变量和局部变量都有各自的应用范围。
主方法
main()方法是类体中的主方法。该方法从“{”开始,至“}”结束。public、static和void分别是main()方法的权限修饰符、静态修饰符和返回值修饰符,Java程序中的main()方法必须声明为public static void。String[] args是一个字符串类型的数组,它是main()方法的参数。main()方法是类体中的主方法。该方法从“{”开始,至“}”结束。public、static和void分别是main()方法的权限修饰符、静态修饰符和返回值修饰符,Java程序中的main()方法必须声明为public static void。String[] args是一个字符串类型的数组,它是main()方法的参数
导入其他类
在Java语言中可以通过import关键字导入相关的类。在JDK的API中(应用程序接口)提供了130多个包,如java.awt、java.io等。可以通过JDK的API文档来查看这些包中的类,把握类的继承结构、类的应用、成员变量表、构造方法表等,并对每个变量的使用目的进行了解,API文档是程序开发人员不可或缺的工具。
基本数据类型
整数类型
整数类型简称整型,用来存储整数数值,即没有小数部分的数值。可以是正数,也可以是负数。整型数据根据它所占内存大小的不同,可分为byte、short、int和long 4种类型。它们具有不同的取值范围。
int型
定义int型变量有以下4种语法:int变量在内存中占4字节,也就是32位bit,在计算机中bit是由0和1来表示的,所以int型值5在计算机中是这样显示的:00000000 00000000 00000000 00000101 int型是Java整型值的默认数据类型。当对多个尚未定义数据类型的整数做运算时,运算的结果将默认为int类型。
byte型
byte型的定义方式与int相同。定义byte类型变量,代码如下:byte a;
byte a, b, c;
byte a = 19, b = -45;
byte a, b, c;
byte a = 19, b = -45;
short型
short型的定义方式与int相同。定义short类型变量
long型
由于long型的取值范围比int型大,且属于高精度数据类型,所以在赋值时要和int型做出区分,需要在整数后加L或者l(小写的L)。定义long类型变量
注意
整数在Java程序中有3种表示形式,分别为十进制、八进制和十六进制:(1)十进制:十进制的表现形式大家都很熟悉,如120、0、-127。除了数字0,不能以0作为其他十进制数的开头。(2)八进制:如0123(转换成十进制数为83)、-0123(转换成十进制数为-83)。八进制数必须以0开头。(3)十六进制:如0x25(转换成十进制数为37)、0Xb01e(转换成十进制数为45086)。十六进制数必须以0X或0x开头。
浮点类型
浮点类型简称浮点型,用来存储含有小数部分的数值。Java语言中浮点类型分为单精度浮点类型(float)和双精度浮点类型(double),它们具有不同的取值范围。在默认情况下小数都被看作double型,若想使用float型小数,则需要在小数后面添加F或f。另外,可以使用后缀d或D来明确表明这是一个double类型数据,但加不加d或D并没有硬性规定。而定义float型变量时,如果不加F或f,系统会认为是double类型数据,进而出错。定义浮点类型变量。
误区警:示浮点值属于近似值,在系统中运算后的结果可能与实际有偏差。【例3.2】根据身高体重计算BMI指数(实例位置:资源包\TM\sl\3\2)创建BMIexponent类,声明double型变量height来记录身高,单位为米;声明int型变量weight记录体重,单位为千克;根据BMI=体重/(身高×身高)计算BMI指数。
字符类型
char型
字符类型(char)用于存储单个字符,占用16位(两个字节)的内存空间。在定义字符型变量时,要以单引号表示,如's'表示一个字符。但是"s"则表示一个字符串,虽然只有一个字符,但由于使用双引号,它仍然表示字符串,而不是字符。使用char关键字可定义字符变量,其语法如下:char x = 'a';由于字符a在Unicode表中的排序位置是97,因此允许将上面的语句写成char x = 97;同C和C++语言一样,Java语言也可以把字符作为整数对待。由于Unicode编码采用无符号编码,可以存储65536个字符(0x0000~0xffff),所以Java中的字符几乎可以处理所有国家的语言文字。若想得到一个0~65536的数所代表的Unicode表中相应位置上的字符,也必须使用char型显式转换。String类型为字符串类型,可以用来保存由多个字符组成的文本内容,其用法与字符类型类似
转义字符
转义字符是一种特殊的字符变量,它以反斜杠“\”开头,后跟一个或多个字符。转义字符具有特定的含义,不同于字符原有的意义,故称“转义”。例如,printf函数的格式串中用到的“\n”就是一个转义字符,意思是“回车换行”。将转义字符赋值给字符变量时,与字符常量值一样需要使用单引号。
布尔类型
布尔类型又称逻辑类型,简称布尔型,通过关键字boolean来定义布尔类型变量。布尔类型只有true和false两个值,分别代表布尔逻辑中的“真”和“假”。布尔值不能与整数类型进行转换。布尔类型通常被用在流程控制中,作为判断条件。
变量与常量
在程序执行过程中,其值不能被改变的量称为常量,其值能被改变的量称为变量。变量与常量的命名都必须使用合法的标识符。
标识符和关键字
标识符
标识符可以简单地理解为一个名字,是用来标识类名、变量名、方法名、数组名、文件名的有效字符序列。Java语言规定标识符由任意顺序的字母、下画线(_)、美元符号($)和数字组成,并且第一个字符不能是数字。标识符不能是Java中的关键字(保留字)
下面是合法标识符:
name
user_age
$page
user_age
$page
下面是非法标识符:
4word
String
User name
String
User name
在Java语言中,标识符中的字母是严格区分大小写的,如good和Good是不同的两个标识符。Java语言使用Unicode标准字符集,最多可以标识65535个字符。因此,Java语言中的字母不仅包括通常的拉丁文字a、b、c等,还包括汉语、日语以及其他许多语言中的文字。题
关键字
关键字又称保留字,是Java语言中已经被赋予特定意义的一些单词,不可以把这些单词作为标识符来使用。
声明变量
声明变量是告诉编译器这个变量的数据类型,在程序运行过程中,空间内的只是变化的,这个内存空间就称为变量,在声明变量时可以赋值,也可以直接赋给初值。
声明常量
在程序运行过程中一直不会改变的量称为常量,也称为“final变量”。常量在整个程序中只能被赋值一次。
在Java语言中声明一个常量,除了要指定数据类型,还需要通过final关键字进行限定。常量名通常是用大写字母,但这并不是必须的。
当变量被final关键字修饰时,该变量就变成了常量,必须在定义时就设定它的初值,否则将会产生编译错误。
在Java语言中声明一个常量,除了要指定数据类型,还需要通过final关键字进行限定。常量名通常是用大写字母,但这并不是必须的。
当变量被final关键字修饰时,该变量就变成了常量,必须在定义时就设定它的初值,否则将会产生编译错误。
变量的有效范围
变量的有效范围是指程序代码能够访问该变量的区域,若超出该区域,则在编译时会出现错误。在程序中,一般会根据变量的“有效范围”将变量分为“成员变量”和“局部变量”。
在类体中所声明的变量被称为成员变量,成员变量在整个类中都有效。类的成员变量又可分为两种,即静态变量和实例变量。对于静态变量,除了能在声明它的类内存取,还能直接以“类名.静态变量”的方式在其他类内食用。
在类的方法体中声明的变量(方法内部定义,"{"与"}"之间的代码中声明的变量)称为局部变量。局部变量只在当前代码块中有效,也就是只能在"{"与"}"之内使用。
局部变量可与成员变量的名字相同,此时成员变量将被隐藏,即这个成员变量在此方法中暂时失效。局部变量采取就近原则。
在类体中所声明的变量被称为成员变量,成员变量在整个类中都有效。类的成员变量又可分为两种,即静态变量和实例变量。对于静态变量,除了能在声明它的类内存取,还能直接以“类名.静态变量”的方式在其他类内食用。
在类的方法体中声明的变量(方法内部定义,"{"与"}"之间的代码中声明的变量)称为局部变量。局部变量只在当前代码块中有效,也就是只能在"{"与"}"之内使用。
局部变量可与成员变量的名字相同,此时成员变量将被隐藏,即这个成员变量在此方法中暂时失效。局部变量采取就近原则。
运算符
赋值运算符
赋值运算符以符号“=”表示,它是一个二元运算符(对两个操作数作处理),其功能是将右方操作数所含的值赋给左方的操作数。例如:int a = 100;该表达式是将100赋值给变量a。左方的操作数必须是一个变量,而右边的操作数则可以是任何表达式,包括变量(如a、number)、常量(如123、'book')、有效的表达式(如45 * 12)。由于赋值运算符“=”处理时会先取得右方表达式处理后的结果,因此一个表达式中若含有两个以上的“=”运算符,会从最右方的“=”开始处理。
算数运算符
Java中的算术运算符主要有+(加)、-(减)、*(乘)、/(除)、%(求余),它们都是二元运算符。其中,“+”和“-”运算符还可以作为数值的正负符号,如+5、-7。
注意:在进行除法运算时,0不能做除数。例如,对于语句“int a = 5 / 0;”,系统会抛出ArithmeticException异常。
自增和自减运算符
自增、自减运算符是单目运算符,可以放在操作元之前,也可以放在操作元之后。操作元必须是一个整型或浮点型变量。自增、自减运算符的作用是使变量的值增1或减1。放在操作元前面的自增、自减运算符,会先将变量的值加1(减1),然后再使该变量参与表达式的运算。放在操作元后面的自增、自减运算符,会先使变量参与表达式的运算,然后再将该变量加1(减1)例如:++a(--a) //表示在使用变量a之前,先使a的值加(减)1
a++(a--) //表示在使用变量a之后,使a的值加(减)1 粗略地分析,“++a”与“a++”的作用都相当于a = a + 1。假设a = 4,则:b = ++a; //先将a的值加1,然后赋给b,此时a值为5,b值为5 再看另一个语法,同样假设a = 4,则:b = a++; //先将a的值赋给b,再将a的值变为5,此时a值为5,b值为4
a++(a--) //表示在使用变量a之后,使a的值加(减)1 粗略地分析,“++a”与“a++”的作用都相当于a = a + 1。假设a = 4,则:b = ++a; //先将a的值加1,然后赋给b,此时a值为5,b值为5 再看另一个语法,同样假设a = 4,则:b = a++; //先将a的值赋给b,再将a的值变为5,此时a值为5,b值为4
比较运算符
比较运算符属于二元运算符,用于程序中的变量之间、变量和自变量之间以及其他类型的信息之间的比较。比较运算符的运算结果是boolean型。当运算符对应的关系成立时,运算结果为true,否则为false。所有比较运算符通常作为判断的依据用在条件语句中。
逻辑运算符
返回类型为布尔型的表达式,如比较运算,可以被组合在一起构成一个更复杂的表达式。这是通过逻辑运算符来实现的。逻辑运算符包括&(&&)(逻辑与)、||(逻辑或)、!(逻辑非)。逻辑与算符的操作元必须是boolean型数据。&&、&:两者为真,结果才为真 ||:只要有一者为真,结果才为真 !:非真即假,非假即真
位运算符
位运算符除“按位与”和“按位或”运算符外,其他只能用于处理整数的操作数,包括byte、short、char、int和long等数据类型。位运算是完全针对位方面的操作。整型数据在内存中以二进制的形式表示,如int型变量7的二进制表示是00000000 00000000 00000000 00000111。左边最高位是符号位,最高位是0表示正数,若为1则表示负数。负数采用补码表示,如-8的二进制表示为111111111 111111111 1111111 11111000。这样就可以对整型数据进行按位运算。
“按位与”运算
按位与”运算的运算符为“&”,为双目运算符。“按位与”运算的运算法则是:如果两个整型数据a、b对应位都是1,则结果位才是1,否则为0。如果两个操作数的精度不同,则结果的精度与精度高的操作数相同
“按位或”运算
“按位或”运算的运算符为“|”,为双目运算符。“按位或”运算的运算法则是:如果两个操作数对应位都是0,则结果位才是0,否则为1。如果两个操作数的精度不同,则结果的精度与精度高的操作数相同
“按位取反”运算
按位取反”运算也称“按位非”运算,运算符为“~”,为单目运算符。“按位取反”就是将操作数二进制中的1修改为0,0修改为1
“按位取反”运算
按位异或”运算的运算符是“^”,为双目运算符。“按位异或”运算的运算法则是:当两个操作数的二进制表示相同(同时为0或同时为1)时,结果为0,否则为1。若两个操作数的精度不同,则结果的精度与精度高的操作数相同
移位操作
Java中的位移运算有三种:
1、<<:左移。(整体左移,空位补0,溢出去掉)
2、>>:右移。(整体右移,整数补0,负数补1,溢出去掉)
3、>>>:无符号右移。(整体右移,空位补0,溢出去掉)
1、<<:左移。(整体左移,空位补0,溢出去掉)
2、>>:右移。(整体右移,整数补0,负数补1,溢出去掉)
3、>>>:无符号右移。(整体右移,空位补0,溢出去掉)
三元运算符
三元运算符的使用格式为:条件式 ? 值1 : 值2 三元运算符的运算规则为:若条件式的值为true,则整个表达式取值1,否则取值2。例如:boolean b = 20 < 45 ? true : false; 上述程序表达式“20 < 45”的运算结果返回真,那么boolean型变量b取值为true。相反,如果表达式的运算结果返回为假,则boolean型变量b取值为false。三元运算符等价于if…else语句。
运算符的优先级
Java中的表达式就是使用运算符连接起来的符合Java规则的式子。运算符的优先级决定了表达式中运算执行的先后顺序。通常,优先级由高到低的顺序依次是:增量和减量运算>算术运算>比较运算>逻辑运算>赋值运算 如果两个运算有相同的优先级,那么左边的表达式要比右边的表达式先被处理。表3.9显示了在Java中众多运算符特定的优先级。
数据类型转换
类型转换是将一个值从一种类型更改为另一种类型的过程。例如,可以将String类型的数据“457”转换为数值型,也可以将任意类型的数据转换为String类型。如果从低精度数据类型向高精度数据类型转换,则永远不会溢出,并且总是成功的;而把高精度数据类型向低精度数据类型转换时,则会有信息丢失,有可能失败。
隐式类型转换
低级类型向高级类型的转换,系统将自动执行,程序员无须进行任何操作。这种类型的转换称为隐式转换。下列基本数据类型会涉及数据转换,不包括逻辑类型和字符类型。这些类型按精度从低到高排列的顺序为byte < short < int < long <float < double。例如,可以将int型变量直接赋值给float型变量,此时int型变量将隐式转换成float型变量。代码如下:int x = 50; //声明int型变量x
float y = x; //将x赋值给y,y的值为50.0 隐式转换也要遵循一定的规则,来解决在什么情况下将哪种类型的数据转换成另一种类型的数据。
float y = x; //将x赋值给y,y的值为50.0 隐式转换也要遵循一定的规则,来解决在什么情况下将哪种类型的数据转换成另一种类型的数据。
显式类型转换
当把高精度的变量的值赋给低精度的变量时,必须使用显式类型转换运算(又称强制类型转换)。语法如下:(类型名)要转换的值
代码注释与编码规范
在程序代码中适当地添加注释,可以提高程序的可读性和可维护性。好的编码规范可以使程序更易阅读和理解。
代码注释
过在程序代码中添加注释可提高程序的可读性。注释中包含了程序的信息,可以帮助程序员更好地阅读和理解程序。在Java源程序文件的任意位置都可添加注释语句。注释中的文字Java编译器不进行编译,所有代码中的注释文字对程序不产生任何影响。Java语言提供了3种添加注释的方法,分别为单行注释、多行注释和文档注释。
单行注释
“//”为单行注释标记,从符号“//”开始直到换行为止的所有内容均作为注释而被编译器忽略。语法如下://注释内容
多行注释
/* */”为多行注释标记,符号“/*”与“*/”之间的所有内容均为注释内容。注释中的内容可以换行。语法如下:/*
注释内容1
注释内容2
…
*/
注释内容1
注释内容2
…
*/
注意:(1)在多行注释中可嵌套单行注释(2)多行注释中不可以嵌套多行注释
文档注释
“/** */”为文档注释标记。符号“/**”与“*/”之间的内容均为文档注释内容。当文档注释出现在声明(如类的声明、类的成员变量的声明、类的成员方法的声明等)之前时,会被Javadoc文档工具读取作为Javadoc文档内容。除注释标记不同外,文档注释的格式与多行注释的格式相同。对于初学者而言,文档注释并不是很重要,了解即可。
编码规范
在学习开发的过程中要养成良好的编码习惯,规整的代码格式会为程序日后的维护工作提供极大的便利。
第四章 流程控制
复合语句
与C语言及其他语言相同,Java语言的复合语句是以整个块区为单位的语句,所以又称块语句。复合语句由开括号“{”开始,闭括号“}”结束。复合语句中的每个语句都是从上到下被执行。复合语句以整个块为单位,能够用在任何一个单独语句可以使用的地方,并且在复合语句中还可以嵌套复合语句。在使用复合语句时要注意,复合语句为局部变量创建了一个作用域,该作用域为程序的一部分,在该作用域中某个变量被创建并能够被使用。如果在某个变量的作用域外使用该变量,则会发生错误。
条件语句
if条件语句
if条件语句是一个重要的编程语句,用于告诉程序在某个条件成立的情况下执行某段语句,而在另一种情况下执行另外的语句。用if条件语句,可选择是否要执行紧跟在条件之后的那个语句。关键字if之后是作为条件的“布尔表达式”。如果该表达式返回的结果为true,则执行其后的语句;如果为false,则不执行if条件之后的语句。if条件语句可分为简单的if条件语句、if…else语句和if…else if多分支语句。
简单的if条件语句
语法如下:if(布尔表达式){
语句序列} 布尔表达式:必要参数,表示最后返回的结果必须是一个布尔值。它可以是一个单纯的布尔变量或常量,也可以是使用关系或布尔运算符的表达式。[插图] 语句序列:可选参数。可以是一条或多条语句,当表达式的值为true时执行这些语句。若语句序列中仅有一条语句,则可以省略条件语句中的“{ }”。
语句序列} 布尔表达式:必要参数,表示最后返回的结果必须是一个布尔值。它可以是一个单纯的布尔变量或常量,也可以是使用关系或布尔运算符的表达式。[插图] 语句序列:可选参数。可以是一条或多条语句,当表达式的值为true时执行这些语句。若语句序列中仅有一条语句,则可以省略条件语句中的“{ }”。
if…else语句
if…else语句是条件语句中最常用的一种形式,它会针对某种条件有选择地做出处理。通常表现为“如果满足某种条件,就进行某种处理,否则就进行另一种处理”。if后面“()”内的表达式的值必须是boolean型的。如果表达式的值为true,则执行紧跟if语句的复合语句;如果表达式的值为false,则执行else后面的复合语句。同简单的if条件语句一样,如果if…else语句的语句序列中只有一条语句(不包括注释),则可以省略该语句序列外面的“{ }”。有时为了编程的需要,else或if后面的“{ }”中可以没有语句。
if…else if多分支语句
if…else if多分支语句用于针对某一事件的多种情况进行处理。通常表现为“如果满足某种条件,就进行某种处理,否则如果满足另一种条件则执行另一种处理”。条件表达式1~条件表达式n:必要参数。可以由多个表达式组成,但最后返回的结果一定要为boolean类型。语句序列:可以是一条或多条语句,当条件表达式1的值为true时,执行语句序列1;当条件表达式2的值为true时,执行语句序列2,依此类推。当省略任意一组语句序列时,可以保留其外面的“{ }”,也可以将“{ }”替换为“;”。
switch条件语句
在编程中,一个常见的问题就是检测一个变量是否符合某个条件,如果不符合,再用另一个值来检测,依此类推。这个程序显得比较笨重,程序员需要测试不同的值来给出输出语句。在Java中,可以用switch语句将动作组织起来,以一个较简单明了的方式来实现“多选一”的选择。switch语句中表达式的值必须是整型、字符型、字符串类型或枚举类型,常量值1~n的数据类型必须与表达式的值的类型相同。switch语句首先计算表达式的值,如果表达式的计算结果和某个case后面的常量值相同,则执行该case语句后的若干个语句直到遇到break语句为止。此时,如果该case语句中没有break语句,将继续执行后面case中的若干个语句,直到遇到break语句为止。若没有一个常量的值与表达式的值相同,则执行default后面的语句。default语句为可选的,如果它不存在,且switch语句中表达式的值不与任何case的常量值相同,switch语句则不做任何处理。
循环语句
while循环语句
while语句也称条件判断语句,它的循环方式为利用一个条件来控制是否要继续反复执行这个语句。语法如下:while (条件表达式) {
语句序列
}当条件表达式的返回值为真时,则执行“{}”中的语句,当执行完“{}”中的语句后,重新判断条件表达式的返回值,直到表达式返回的结果为假时,退出循环。
语句序列
}当条件表达式的返回值为真时,则执行“{}”中的语句,当执行完“{}”中的语句后,重新判断条件表达式的返回值,直到表达式返回的结果为假时,退出循环。
do.....while循环语句
o…while循环语句与while循环语句类似,它们之间的区别是while语句为先判断条件是否成立再执行循环体,而do…while循环语句则先执行一次循环后,再判断条件是否成立。也就是说,do…while循环语句“{}”中的程序段至少要被执行一次。do…while语句与while语句的一个明显区别是,do…while语句在结尾处多了一个分号。
for循环语句
for循环是Java程序设计中最有用的循环语句之一。一个for循环可以用来重复执行某条语句,直到某个条件得到满足。for循环有两种语句,一种是传统的for语句,一种是foreach语句
for语句
传统的for语句中有3个表达式,表达式1:初始化表达式,负责完成变量的初始化。表达式2:循环条件表达式,值为boolean型的表达式,指定循环条件。等同于while循环里的表达式。表达式3:每次循环结束后执行的语句,通常用来改变循环条件。在执行for循环时,首先执行表达式1,完成某一变量的初始化工作;下一步判断表达式2的值,若表达式2的值为true,则进入循环体;在执行完循环体后紧接着计算表达式3,这部分通常是增加或减少循环控制变量的一个表达式。这样一轮循环就结束了。第二轮循环从计算表达式2开始,若表达式2返回true,则继续循环,否则跳出整个for语句。
foreach语句
oreach语句是for语句的特殊简化版本,不能完全取代for语句,但任何foreach语句都可以改写为for语句版本。foreach并不是一个关键字,习惯上将这种特殊的for语句格式称为foreach语句。
循环控制
break语句
使用break语句可以跳出switch结构。在循环结构中,同样也可用break语句跳出当前循环体,从而中断当前循环。注意:循环嵌套情况下,break语句将只会使程序流程跳出包含它的最内层的循环结构,即只跳出一层循环。如果想让break跳出外层循环,Java提供了“标签”的功能,语法如下:标签名: 循环体{
break标签名;
}标签名:任意标识符。循环体:任意循环语句。break标签名:break跳出指定的循环体,此循环体的标签名必须与break的标签名一致。带有标签的break可以指定跳出的循环,这个循环可以是内层循环,也可以是外层循环。
break标签名;
}标签名:任意标识符。循环体:任意循环语句。break标签名:break跳出指定的循环体,此循环体的标签名必须与break的标签名一致。带有标签的break可以指定跳出的循环,这个循环可以是内层循环,也可以是外层循环。
continue语句
continue语句是针对break语句的补充。continue不是立即跳出循环体,而是跳过本次循环,回到循环的条件测试部分,重新开始执行循环。在for循环语句中遇到continue后,首先执行循环的增量部分,然后进行条件测试。在while和do…while循环中,continue语句使控制直接回到条件测试部分。
第五章 数组
数组概述
数组是最为常见的一种数据结构,是相同类型的用一个标识符封装到一起的基本类型数据序列或对象序列。可以用一个统一的数组名和下标来唯一确定数组中的元素。实质上,数组是一个简单的线性序列,因此访问速度很快。
一维数组
一维数组实质上是一组相同类型数据的线性集合,当在程序中需要处理一组数据,或者传递一些数据时,可以应用这种类型的数组。
创建一维数组
数组作为对象允许使用new关键字进行内存分配。在使用数组之前,必须首先定义数组变量所属的类型。
一维数组的创建有两种方式
1.先声明,在用new关键字进行内存分配
声明有两种方式 数组元素类型 数组名字[ ];
数组元素类型 [ ] 数组名字;
数组元素类型决定了数组的数据类型,它可以是Java中任意的数据类型,声明数组后我们还不能立即访问它的任何元素,因为声明数组只是给出了数组名字和元素的数据类型,要想使用它还要为它分配内存空间,在位数组分配内存空间时必须指明数组的长度,格式如下:
数组名字=new 数组元素的类型[数组元素的个数]
数组名字:被连接到数组变量的名称
数组元素的个数:指定数组中变量的个数,即数组的长度
通过上面可知,使用new关键字为数组分配内存时,必须指定数组元素的类型和数字元素的个数,即数组的长度
2.声明的同时为数组分配内存
数组元素的类型 数组名=new 数组元素的类型[数组元素的个数];
初始化数组
int arr[ ]=new int [ ]{1,2,3,5,25};
int arr[ ]={34,23,12,6};
数组元素赋值
数组名[索引]=值;
创建一维数组
数组作为对象允许使用new关键字进行内存分配。在使用数组之前,必须首先定义数组变量所属的类型。
一维数组的创建有两种方式
1.先声明,在用new关键字进行内存分配
声明有两种方式 数组元素类型 数组名字[ ];
数组元素类型 [ ] 数组名字;
数组元素类型决定了数组的数据类型,它可以是Java中任意的数据类型,声明数组后我们还不能立即访问它的任何元素,因为声明数组只是给出了数组名字和元素的数据类型,要想使用它还要为它分配内存空间,在位数组分配内存空间时必须指明数组的长度,格式如下:
数组名字=new 数组元素的类型[数组元素的个数]
数组名字:被连接到数组变量的名称
数组元素的个数:指定数组中变量的个数,即数组的长度
通过上面可知,使用new关键字为数组分配内存时,必须指定数组元素的类型和数字元素的个数,即数组的长度
2.声明的同时为数组分配内存
数组元素的类型 数组名=new 数组元素的类型[数组元素的个数];
初始化数组
int arr[ ]=new int [ ]{1,2,3,5,25};
int arr[ ]={34,23,12,6};
数组元素赋值
数组名[索引]=值;
二维数组
如果一维数组中的各个元素仍然是一个数组,那么它就是一个二维数组。二维数组常用于表示表,表中的信息以行和列的形式组织,第一个下标代表元素所在的行,第二个下标代表元素所在的列。创建二维数组 二维数组可以看作是特殊的一维数组,因此二维数组的创建同样有两种方式。1.先声明,再用new关键字进行内存分配声明二维数组的语法如下:数组元素的类型 数组名字[ ][ ];
数组元素的类型[ ][ ] 数组名字; 声明二维数组,代码如下:int a[][]; 同一维数组一样,二维数组在声明时也没有分配内存空间,同样要使用new关键字来分配内存,然后才可以访问每个元素。对于高维数组,有两种为数组分配内存的方式。第一种内存分配方式是直接为每一维分配内存空间,代码如下:a = new int[2][4] 第二种内存分配方式是分别为每一维分配内存,代码如下:a = new int[2][];
a[0] = new int[2];
a[1] = new int[3]; 2.声明的同时为数组分配内存第二种创建方式与第一种实现的功能相同,只不过声明与赋值合并到同一行代码中。初始化二维数组二维数组的初始化与一维数组初始化类似,同样可以使用大括号完成。语法如下:type arrayname[][] = {value1,value2,…,valuen}; 初始化二维数组,代码如下:int myarr[][] = {{12,0},{45,10}}; 初始化二维数组后,要明确数组的下标都是从0开始。int型二维数组是以int a [][]来定义的,所以可以直接给a[x][y]赋值。
数组元素的类型[ ][ ] 数组名字; 声明二维数组,代码如下:int a[][]; 同一维数组一样,二维数组在声明时也没有分配内存空间,同样要使用new关键字来分配内存,然后才可以访问每个元素。对于高维数组,有两种为数组分配内存的方式。第一种内存分配方式是直接为每一维分配内存空间,代码如下:a = new int[2][4] 第二种内存分配方式是分别为每一维分配内存,代码如下:a = new int[2][];
a[0] = new int[2];
a[1] = new int[3]; 2.声明的同时为数组分配内存第二种创建方式与第一种实现的功能相同,只不过声明与赋值合并到同一行代码中。初始化二维数组二维数组的初始化与一维数组初始化类似,同样可以使用大括号完成。语法如下:type arrayname[][] = {value1,value2,…,valuen}; 初始化二维数组,代码如下:int myarr[][] = {{12,0},{45,10}}; 初始化二维数组后,要明确数组的下标都是从0开始。int型二维数组是以int a [][]来定义的,所以可以直接给a[x][y]赋值。
数组的基本操作
java.util包的Arrays类包含了用来操作数组(如排序和搜索)的各种方法
遍历数组
遍历数组就是获取数组中的每个元素。通常遍历数组都是使用for循环来实现。遍历二维数组需使用双层for循环,通过数组的length属性可获得数组的长度
填充替换数组元素
数组中的元素定义完成后,可通过Arrays类的静态方法fill()来对数组中的元素进行替换。该方法通过各种重载形式可完成对任意类型的数组元素的替换。fill()方法有两种参数类型。
fill(int[] a,int value)
该方法可将指定的int值分配给int型数组的每个元素。语法如下:fill(int[] a, int value)
fill(int[] a,int fromIndex,int toIndex,int value)
该方法将指定的int值分配给int型数组指定范围中的每个元素。填充的范围从索引fromIndex(包括)一直到索引toIndex(不包括)。如果fromIndex ==toIndex,则填充范围为空。语法如下:fill(int[] a, int fromIndex, int toIndex, int value)
对数组进行排序
通过Arrays类的静态方法sort()可以实现对数组的排序。sort()方法提供了多种重载形式,可对任意类型的数组进行升序排序。语法如下:Arrays.sort(object)
复制数组
Arrays类的copyOf()方法与copyOfRange()方法可以实现对数组的复制。
copyOf()方法
该方法提供了多种重载形式,用于满足不同类型数组的复制。语法如下:copyOf(arr, int newlength)
copyOfRange()方法
该方法同样提供了多种重载形式。语法如下:copyOfRange(arr, int formIndex, int toIndex)
查询数组
Arrays类的binarySearch()方法,可使用二分搜索法来搜索指定数组,以获得指定对象。该方法返回要搜索元素的索引值。binarySearch()方法提供了多种重载形式,用于满足各种类型数组的查找需要。binarySearch()方法有两种参数类型。
binarySearch(Object[] a, int fromIndex, int toIndex, Object key)语法如下:binarySearch(Object[] a, int fromIndex, int toIndex, Object key)
binarySearch(Object[],int fromIndex,int toIndex,Object key)该方法在指定的范围内检索某一元素。语法如下:binarySearch(Object[] a, int fromIndex, int toIndex, Object key)在使用该方法前,同样要对数组进行排序,这样才能获得准确的索引值。如果要搜索的元素key在指定的范围内,则返回搜索键的索引;否则返回-1或“-”(插入点)。如果范围中的所有元素都小于指定的键,则插入点为toIndex(注意,这保证了当且仅当此键被找到时,返回的值将大于等于0)。
数组排序算法
冒泡排序
冒泡算法由双层循环实现,其中外层循环用于控制排序轮数
直接选择排序
将最大的数放到最后,固定不动,第二次再将最大的数放到最后,固定不动,往后继续。
反转排序
就是第一个数和最后一个数交换,第二个数和倒数第二个数交换,第三个数和倒数第三个数交换,以此类推。就像一面镜子,如果是单数中间那个不会交换。
第二篇 面向对象编程
第六章 类和对象
面向对象概述
对象
对象是事物存在的实体,世间万物皆对象。对象分为两个部分,即静态部分与动态对象部分
静态部分:不能动的部分,称为“属性"
动态部分:对象可执行的动作,称为“行为”
类
类是统一事物的统称,如果将现实世界中的一事物抽象成对象,类就是这类对象的统称。 类是对象的设计图;类是封装对象的属性和行为的载体,具有相同属性和行为的一类实体被称为类。类对象的行为是以方法的形式定义的,对象的属性是以成员变量的形式定义的,所以类包括对象的属性和方法。
封装
面向对象程序设计具有以下特点:封装性、继承性和多态性。封装是面向对象编程的核心思想。将对象的属性和行为封装起来,其载体就是类,类通常对客户隐藏其实现细节,这就是封装的思想。采用封装的思想保证了类内部数据结构的完整性,提高了程序的可维护性。
继承
类与类之间同样具有关系,这种关系被称为关联。两个类之间的关系有很多种,继承是关联中的一种。设计软件时,使用继承思想可以缩短软件开发的周期,复用那些已经定义好的类可以提高系统性能,减少系统在使用过程中出现错误的概率。
多态
将父类对象应用与子类的特征就是多态。
类
成员变量
在Java中,对象的属性也称为成员变量,成员变量可以是任意类型,整个类中均是成员变量作用范围。
成员方法
在Java语言中,使用成员方法对应于类对象的行为。定义成员方法的语法格式如下:权限修饰符 返回值类型 方法名(参数类型 参数名){
.... //方法体
return 返回值;
}
.... //方法体
return 返回值;
}
权限修饰符
Java中的权限修饰符主要包括private、public和protected,这些修饰符控制着对类和类的成员变量以及成员方法的访问。如果一个类的成员变量或成员方法被修饰为private,则该成员变量只能在本类中被使用,在子类中是不可见的,并且对其他包的类也是不可见的。如果将类的成员变量和成员方法的访问权限设置为public,那么除了可以在本类使用这些数据,还可以在子类和其他包的类中使用。如果一个类的访问权限被设置为private,这个类将隐藏其内的所有数据,以免用户直接访问它。如果需要使类中的数据被子类或其他包中的类使用,可以将这个类设置为public访问权限。如果一个类使用protected修饰符,那么只有本包内的该类的子类或其他类可以访问此类中的成员变量和成员方法。这么看来,public和protected修饰的类可以由子类访问,如果子类和父类不在同一包中,那么只有修饰符为public的类可以被子类进行访问。如果父类不允许通过继承产生的子类访问它的成员变量,那么必须使用private声明父类的这个成员变量。
局部变量及其有效范围
如果在成员方法内定义一个变量,那么这个变量被称为局部变量。实际上,方法中的形参也可作为一个局部变量。局部变量是在方法被执行时创建,在方法执行结束时被销毁。局部变量在使用时必须进行赋值操作或被初始化,否则会出现编译错误。在ChangeDemo类中创建静态的exchange()方法,该方法可以将数组参数arr的前两个元素值互换,通过在方法中定义一个保存临时数据的局部变量tmp,利用tmp交换两个元素的值。可以将局部变量的有效范围称为变量的作用域,局部变量的有效范围从该变量的声明开始到该变量的结束为止。在相互不嵌套的作用域中可以同时声明两个名称和类型相同的局部变量,但是在相互嵌套的区域中不可以这样声明,如果将局部变量id在方法体的for循环中再次定义,编译器将会报错。
this关键字
this关键字用于表示本类当前的对象,当前对象不是某个new出来的实体对象,而是当前正在编辑的类。this关键字只能在本类中使用。
类的构造方法
在类中,除成员方法外,还存在一种特殊类型的方法,那就是构造方法。构造方法是一个与类同名的方法,对象的创建就是通过构造方法完成的。每当类实例化一个对象时,类都会自动调用构造方法。构造方法的特点如下:构造方法没有返回值。构造方法的名称要与本类的名称相同。构造方法的定义语法格式:(public :构造方法修饰符;Name:构造方法的名称)
public Name(){
..... //构造方法体
}在构造方法中可以为成员变量赋值,这样当实例化一个本类对象时,相应的成员变量也将被初始化。如果类中没有明确定义构造方法,编译器会自动创建一个不带参数的默认构造方法。当顾客购买鸡蛋灌饼时,如果要求加两个蛋,店家就给饼加两个蛋;不要求时,店家会默认给饼加一个蛋。创建鸡蛋灌饼类(EggCake类),使用this关键字,在无参构造方法中调用有参构造方法,实现上述加蛋过程。
public Name(){
..... //构造方法体
}在构造方法中可以为成员变量赋值,这样当实例化一个本类对象时,相应的成员变量也将被初始化。如果类中没有明确定义构造方法,编译器会自动创建一个不带参数的默认构造方法。当顾客购买鸡蛋灌饼时,如果要求加两个蛋,店家就给饼加两个蛋;不要求时,店家会默认给饼加一个蛋。创建鸡蛋灌饼类(EggCake类),使用this关键字,在无参构造方法中调用有参构造方法,实现上述加蛋过程。
静态成员
由static修饰的变量和方法被称为静态变量和动态方法。被声明为static的变量和方法被称为静态成员。静态成员属于类所有,区别于个别对象,可以在本类或其他类使用类名和”.“运算符调用静态成员。语法如下:
类名.静态类成员
创建并调用静态属性和静态变量,创建homework类,在类中使用static关键字定义一个属性和一个方法,并在主方法中条用。静态变量与静态方法的作用通常是为了提供共享数据或方法,如数学计算公式等。尽管使用这种方式调用静态成员比较方便,但静态成员同样遵循修饰符的约束。
在part类中创建一个静态整数类型属性count,在构造方法中让count自增。总结以下使用static关键字要注意的几点:
在静态方法中不可使用this关键字。
在静态方法中不可以直接调用非静态方法。
局部变量不可以使用static关键字声明。
主方法必须用static声明。
只有内部类可以使用static关键字声明。
类名.静态类成员
创建并调用静态属性和静态变量,创建homework类,在类中使用static关键字定义一个属性和一个方法,并在主方法中条用。静态变量与静态方法的作用通常是为了提供共享数据或方法,如数学计算公式等。尽管使用这种方式调用静态成员比较方便,但静态成员同样遵循修饰符的约束。
在part类中创建一个静态整数类型属性count,在构造方法中让count自增。总结以下使用static关键字要注意的几点:
在静态方法中不可使用this关键字。
在静态方法中不可以直接调用非静态方法。
局部变量不可以使用static关键字声明。
主方法必须用static声明。
只有内部类可以使用static关键字声明。
类的主方法
主方法是类的入口点,它定义了程序从何处开始。主方法提供对程序流向的控制,Java编译器通过主方法来执行程序。主方法的语法如下:
public stasti void mian(String args){
.... //方法体
}
在主方法的定义中可以看到其具有以下特点:
主方法是静态的,所以如要直接在主方法中条用其他方法,则该方法必须也是静态的。
主方法没有返回值。
主方法的形参为数组。其中,args[0]~[n]分别代表程序的第一个参数到n个参数,可以使用args.length获取参数的个数。
读取主方法的参数组,在项目创建part类,在主方法中编写一下代码,并在Eclipse中设置程序参数。
public stasti void mian(String args){
.... //方法体
}
在主方法的定义中可以看到其具有以下特点:
主方法是静态的,所以如要直接在主方法中条用其他方法,则该方法必须也是静态的。
主方法没有返回值。
主方法的形参为数组。其中,args[0]~[n]分别代表程序的第一个参数到n个参数,可以使用args.length获取参数的个数。
读取主方法的参数组,在项目创建part类,在主方法中编写一下代码,并在Eclipse中设置程序参数。
对象
创建
对象可以认为是在一类事物中抽象出某一个特例,可以通过这个特例来处理这类事物出现的问题。在Java语言中,通过new操作符来创建对象。前文在讲解构造方法时介绍过,每实例化一个对象就会自动调用一次构造方法,实质上这个过程就是创建对象的过程。准确地说,可以在Java语言中使用new操作符调用构造方法创建对象。语法如下:Test test = new Test();
Test test = new Test("a");test对象被创建出来时,就是一个对象的引用,这个引用在内存中为对象分配了存储空间。可以在构造方法中初始化成员变量,当创建对象时,自动调用构造方法。也就是说,在Java语言中,初始化与创建是被捆绑在一起的。每个对象都是相互独立的,在内存中占据独立的内存地址,并且每个对象都具有自己的生命周期,当一个对象的生命周期结束时,对象就变成垃圾,由Java虚拟机自带的垃圾回收机制处理,不能再被使用。
Test test = new Test("a");test对象被创建出来时,就是一个对象的引用,这个引用在内存中为对象分配了存储空间。可以在构造方法中初始化成员变量,当创建对象时,自动调用构造方法。也就是说,在Java语言中,初始化与创建是被捆绑在一起的。每个对象都是相互独立的,在内存中占据独立的内存地址,并且每个对象都具有自己的生命周期,当一个对象的生命周期结束时,对象就变成垃圾,由Java虚拟机自带的垃圾回收机制处理,不能再被使用。
访问属性和行为
用户使用new操作符创建一个对象后,可以使用“对象.类成员”来获取对象的属性和行为。用户使用new操作符创建一个对象后,可以使用“对象.类成员”来获取对象的属性和行为。
引用
在Java语言中,尽管一切都可以看作对象,但真正的操作标识符实质上是一个引用,那么引用在Java中是如何体现的呢?语法如下:类名 对象的引用变量。例如,一个People类的引用可以使用以下代码:People tom; 通常一个引用不一定需要有一个对象相关联。引用与对象相关联的语法如下:People tom = new People();
销毁
每个对象都有生命周期,当对象的生命周期结束时,分配给该对象的内存地址需要被回收。在其他语言中,需要用户手动回收废弃的对象。Java拥有一套完整的垃圾回收机制,用户不必担心废弃的对象占用内存,垃圾回收器会自动回收无用却占用内存的资源。在学习垃圾回收机制之前,首先需要了解何种对象会被Java虚拟机视为“垃圾”。主要包括以下两种情况:对象引用超过其作用范围,这个对象将被视为垃圾。将对象赋值为null。虽然Java的垃圾回收机制已经很完善,但垃圾回收器只能回收那些由new操作符创建的对象。某些对象不是通过new操作符在内存中获取存储空间的,这种对象无法被垃圾回收机制所识别。在Java中,提供了一个finalize()方法,这个方法是Object类的方法,它被声明为protected,用户可以在自己的类中定义这个方法。如果用户在类中定义了finalize()方法,在垃圾回收时会首先调用该方法,在下一次垃圾回收动作发生时,才真正回收被对象占用的内存。
第七章 继承、多态、抽象类与接口
继承
继承在面向对象开发思想中是一个非常重要的概念,它使整个程序架构具有一定的弹性。在程序中复用一些已经定义完善的类,不仅可以减少软件开发周期,也可以提高软件的可维护性和可扩展性。在Java语言中,一个类继承另一个类需要使用关键字extends,关键字extends的使用方法如下:class Child extends Parent { } 因为Java只支持单继承,即一个类只能有一个父类。子类在继承父类之后,创建子类对象的同时也会调用父类的构造方法。子类继承父类之后可以调用父类创建好的属性和方法。Java虽然不允许同时继承两个父类,但不代表没有多继承的关系,可以通过类似“祖父>父>儿子>孙子”的方式实现多代继承。
Object类
在开始学习使用class关键字定义类时,就应用到了继承原理,因为在Java中所有的类都直接或间接继承了java.lang.Object类。Object类是比较特殊的类,它是所有类的父类,是Java类层中的最高层类。用户创建一个类时,除非已经指定要从其他类继承,否则它就是从java.lang.Object类继承而来的。Java中的每个类都源于java.lang.Object类,如String类、Integer类等都是继承于Object类。除此之外,自定义的类也都继承于Object类。由于所有类都是Object类的子类,所以在定义类时可省略extends Object。在Object类中,主要包括clone()、finalize()、equals()、toString()等方法,其中常用的两个方法为equals()和toString()方法。由于所有的类都是Object类的子类,所以任何类都可以重写Object类中的方法。
getClass()方法
getClass()方法是Object类定义的方法,它会返回对象执行时的Class实例,然后使用此实例调用getName()方法可以取得类的名称。语法如下:getClass().getname();可以将getClass()方法与toString()方法联合使用。
toString()方法
toString()方法的功能是将一个对象返回为字符串形式,它会返回一个String实例。在实际的应用中通常重写toString()方法,为对象提供一个特定的输出模式。当这个类转换为字符串或与字符串连接时,将自动调用重写的toString()方法。
equals()方法
在Java语言中,有两种比较对象的方式,分别为“==”运算符与equals()方法。两者的区别在于:“==”比较的是两个对象引用内存地址是否相等,而equals()方法比较的是两个对象的实际内容。(使用new操作符创建的都是引用数据类型)注意,在使用equals() 方法比较自行编写的类对象时,那么需要先重写equals方法,因为每个类判相等的规则都是不一样的。而且如果没有重写的话,那么系统会自动调用Object中的equals方法。
对象类型的转换
对象类型的转换在Java编程中经常遇到,主要包括向上转型与向下转型操作。非继承关系之间不能进行类型转换。
对象之间的类型转换在Java编程中还是很常见的。类型转换分为向上转型与向下转型。
对象之间的类型转换在Java编程中还是很常见的。类型转换分为向上转型与向下转型。
向上转型
向上转型可以被理解为将子类类型的对象转换为父类类型的对象,即把子类类型的对象直接赋值给父类类型的对象,进而实现按照父类描述子类的效果。进行向上转型,父类类型的对象可以引用子类类型的对象。而且,向上转型是安全的,因为向上转型是将一个较具体的类的对象转换为一个较抽象的类的对象。格式为: 父类 对象名 = (父类) 子类对象;需要注意得是,在进行向上类型转换后,父类对象依旧无法调用子类独有的属性与方法。只能调用从父类中继承下来的属性与方法。
向下转型
向下类型转换可以理解为将父类类型的对象转换为子类类型的对象。 但是运用向下转型,因为父类大多是较为抽象的类,而子类大多是具体的类, 而将一个较为抽象的类转换为一个较为具体的类,这样的转换通常会出现错误,所以向下转型是不安全的。要想实现向下转型,需要借助强制类型转换。语法如下:子类类型 子类对象 = (子类类型)父类对象;注意,两个没有继承关系的对象不可以进行向上转型或者向下转型。父类对象可以强制转换为子类对象,但有一个前提:这个父类对象要先引用这个子类对象。
instanceof关键字
当在程序中执行向下转型操作时,如果父类对象不是子类对象的实例,就会发生ClassCastException异常,所以在执行向下转型之前需要养成一个良好的习惯,就是判断父类对象是否为子类对象的实例。这个判断通常使用instanceof关键字来完成。可以使用instanceof关键字判断是否一个类实现了某个接口,也可以用它来判断一个实例对象是否属于一个类。instanceof的语法格式如下:myobject instanceof ExampleClass;使用instanceof关键字的表达式返回值为布尔值。如果返回值为true,说明myobject对象为ExampleClass的实例对象;如果返回值为false,说明myobject对象不是ExampleClass的实例对象。
方法的重载
构造方法只有一个名称。如果希望以不同的方式来实例化对象,就需要使用多个构造方法来完成。由于这些构造方法都需要根据类名进行命名,为了让方法名相同而形参不同的构造方法同时存在,必须用到方法重载。虽然方法重载起源于构造方法,但它也可以应用到其他方法中。方法的重载就是在同一个类中允许存在一个以上的同名方法,只要这些方法的参数个数或类型不同即可。编译器是利用方法名、方法各参数类型和参数的个数、参数的顺序来确定类中的方法是否唯一。方法的重载使得方法以统一的名称被管理,使程序代码更有条理。在谈到参数个数可以确定两个方法是否具有重载关系时,会想到定义不定长参数方法。不定长方法的语法如下:返回值 方法名(参数数据类型…参数名称)
final关键字
final被译为“最后的”“最终的”,final是Java语言中的一个关键字,凡是被final关键字修饰过的内容都是不可改变的。
final变量
final关键字可用于变量声明,一旦该变量被设定,就不可以再改变该变量的值。通常,由final定义的变量为常量。例如,在类中定义PI值,可以使用如下语句:final double PI = 3.14;当在程序中使用到PI这个常量时,它的值就是3.14。如果在程序中再次对定义为final的常量赋值,编译器将不会接受。final关键字定义的变量必须在声明时对其进行赋值操作。final除了可以修饰基本数据类型的常量,还可以修饰对象引用。由于数组也可以被看作一个对象来引用,所以final可以修饰数组。一旦一个对象引用被修饰为final后,它就只能恒定指向一个对象,无法将其改变以指向另一个对象。一个既是static又是final的字段只占据一段不能改变的存储空间。
final方法
将方法定义为final类型,可以防止子类修改父类的定义与实现方式,同时定义为final的方法的执行效率要高于非final方法。在修饰权限中曾经提到过private修饰符,如果一个父类的某个方法被设置为private,子类将无法访问该方法,自然无法覆盖该方法。也就是说,一个定义为private的方法隐式被指定为final类型,因此无须将一个定义为private的方法再定义为final类型。
final类
定义为final的类不能被继承。如果希望一个类不被任何类继承,并且不允许其他人对这个类进行任何改动,可以将这个类设置为final类。final类的语法如下:final 类名{}如果将某个类设置为final类,则该类中的所有方法都被隐式设置为final方法,但是final类中的成员变量可以被定义为final或非final形式。例如,已知JDK中的java.lang包下的Math数学类和String字符串类都是由final关键字修饰的类,这两个类就无法做任何类的父类,如果这两个类出现在extends右侧就会发生编译错误。
多态
利用多态可以使程序具有良好的扩展性,并可以对所有类对象进行通用的处理。节省了开发和维护时间,因为程序员无须在所有的子类中定义执行相同功能的方法,避免了大量重复代码的编写。同时,只要实例化一个继承父类的子类对象,即可调用相应的方法,如果需求发生了变更,只需要维护一个draw()方法即可。
抽象
在解决实际问题时,一般将父类定义为抽象类,需要使用这个父类进行继承与多态处理。回想继承和多态原理,继承树中越是在上方的类越抽象,如鸽子类继承鸟类、鸟类继承动物类等。在多态机制中,并不需要将父类初始化为对象,我们需要的只是子类对象,所以在Java语言中设置抽象类不可以实例化为对象。使用abstract关键字定义的类称为抽象类,而使用这个关键字定义的方法称为抽象方法。抽象方法没有方法体,这个方法本身没有任何意义,除非它被重写,而承载这个抽象方法的抽象类必须被继承,实际上抽象类除了被继承没有任何意义。反过来讲,如果声明一个抽象方法,就必须将承载这个抽象方法的类定义为抽象类,不能在非抽象类中获取抽象方法。换句话说,只要类中有一个抽象方法,此类就被标记为抽象类。抽象类被继承后需要实现其中所有的抽象方法,也就是保证以相同的方法名称、参数列表和返回值类型创建出非抽象方法,当然也可以是抽象方法。
接口
接口是抽象类的延伸,可以将它看作是纯粹的抽象类,接口中的所有方法都没有方法体。Java中不允许出现多重继承,但使用接口就可以实现多重继承。一个类可以同时实现多个接口,因此可以将所有需要继承的接口放置在implements关键字后并使用逗号隔开。实现多个接口的语法如下:class 类名 implements 接口1,接口2,…,接口n;但这可能会在一个类中产生庞大的代码量,因为继承一个接口时需要实现接口中所有的方法。一个接口可以继承另一个接口,其语法如下:interface intf1 { }
interface intf2 extends intf1 { } //接口继承接口
interface intf2 extends intf1 { } //接口继承接口
第八章 包和内部类
JAVA类包
在Java中每定义好一个类,通过Java编译器进行编译之后,都会生成一个扩展名为.class的文件。当程序的规模逐渐扩大时,就很容易发生类名称冲突的现象。JDK API中提供了成千上万具有各种功能的类,系统又是如何管理的呢?Java中提供了一种管理类文件的机制,就是类包。
类名冲突
Java中每个接口或类都来自不同的类包,无论是Java API中的类与接口还是自定义的类与接口,都需要隶属于某一个类包,这个类包包含了一些类和接口。如果没有包的存在,管理程序中的类名称将是一件非常麻烦的事情。如果程序只由一个类组成,自然不会出现类名重叠的问题,但是随着程序的类的数量增多,难免会出现这一问题。例如,在程序中定义一个Login类,因业务需要,还要定义一个名称为Login的类,但是这两个类所实现的功能完全不同,于是问题就产生了——编译器不会允许存在同名的类文件。解决这类问题的办法是将这两个类放置在不同的类包中。
完整的类路径
一个完整的类名需要包名与类名的组合,每个类都隶属于一个类包,只要保证同一类包中的类不同名,就可以有效地避免同名类冲突的情况。如:String,其实并不是它完整的名称,就如同一个人一样有名有姓,String完整的名称是:Java.lang.String,java.lang是包的名称,String是类的名称。
创建包
在Eclipse中创建包的步骤如下:(1)在项目的src节点上右击,选择“新建”/“包”命令(英文为New /Package)。(2)弹出“新建Java包”(New Java Package)对话框,在“名称”(Name)文本框中输入新建的包名,如com.mr,然后单击“完成”(Finish)按钮,如图8.2所示。(3)在Eclipse中创建类时,可以在新建立的包上右击,选择“新建”(New)命令,这样新建的类会默认保存在该包中。另外也可以在New Java Class对话框中指定新建类所在的包。在Java中包名设计应与文件系统结构相对应,如一个包名为com.mr,那么该包中的类位于com文件夹下的mr子文件夹下。没有定义包的类会被归纳在默认包(default package)中。在实际开发中,应该为所有类设置包名,这是良好的编程习惯。在类中定义包名的语法如下:package 包名
导入包
使用import关键字导入包
如果某个类中需要使用Math 类,那么如何告知编译器当前应该使用哪一个包中的Math类,是 java.lang.Math 类还是commrMath类?这是一个令人困扰的问题。此时,可以使用Java 中的import关键字指定。例如,如果在程序中使用 import 关键字导入commrMath类,在程序中使用Math类时就会自动选择commrMath类。import关键字的语法如下:import com.mr.*; //导入com.mr包中的所有类
import com.mr.Math //导入com.mr包中的Math类 在使用import关键字时,可以指定类的完整描述,如果为了使用包中更多的类,可以在使用import关键字指定时在包指定后加上*,这表示可以在程序中使用该包中的所有类。
import com.mr.Math //导入com.mr包中的Math类 在使用import关键字时,可以指定类的完整描述,如果为了使用包中更多的类,可以在使用import关键字指定时在包指定后加上*,这表示可以在程序中使用该包中的所有类。
使用import导入静态成员
import关键字除导入包外,还可以导入静态成员,这是JDK 5.0以上版本提供的功能。导入静态成员可以使编程更为方便。使用import导入静态成员的语法如下:import static 静态成员
内部类
在一个文件中定义两个类,则其中任何一个类都不在另一个类的内部。如果在类中再定义一个类,则将在类中再定义的那个类称为内部类。成员内部类和匿名类为最常见的内部类。
成员内部类
在一个类中使用内部类,可以在内部类直接存取其中所在类的私有成员变量。成员内部类语法如下:class OuterClass{//外部类
calss lnner Class{//内部类
}
} 在成员内部类中可以随意使用外部类的成员方法及成员变量,尽管这些类成员被修饰为private。尽管成员变量i以及成员方法g()都在外部类中被修饰为private,但在成员内部类中可以直接使用。内部类的实例一定要绑定在外部类的实例上,如果从外部类中初始化一个内部类对象,那么内部类对象就会绑定在外部类对象上。内部类初始化方式与其他类的初始化方式相同,都是使用new关键字。成员内部类不止可以在外部类中使用,在其他类中也可以使用。在其他类中创建内部类对象的语法非常特殊,语法如下:外部类 outer = new 外部类();
外部类.内部类 inner = outer.new 内部类();
calss lnner Class{//内部类
}
} 在成员内部类中可以随意使用外部类的成员方法及成员变量,尽管这些类成员被修饰为private。尽管成员变量i以及成员方法g()都在外部类中被修饰为private,但在成员内部类中可以直接使用。内部类的实例一定要绑定在外部类的实例上,如果从外部类中初始化一个内部类对象,那么内部类对象就会绑定在外部类对象上。内部类初始化方式与其他类的初始化方式相同,都是使用new关键字。成员内部类不止可以在外部类中使用,在其他类中也可以使用。在其他类中创建内部类对象的语法非常特殊,语法如下:外部类 outer = new 外部类();
外部类.内部类 inner = outer.new 内部类();
如果在外部类中定义的成员变量与内部类的成员变量名称相同,可以使用this关键字。在类中,如果遇到内部类与外部类的成员变量重名的情况,可以使用this关键字进行处理。例如,在内部类中使用this.x语句可以调用内部类的成员变量x,而使用TheSameName.this.x语句可以调用外部类的成员变量x,即使用外部类名称后跟一个点操作符和this关键字便可获取外部类的一个引用。
匿名内部类
匿名类是在创建一种写法。对象时才会编写类体的一种写法。
匿名类的特点是”现写现用“语法如下:
new 父类/父接口(){
子类实现内容
} 使用匿名内部类创建一个抽象狗类的对象 abstract class Dog {//抽象类 Dog
String Color;//字符串类型
public abstract void move();//抽象类
public abstract void call();//抽象类
}
public class Demo1{//类名
public static void main(String[] args) {//主方法
// TODO Auto-generated method stub
Dog maomao=new Dog() {//构造一个对象
public void move() {//使用匿名内部类补充属性
System.out.println("四腿狂奔");
}
public void call() {//使用匿名内部类补充属性
System.out.println("嗷呜~");
}
};
maomao.Color ="灰色";
maomao.move ();
maomao.call();
}
}运行结果如下:四腿狂奔
嗷呜~ 从这个结果可以看出,本来无法创建对象的抽象类竟然也可以出现在new关键字的右侧。为何叫匿名内部类?就是因为实例中Dog抽象类的实现类没有名称。创建出的对象maomao既不是金毛犬,也不是哈士奇犬,在程序中maomao只能解读为“一只具体的无名之狗”。使用匿名类时应该遵循以下原则:匿名类不能写构造方法。匿名类不能定义静态的成员。 如果匿名类创建的对象没有赋值给任何引用变量,会导致该对象用完一次就会被Java虚拟机销毁。
匿名类的特点是”现写现用“语法如下:
new 父类/父接口(){
子类实现内容
} 使用匿名内部类创建一个抽象狗类的对象 abstract class Dog {//抽象类 Dog
String Color;//字符串类型
public abstract void move();//抽象类
public abstract void call();//抽象类
}
public class Demo1{//类名
public static void main(String[] args) {//主方法
// TODO Auto-generated method stub
Dog maomao=new Dog() {//构造一个对象
public void move() {//使用匿名内部类补充属性
System.out.println("四腿狂奔");
}
public void call() {//使用匿名内部类补充属性
System.out.println("嗷呜~");
}
};
maomao.Color ="灰色";
maomao.move ();
maomao.call();
}
}运行结果如下:四腿狂奔
嗷呜~ 从这个结果可以看出,本来无法创建对象的抽象类竟然也可以出现在new关键字的右侧。为何叫匿名内部类?就是因为实例中Dog抽象类的实现类没有名称。创建出的对象maomao既不是金毛犬,也不是哈士奇犬,在程序中maomao只能解读为“一只具体的无名之狗”。使用匿名类时应该遵循以下原则:匿名类不能写构造方法。匿名类不能定义静态的成员。 如果匿名类创建的对象没有赋值给任何引用变量,会导致该对象用完一次就会被Java虚拟机销毁。
第三篇 核心技术
第九章 异常处理
异常概述
在程序中,异常可能由程序员没有预料到的各种情况产生,也可能由超出了程序员可控范围的环境因素产生,如用户的坏数据、试图打开一个根本不存在的文件等。在Java中,这种在程序运行时可能出现的一些错误称为异常。异常是一个在程序执行期间发生的事件,它中断了正在执行的程序的正常指令流。
异常的抛出与捕捉
为了保证程序有效地执行,需要对抛出的异常进行相应的处理。在Java中,如果某个方法抛出异常,既可以在当前方法中进行捕捉,而后处理该异常,也可以将异常向上抛出,交由方法调用者来处理。
抛出异常
异常抛出后,如果不做任何处理,程序就会被终止。例如,将一个字符串转换为整型,可以通过Integer类的parseInt()方法来实现。但如果该字符串不是数字形式,parseInt()方法就会抛出异常,程序将在出现异常的位置终止,不再执行下面的语句。
捕捉异常
Java语言的异常捕获结构由try、catch和finally 3部分组成。其中,try语句块存放的是可能发生异常的Java语句;catch语句块在try语句块之后,用来激发被捕获的异常;finally语句块是异常处理结构的最后执行部分,无论try语句块中的代码如何退出,都将执行finally语句块。
try-catch语句块
public class Take {
public static void main(String[] args) {
// TODO 自动生成的方法存根
try {
String str = "lili";//定义字符串
System.out.println(str+"年龄是:");//输出的提示信息
int age = Integer.parseInt("20L");//数据类型转换
System.out.println(age);//数据类型转换
}catch(Exception e) {//catch语句块用来获取异常信息
e.printStackTrace();//输出异常性质
}
System.out.println("program over");//输出信息
}
}结果显示:NumberFormatException 数字格式错误
public static void main(String[] args) {
// TODO 自动生成的方法存根
try {
String str = "lili";//定义字符串
System.out.println(str+"年龄是:");//输出的提示信息
int age = Integer.parseInt("20L");//数据类型转换
System.out.println(age);//数据类型转换
}catch(Exception e) {//catch语句块用来获取异常信息
e.printStackTrace();//输出异常性质
}
System.out.println("program over");//输出信息
}
}结果显示:NumberFormatException 数字格式错误
finally语句块
完整的异常处理语句一定要包含finally语句,无论程序中有无异常发生,并且无论之前的try-catch语句块是否顺利执行完毕,都会执行finally语句。
在以下4种特殊情况下,finally块不会被执行:
(1)在finally语句块中发生了异常
(2)在前面的代码中使用了System.exit()退出程序
(3)程序所在的线程死亡
(4)关闭cpu
在以下4种特殊情况下,finally块不会被执行:
(1)在finally语句块中发生了异常
(2)在前面的代码中使用了System.exit()退出程序
(3)程序所在的线程死亡
(4)关闭cpu
JAVA常见的异常类
1,ClasscastException 类型转换异常 2,ClassNotFxception 未找到相应类异常
3,ArithmeticException 算术异常 4,ArrayIndexOutOfBoundsException 数组下标越界
5,ArrayStoreException 数组中包含不兼容的值抛出的异常
6,SQLException 操作数据库异常类 7, NullPointerException 空指针异常
8,NoSuchFieldException 字段未找到异常 9,NoSuchMethodException 方法未找到抛出异常
10.NumberFormatException 字符串转换为数字抛出的异常
11.NegativeArraySizeException 数组元素个数为负数抛出的异常
12.StringIndexOutOfBoundsException 字符串索引超出范围抛出的异常
13.IOException 输入输出异常
14.IllegalAccessException 不允许访问某类异常
15.InstantiationException 指定的类对象无法被实例化时,抛出该异常
16.EOFException 文件已结束异常
17.FileNotFoundException 文件未找到异常
3,ArithmeticException 算术异常 4,ArrayIndexOutOfBoundsException 数组下标越界
5,ArrayStoreException 数组中包含不兼容的值抛出的异常
6,SQLException 操作数据库异常类 7, NullPointerException 空指针异常
8,NoSuchFieldException 字段未找到异常 9,NoSuchMethodException 方法未找到抛出异常
10.NumberFormatException 字符串转换为数字抛出的异常
11.NegativeArraySizeException 数组元素个数为负数抛出的异常
12.StringIndexOutOfBoundsException 字符串索引超出范围抛出的异常
13.IOException 输入输出异常
14.IllegalAccessException 不允许访问某类异常
15.InstantiationException 指定的类对象无法被实例化时,抛出该异常
16.EOFException 文件已结束异常
17.FileNotFoundException 文件未找到异常
自定义异常
使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户只需继承Exception类即可自定义异常类。在程序中使用自定义异常类,大体可分为以下几个步骤:(1)创建自定义异常类。(2)在方法中通过throw关键字抛出异常对象。(3)如果在当前抛出异常的方法中处理异常,可以使用try-catch语句块捕获并处理,否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作。(4)在出现异常的方法的调用者中捕获并处理异常。
在方法中抛出异常
若某个方法可能会发生异常,但不想在当前方法中处理这个异常,则可以使用throws、throw关键字在方法中抛出异常。
使用throws关键字抛出异常
throws关键字通常被应用在声明方法时,用来指定方法可能抛出的异常。多个异常可使用逗号分隔。
使用throw关键字抛出异常
throw关键字通常用于方法体中,并且抛出一个异常对象。程序在执行到throw语句时立即终止,它后面的语句都不执行。通过throw抛出异常后,如果想在上一级代码中捕获并处理异常,则需要在抛出异常的方法中使用throws关键字在方法的声明中指明要抛出的异常;如果要捕捉throw抛出的异常,则必须使用try-catch语句块。throw通常用来抛出用户自定义异常。
运行时异常
RuntimeException异常是程序运行过程中抛出的异常。Java类库的每个包中都定义了异常类,所有这些类都是Throwable类的子类。Throwable类派生了两个子类,分别是Exception类和Error类。Error类及其子类用来描述Java运行系统中的内部错误以及资源耗尽的错误,这类错误比较严重。Exception类称为非致命性类,可以通过捕捉处理使程序继续执行。Exception类又根据错误发生的原因分为RuntimeException异常和除RuntimeException之外的异常。
异常的使用原则
Java异常强制用户去考虑程序的强健性和安全性。异常处理不应用来控制程序的正常流程,其主要作用是捕获程序在运行时发生异常并进行相应的处理。编写代码处理某个方法可能出现异常时,可遵循以下几个原则:
1,在当前方法声明中使用try-catch语句捕获异常
2,一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或异常的子类
3,如果父类抛出多个异常,则覆盖方法必须抛出那些异常的一个子集,不能抛出新异常
1,在当前方法声明中使用try-catch语句捕获异常
2,一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或异常的子类
3,如果父类抛出多个异常,则覆盖方法必须抛出那些异常的一个子集,不能抛出新异常
第十章 字符串
字符串是Java程序中经常处理的对象,如果字符串运用得不好,将影响到程序运行的效率。在Java中,字符串作为String类的实例来处理。以对象的方式处理字符串,将使字符串更加灵活、方便。了解字符串上可用的操作,可以节省程序编写与维护的时间。
String类
单个字符可以用char类型保存,多个字符组成的文本就需要保存在String对象中。String通常被称为字符串,一个String对象最多可以保存(232-1)个字节(占用4GB空间大小)的文本内容。
声明字符串
str = "你好";
str = new String("你好");//10和11行输出结果一致
String:指定该变量为字符串类型
str:任意有效的标识符,表字符串变量的名称
str = new String("你好");//10和11行输出结果一致
String:指定该变量为字符串类型
str:任意有效的标识符,表字符串变量的名称
创建字符串
在Java语言中,将字符串作为对象来处理,因此可以像创建其他类对象一样来创建字符串对象。创建对象要使用类的构造方法。String类的常用构造方法如下: 1,String(char a[])该方法用一个字符数组ch创建String对象
char[] ch = {'g','o','o','d'};
str = new String(ch);
//两者等价于 String ch = new String("good")
2,String(char a[],int offset,int lenght)该方法提取字符数组c中的一部分创建一个字符串对象。参数offest表示开始截取字符串的位置,lenght表示截取字符串的长度。
char[] c = {'s','t','u','d','e','n','t'};
String s = new String(c,1,3);//1为前索引,3为个数
//两者等价于 String s = new String("tud")
3,String(char value)该构造方法可分配一个新的String对象,使其表示字符串数组参数中所有的元素连接的结果
char[] c = {'s','t','u','d','e','n','t'};
String s = new String(c);
//两者等价于 String s = new String("student")
除了以上几种使用String类的构造方法来创建字符串变量外,还可以通过将字符串常量的引用赋值给一个字符串变量来创建字符串,代码如下:
String str1,str2;
str1 = "we are students"
str2 = "we are students"
char[] ch = {'g','o','o','d'};
str = new String(ch);
//两者等价于 String ch = new String("good")
2,String(char a[],int offset,int lenght)该方法提取字符数组c中的一部分创建一个字符串对象。参数offest表示开始截取字符串的位置,lenght表示截取字符串的长度。
char[] c = {'s','t','u','d','e','n','t'};
String s = new String(c,1,3);//1为前索引,3为个数
//两者等价于 String s = new String("tud")
3,String(char value)该构造方法可分配一个新的String对象,使其表示字符串数组参数中所有的元素连接的结果
char[] c = {'s','t','u','d','e','n','t'};
String s = new String(c);
//两者等价于 String s = new String("student")
除了以上几种使用String类的构造方法来创建字符串变量外,还可以通过将字符串常量的引用赋值给一个字符串变量来创建字符串,代码如下:
String str1,str2;
str1 = "we are students"
str2 = "we are students"
连接字符串
对于已声明的字符串,可以对其进行相应的操作,连接字符串就是字符操作中较简单的一种。可以对多个字符串进行连接,也可使字符串与其他数据类型进行连接。
连接多个字符串
使用“+”运算符可实现连接多个字符串的功能。“+”运算符可以连接多个String对象并产生一个新的String对象。
连接其他数据类型
字符串也可同其他基本数据类型进行连接。如果将字符串同其他数据类型数据进行连接,会将其他数据类型的数据直接转换成字符串。
获取字符串信息
字符串作为对象,可通过相应方法获取字符串的有效信息,如获取某字符串的长度、某个索引位置的字符等。
获取字符串长度
使用string类的length()方法可获取声明的字符串对象的长度:(str为字符串长度)
str.length();
获取字符串的长度: 、
String str = "we are students";
int size = str.length();
str.length();
获取字符串的长度: 、
String str = "we are students";
int size = str.length();
字符串查找
String类提供了两种查找字符串的方法,即indexOf()与lastIndexOf()方法。这两种方法都允许在字符串中搜索指定条件的字符或字符串。
indexOf(String s)
该方法用于返回参数字符串s在指定字符串中第一次出现的索引位置
str.indexOf(substr)
str:任意字符串对象 sbustr:要搜索的字符串
String str = "we are students";
int size = str.indexOf("a");//变量size的值是3
str.indexOf(substr)
str:任意字符串对象 sbustr:要搜索的字符串
String str = "we are students";
int size = str.indexOf("a");//变量size的值是3
lastIndexOf(String str)
该方法用于返回指定字符串最后一次出现的索引位置
str.lastindexOf(substr)
str:任意字符串对象 sbustr:要搜索的字符串
str.lastindexOf(substr)
str:任意字符串对象 sbustr:要搜索的字符串
获取指定索引位置的字符
使用charAt()方法可将指定索引处的字符返回:
str.charAt(int index)
str:任意字符串 index:整数型,用于指定要返回字符的下标
str.charAt(int index)
str:任意字符串 index:整数型,用于指定要返回字符的下标
字符串操作
获取字符串
通过String类的substring()方法可对字符串进行截取。substring()方法被两种不同的重载形式,来满足不同的需要。
substring(int beginIndex)
该方法返回是从指定的索引位置开始截取直到该字符串结尾的子串
str.substring(int beginIndex)
beginIndex:指定从某一索引处开始截取字符串 代码如下:
String str = "hello word";
String substr = str.substring(3);
str.substring(int beginIndex)
beginIndex:指定从某一索引处开始截取字符串 代码如下:
String str = "hello word";
String substr = str.substring(3);
substring(int beginIndex, int endIndex)
该方法返回的是从字符串某一索引位置开始截取至某一索引位置结束的子串。
substring(int beginIndex,int endIndex)
beginIndex:开始截取子字符串的索引位置 endIndex:子字符串在整个字符串中的结束位置
substring(int beginIndex,int endIndex)
beginIndex:开始截取子字符串的索引位置 endIndex:子字符串在整个字符串中的结束位置
去除空格
trim()方法返回字符串的副本,忽略前导空格和尾部空格:
str.trim() 其中,str为任意字符串对象。
str.trim() 其中,str为任意字符串对象。
字符串替换
replace()方法可实现将指定的字符或字符串替换成新的字符或字符串。
str.replace(CharSequence target,CharSequence replacement)
target:要替换的字符或字符串 replacement:用于替换原来字符串的内容 replace()方法返回的结果是一个新的字符串。如果字符或字符串oldChar没有出现在该对象表达式中的字符串序列中,则将原字符串返回。
str.replace(CharSequence target,CharSequence replacement)
target:要替换的字符或字符串 replacement:用于替换原来字符串的内容 replace()方法返回的结果是一个新的字符串。如果字符或字符串oldChar没有出现在该对象表达式中的字符串序列中,则将原字符串返回。
判断字符串的开始与结尾
startsWith()方法与endsWith()方法分别用于判断字符串是否以指定的内容开始或结束,这两个方法的返回值都是Boolean类型。
startsWith()方法
该方法用于判断当前字符串对象的前缀是否为参数指定的字符串结束
str.startsWith(String prefix)
prefix:指作为前缀的字符串
str.startsWith(String prefix)
prefix:指作为前缀的字符串
endsWith()方法
该方法用于判断当前字符串是否为以给定的字符串结束
str.endsWith(String suffix)
suffix:作为后缀的字符串
str.endsWith(String suffix)
suffix:作为后缀的字符串
判断字符串是否相等
对字符串对象进行比较不能简单地使用比较运算符“==”,因为比较运算符比较的是两个字符串的地址是否相同。即使两个字符串的内容相同,两个对象的内存地址也是不同的,使用比较运算符仍然会返回false。使用比较运算符比较两个字符串,代码如下:
String tom = new String("i am a student");
String jerry = new String("i am a student");
boolean b = (tom == jerry);
因此,要比较两个字符串内容是否相等,应使用equals()方法和equalsignorecase()方法。
String tom = new String("i am a student");
String jerry = new String("i am a student");
boolean b = (tom == jerry);
因此,要比较两个字符串内容是否相等,应使用equals()方法和equalsignorecase()方法。
equals()方法
如果两个字符串具有相同的字符和长度,则使用equals()方法进行比较时,返回true。否则,返回false。语法如下:
str.equals(String otherstr) 其中,str、otherstr是要比较的两个字符串对象。
str.equals(String otherstr) 其中,str、otherstr是要比较的两个字符串对象。
equalsIgnoreCase()方法
忽略了大小写的情况比较两个字符串是否相等,返回结果为Boolean类型。语法如下:
str.equalsIgnoreCase(String otherstr) 其中,str、otherstr是要比较的两个字符串对象。
str.equalsIgnoreCase(String otherstr) 其中,str、otherstr是要比较的两个字符串对象。
按字典顺序比较两个字符串
compareTo()方法为按字典顺序比较两个字符串,该比较基于字符串中各个字符的Unicode值,按字典顺序将String对象表示的字符序列与参数字符串所表示的字符序列进行比较。如果按字典顺序此String对象位于参数字符串之前,则比较结果为一个负整数;如果按字典顺序此String对象位于参数字符串之后,则比较结果为一个正整数;如果这两个字符串相等,则结果为0。语法如下:
str.compearTo(String otherstr)
说明:compareTo()方法只有在equals()方法返回turn时才返回0.
str.compearTo(String otherstr)
说明:compareTo()方法只有在equals()方法返回turn时才返回0.
字母大小写转换
toLowerCase()方法
该方法将字符串中的所有大写字母转换为小写。如果字符串中没有应该被转换的字符,则将原字符串返回;否则将返回一个新的字符串,将原字符串中每个大写字母都转换成小写,字符串长度不变。语法如下:str.toLowerCase() 其中,str是要进行转换的字符串。
toUpperCase()方法
该方法将字符串中所有的小写字母转换为大写。如果字符串中没有应该被转换的字符,则将原字符串返回;否则返回一个新字符串,将原字符串中每个小写字母都转换成大写,字符串长度不变。语法如下:str.toUpperCase() 其中,str是要进行转换的字符串。
字符串分割
使用split()方法可以使字符串按指定的分割字符或字符串进行分割,并将分割后的结果存放在字符串数组中。split()方法提供了以下两种字符串分割形式。
split(String sign)
该方法可根据给定的分割符对字符串进行拆分。语法如下:str.split(String sign) 其中,sign为分割字符串的分割符,也可以使用正则表达式。
split(String sign,int limit)
该方法可根据给定的分割符对字符串进行拆分,并限定拆分的次数。语法如下:str.split(String sign,int limit) sign:分割字符串的分割符,也可以使用正则表达式。 limit:限制的分割次数。
格式化字符串
String类的静态format()方法用于创建格式化的字符串。format()方法有两种重载形式
format(String format.Object...args)
该方法使用指定的格式字符串和参数返回一个格式化字符串,格式化后的新字符串使用本地默认的语言环境:
str.format(String format,Object...args)
str.format(String format,Object...args)
format(Local l,String format,Object...args)
该方法使用指定的语言环境,格式字符串和参数返回一个格式字符串,格式化后的新字符串使用其指定的语言环境:
str.format(Local l,String format,Object...args)
str.format(Local l,String format,Object...args)
日期和时间字符串格式化
在应用程序设计中,经常需要显示日期和时间。如果想输出满意的日期和时间格式,一般需要编写大量的代码、经过各种算法才能实现。format()方法通过给定的特殊转换符作为参数来实现对日期和时间的格式化。
日期格式化
Date date = new Date();
String s = String.format("%te",date);
String s = String.format("%te",date);
时间格式化
使用format()方法不仅可以完成日期的格式化,也可以实现时间的格式化。时间的格式化转换符要比日期的格式化转换符更多、更精确,它可以将时间格式化为时、分、秒、毫秒等。
格式化常见的日期时间组合
import java.util.Date;
public class DateAndTime {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Date date = new Date();//创建Date对象date
String time = String.format("%tc", date);//将date格式化
String form = String.format("%tF", date);
System.out.println("全部的时间信息是:"+ time);//将格式化后的日期时间输出
System.out.println("年-月-日格式"+ form);
}
}
public class DateAndTime {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Date date = new Date();//创建Date对象date
String time = String.format("%tc", date);//将date格式化
String form = String.format("%tF", date);
System.out.println("全部的时间信息是:"+ time);//将格式化后的日期时间输出
System.out.println("年-月-日格式"+ form);
}
}
常规类型格式化
public class General {
public static void main(String[] args) {
// TODO 自动生成的方法存根
String str=String.format("%d",400/2);//将结果以十进制格式显示
String str2=String.format("%b",3>5);//将结果以boolean型显示
String str3=String.format("%x",200);//将结果以十六进制显示z
System.out.println("400的一半是:"+str);//输出格式字符串
System.out.println("3>5正确吗:"+str2);
System.out.println("200的十六进制数是:"+str3);
}
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
String str=String.format("%d",400/2);//将结果以十进制格式显示
String str2=String.format("%b",3>5);//将结果以boolean型显示
String str3=String.format("%x",200);//将结果以十六进制显示z
System.out.println("400的一半是:"+str);//输出格式字符串
System.out.println("3>5正确吗:"+str2);
System.out.println("200的十六进制数是:"+str3);
}
}
使用正则表达式
正则表达式通常被用于判断语句中,用来检查某一字符串是否满足某一格式。正则表达式是含有一些具有特殊意义字符的字符串,这些特殊字符称为正则表达式的元字符。例如,“\\d”表示数字0~9中的任何一个,“\d”就是元字符。在正则表达式中,可以使用方括号括起若千个字符来表示一个元字符,该元字符可代表方括号中的任何一个字符。例如,reg =“[abc]4”,这样字符串 a4、b4、4 都是和正则表达式匹配的字符串。方括号元字符还可以为其他格式。如:
[456]:代表4、5、6之外的任何字符
[a-r]: 代表a~r中的任何一个字母。
[a-zA-Z]:可表示任意一个英文字母。
[a-e[g-z]]:代表 a~e 或 g~z 中的任何一个字母(并运算)。
[a-o&&[def]]:代表字母 d、e、f (交运算)。
[a-d&&[^bc]]: 代表字母 a、d(差运算)。
在正则表达式中允许使用限定修饰符来限定元字符出现的次数。
[456]:代表4、5、6之外的任何字符
[a-r]: 代表a~r中的任何一个字母。
[a-zA-Z]:可表示任意一个英文字母。
[a-e[g-z]]:代表 a~e 或 g~z 中的任何一个字母(并运算)。
[a-o&&[def]]:代表字母 d、e、f (交运算)。
[a-d&&[^bc]]: 代表字母 a、d(差运算)。
在正则表达式中允许使用限定修饰符来限定元字符出现的次数。
字符串生成器
创建成功的字符串对象,其长度是固定的,内容不能被改变和编译。虽然使用“+”可以达到附加新字符或字符串的目的,但“+”会产生一个新的String实例,会在内存中创建新的字符串对象。如果重复地对字符串进行修改,将极大地增加系统开销。而JDK新增了可变的字符序列StringBuilder类,大大提高了频繁增加字符串的效率。
append()方法
该方法用于向字符串生成器中追加内容。通过该方法的多个重载形式,可实现接受任何类型的费据,如int、boolean、char、String、double 或者另一个字符串生成器等。语法如下:
append(content)
其中,content表示要追加到字符串生成器中的内容,可以是任何类型的数据或者其他对象
append(content)
其中,content表示要追加到字符串生成器中的内容,可以是任何类型的数据或者其他对象
insert(int offset, arg)方法
该方法用于向字符串生成器中的指定位置插入数据内容。通过该方法的不同重载形式,可实现向字符串生成器中插入 int、float、char 和 boolean 等基本数据类型的数据或其他对象。语法如下:
insert(int offset arg)
ofset: 字符串生成器的位置。该参数必须大于等于0,且小于等于此序列的长度。
arg:将插入至字符串生成器的位置。该参数可以是任何数据类型的数据或其他对象。向字符串生成器中指定的位置添加字符,代码如下:
StringBuilder bf= new StringBuilder("hello");//创建字符生成器
bf.insert(5,"world");//添加至字符生成器的位置及内容
System.out.println(bf.toString());//此时输出信息为hello word
insert(int offset arg)
ofset: 字符串生成器的位置。该参数必须大于等于0,且小于等于此序列的长度。
arg:将插入至字符串生成器的位置。该参数可以是任何数据类型的数据或其他对象。向字符串生成器中指定的位置添加字符,代码如下:
StringBuilder bf= new StringBuilder("hello");//创建字符生成器
bf.insert(5,"world");//添加至字符生成器的位置及内容
System.out.println(bf.toString());//此时输出信息为hello word
delete(int start , int end)方法(前删后不删)
移除此序列的子字符串中的字符。该子字符串从指定的 start 处开始,一直到索引 end-1处的字符。如果不存在这种字符,则一直到序列尾部。如果 stat 等于 end,则不发生任何更改。语法如下:
delete(int start , int end)
start:将要删除的字符串的起点位置
end:将要删除的字符串的终点位置
删除指定位置的子字符串,代码如下:
StringBuilder bf = new StringBuilder("StringBuilder");//创建字符串生成器
bf.delete(5,10);//删除的子字符串
System.out.preintln(bf.toString());//此时输出的信息为Strinder
delete(int start , int end)
start:将要删除的字符串的起点位置
end:将要删除的字符串的终点位置
删除指定位置的子字符串,代码如下:
StringBuilder bf = new StringBuilder("StringBuilder");//创建字符串生成器
bf.delete(5,10);//删除的子字符串
System.out.preintln(bf.toString());//此时输出的信息为Strinder
第十一章 常用库类
包装类
Java是一种面向对象语言,但在Java中不能定义基本数据类型的对象,为了能将基本数据类型视为对象进行处理,Java提出了包装类的概念,它主要是将基本数据类型封装在包装类中,如int型的包装类Integer、boolean型的包装类Boolean等,这样便可以把这些基本数据类型转换为对象进行处理。
Integer类
Java.lang包中的integer类,byte类,short类和long类,分别将基本数据类型interesting,byte,short和long封装成一个类,由这些类都是number类的子类,区别就是封装不同的数据类型,其包含的方法基本相同。
integer类在对象包装一个基本数据类型int的值,该类的对象包含int类型的字段。
Integer类提供了以下4个常量:
MAXVALUE:表示int类型可取的最大值,即231-1。
MINVALUE:表示int类型可取的最小值,即-23。
SIZE:用来以二进制补码形式表示int值的位数。
TYPE:表示基本类型int的Class 实例。
integer类在对象包装一个基本数据类型int的值,该类的对象包含int类型的字段。
Integer类提供了以下4个常量:
MAXVALUE:表示int类型可取的最大值,即231-1。
MINVALUE:表示int类型可取的最小值,即-23。
SIZE:用来以二进制补码形式表示int值的位数。
TYPE:表示基本类型int的Class 实例。
Double类
ouble类和Float类是对double、float基本类型的封装,它们都是Number类的子类,都是对浮点数进行操作,所以常用方法基本相同。Double类在对象中包装一个基本类型为double的值,每个Double类的对象都包含一个double类型的字段。此外,该类还提供多个方法,可以将double类型转换为String类型,将String类型转换为double类型,也提供了其他一些处理double类型时有用的常量和方法。
Double 类主要提供了以下常量:
MAX_EXPONENT:返回 int 值,表示有限 double变量可能具有的最大指数
MIN EXPONENT:返回int值,表示标准化 double变量可能具有的最小指数
NEGATIVE_INFINITY:返回 double值,表示保存 double 类型的负无穷大值的常量
POSITIVE_INFINITY:返回 double值,表示保存 double类型的正无穷大值的常量
Double 类主要提供了以下常量:
MAX_EXPONENT:返回 int 值,表示有限 double变量可能具有的最大指数
MIN EXPONENT:返回int值,表示标准化 double变量可能具有的最小指数
NEGATIVE_INFINITY:返回 double值,表示保存 double 类型的负无穷大值的常量
POSITIVE_INFINITY:返回 double值,表示保存 double类型的正无穷大值的常量
Boolean类
Boolean类将基本类型为boolean的值包装在一个对象中。一个Boolean类型的对象只包含一个类型为boolean的字段。此外,此类还为boolean类型和String类型的相互转换提供了许多方法,并提供了处理boolean类型时非常有用的其他一些常量和方法。
Boolcan 提供了以下3个常量
TRUE:对应基值ie的 Boolean 对象
FALSEr对应基值lse 的 Boolcan 对象
TYPE:基本类型boolean的Class对象
Boolcan 提供了以下3个常量
TRUE:对应基值ie的 Boolean 对象
FALSEr对应基值lse 的 Boolcan 对象
TYPE:基本类型boolean的Class对象
Character类
Character类在对象中包装一个基本类型为char的值,该类提供了多种方法,以确定字符的类别(小写字母、数字等),并可以很方便地将字符从大写转换成小写,反之亦然。
Character类提供了大量表示特定字符的常量,例如:
CONNECTOR_PUNCTUATION:返回byte型值,表示 Unicode 规范中的常规类别“Pe"
UNASSIGNED:返回 byte 型值,表示 Unicode 规范中的常规类别“Cn”
TITLECASE_LETTER:返回 byte型值,表示Unicode规范中的常规类别“Lt”
Character类提供了大量表示特定字符的常量,例如:
CONNECTOR_PUNCTUATION:返回byte型值,表示 Unicode 规范中的常规类别“Pe"
UNASSIGNED:返回 byte 型值,表示 Unicode 规范中的常规类别“Cn”
TITLECASE_LETTER:返回 byte型值,表示Unicode规范中的常规类别“Lt”
Number类
前面介绍了Java中的包装类,对于数值型的包装类,它们有一个共同的父类——Number类,该类是一个抽象类,它是Byte、Integer、Short、Long、Float和Double类的父类,其子类必须提供将表示的数值转换为byte、int、short、long、float和double的方法。Number类的方法分别被其各子类所实现,也就是说,在Number类的所有子类中都包含以上这几种方法。
数字处理
数字格式化
数字格式化在解决实际问题时应用非常普遍,如表示某超市的商品价格,需要保留两位有效数字。数字格式化操作主要针对的是浮点型数据,包括double型和float型数据。在Java中,没有格式化的数据遵循以下原则:
口如果数据绝对值大于0.001 并且小于 10000000,使以常规小数形式表示。
口如果数据绝对值小于0.001或者大于10000000,使用科学记数法表示。
由于上述输出格式不能满足解决实际问题的要求,通常将结果格式化为指定形式后输出。在 Java中,可以使用DecimalFormat类进行格式化操作。DecimalFormat类是NumberFormat的一个子类用于格式化十进制数字。它可以将一些数字格式化为整数、浮点数、百分数等。通过使用该类可以为要输出的数字加上单位或控制数字的精度。一”情况下,可以在实例化 DecimalFormat 对象时传递数字格式,也可以通过 DecimalFormat 类中applyPattern0方法来实现数字格式化。当格式化数字时,可在DecimalFormat类中使用一些特殊字符构成一个格式化模板,使数字按照一定的特殊字符规则进行匹配。
口如果数据绝对值大于0.001 并且小于 10000000,使以常规小数形式表示。
口如果数据绝对值小于0.001或者大于10000000,使用科学记数法表示。
由于上述输出格式不能满足解决实际问题的要求,通常将结果格式化为指定形式后输出。在 Java中,可以使用DecimalFormat类进行格式化操作。DecimalFormat类是NumberFormat的一个子类用于格式化十进制数字。它可以将一些数字格式化为整数、浮点数、百分数等。通过使用该类可以为要输出的数字加上单位或控制数字的精度。一”情况下,可以在实例化 DecimalFormat 对象时传递数字格式,也可以通过 DecimalFormat 类中applyPattern0方法来实现数字格式化。当格式化数字时,可在DecimalFormat类中使用一些特殊字符构成一个格式化模板,使数字按照一定的特殊字符规则进行匹配。
Math类
Math 类提供了众多数学函数方法,主要包括三角函数方法,指数函数方法,取整函数方法,取大值、最小值,以及平均值函数方法。这些方法都被定义为 static 形式,所以在程序中应用比较简便可以使用如下形式调用:
Math.数学方法在 Math 类中,除函数方法外还存在一些常用数学常量,如I、E等。这些数学常量作为Mah的成员变量出现,调用起来也很简单。可以使用如下形式调用,
Math.PI
Math.E
Math 类中的常用数学运算方法较多,大致可以将其分为四大类别,分别为三角函数方法,指数数方法,取整函数方法,以及取最大值、最小值和绝对值函数方法。
Math.数学方法在 Math 类中,除函数方法外还存在一些常用数学常量,如I、E等。这些数学常量作为Mah的成员变量出现,调用起来也很简单。可以使用如下形式调用,
Math.PI
Math.E
Math 类中的常用数学运算方法较多,大致可以将其分为四大类别,分别为三角函数方法,指数数方法,取整函数方法,以及取最大值、最小值和绝对值函数方法。
三角函数方法
Math类中包含的三角函数方法如下:
publicstatic double sin(double a):返回角的三角正弦
public static double cos(double a):返回角的三角余弦
public static double tan(double a):返回角的三角正切
public static double asin(double a):返回一个值的反正弦
public static double acos(double a):返回一个值的反余弦
public static double atan(double a):返回一个值的反正切
public static double toRadians(double angdeg):将角度转换为弧度
public static double toDegrees(double angrad):将弧度转换为角度。
publicstatic double sin(double a):返回角的三角正弦
public static double cos(double a):返回角的三角余弦
public static double tan(double a):返回角的三角正切
public static double asin(double a):返回一个值的反正弦
public static double acos(double a):返回一个值的反余弦
public static double atan(double a):返回一个值的反正切
public static double toRadians(double angdeg):将角度转换为弧度
public static double toDegrees(double angrad):将弧度转换为角度。
指数函数方法
Math类中与指数相关的函数方法如下:
publicstatic double exp(doublea):用于获取e的a次方,即取e^2
publicstatic double log(doublea):用于取自然对数,即取Ina的值
publicstaticdoublelog10(doublea):用于取底数为10的a的对数。
public static doublesqrt(doublea):用于取a的平方根,其中a的值不能为负值。
public static double cbrt(doublea):用于取a的立方根。
public static double pow(double adouble b):用于取a的b次方
publicstatic double exp(doublea):用于获取e的a次方,即取e^2
publicstatic double log(doublea):用于取自然对数,即取Ina的值
publicstaticdoublelog10(doublea):用于取底数为10的a的对数。
public static doublesqrt(doublea):用于取a的平方根,其中a的值不能为负值。
public static double cbrt(doublea):用于取a的立方根。
public static double pow(double adouble b):用于取a的b次方
取整函数方法
在具体的问题中,取整操作使用也很普遍,所以Java在Mah类中添加了数字取整方法。Mahx
中主要包括以下几种取整方法:
public static double ceil(double a): 返回大于等于参数的最小整数
public static double floor(double a): 返回小于等于参数的最大整数
public static double rint(double a): 返与参数最接近的整数,如果存在两个同样接近的整数.
则结果取偶数。
public static int round(float a): 将参数加上05 后返与参数最近的整数
public static longround(double a): 将参数加上05 后返与参数最近的整数,然后强制转换为长整型。
中主要包括以下几种取整方法:
public static double ceil(double a): 返回大于等于参数的最小整数
public static double floor(double a): 返回小于等于参数的最大整数
public static double rint(double a): 返与参数最接近的整数,如果存在两个同样接近的整数.
则结果取偶数。
public static int round(float a): 将参数加上05 后返与参数最近的整数
public static longround(double a): 将参数加上05 后返与参数最近的整数,然后强制转换为长整型。
取最大值、最小值、绝对值函数方法
在程序中最常用的方法就是取最大值、最小值、绝对值等,Math 类中包括的操作方法如下:
public static double max(double adouble b):取a与b之间的最大值。
publicstaticintmin(intaint b):取a与b之间的最小值,参数为整型。
publicstaticlongmin(longa,longb):取a与b之间的最小值,参数为长整型。
public static float min(float a,float b): 取a与b之间的最小值,参数为单精度浮点型。
public static double min(double a,double b): 取a与b之间的最小值,参数为双精度浮点型
public staticintabs(inta):返回整型参数的绝对值。
public static longabs(longa):返回长整型参数的绝对值。
public static float abs(float a):返回单精度浮点型参数的绝对值。
public static double abs(doublea):返回双精度浮点型参数的绝对值。
public static double max(double adouble b):取a与b之间的最大值。
publicstaticintmin(intaint b):取a与b之间的最小值,参数为整型。
publicstaticlongmin(longa,longb):取a与b之间的最小值,参数为长整型。
public static float min(float a,float b): 取a与b之间的最小值,参数为单精度浮点型。
public static double min(double a,double b): 取a与b之间的最小值,参数为双精度浮点型
public staticintabs(inta):返回整型参数的绝对值。
public static longabs(longa):返回长整型参数的绝对值。
public static float abs(float a):返回单精度浮点型参数的绝对值。
public static double abs(doublea):返回双精度浮点型参数的绝对值。
Random类
Random类是JDK 中的随机数生成器类,可以通过实例化一个 Random 对象创建一个随机数生器,语法如下:
Random r = new Random():
以这种方式实例化对象时,Java 编译器将以系统当前时间作为随机数生成器的种子。因为解时刻的时间不可能相同,所以产生的随机数不同。但是如果运行速度太快,也会产生两个运行结累的随机数。
用户也可以在实例化 Random 类对象时,设置随机数生成器的种子。语法如下:
Random r = new Random(seedValue)
r:Random类对象。
scedValue:随机数生成器的种子。
在Random 类中,提供了获取各种数据类型随机数的方法,下面列举几个常用的方法:
public int nextInt():返回一个随机整数。
public int nextInt(int n): 返回大于等于0且小于n 的随机整数。
public long nextLong(): 返回一个随机长整型值。
public boolean nextBoolean(): 返回一个随机布尔型值。
public float nextFloat(): 返回一个随机单精度浮点型值。
public double nextDouble(): 返回一个随机双精度浮点型值。
public double nextGaussian():返回一个概率密度为高斯分布的双精度浮点型值
Random r = new Random():
以这种方式实例化对象时,Java 编译器将以系统当前时间作为随机数生成器的种子。因为解时刻的时间不可能相同,所以产生的随机数不同。但是如果运行速度太快,也会产生两个运行结累的随机数。
用户也可以在实例化 Random 类对象时,设置随机数生成器的种子。语法如下:
Random r = new Random(seedValue)
r:Random类对象。
scedValue:随机数生成器的种子。
在Random 类中,提供了获取各种数据类型随机数的方法,下面列举几个常用的方法:
public int nextInt():返回一个随机整数。
public int nextInt(int n): 返回大于等于0且小于n 的随机整数。
public long nextLong(): 返回一个随机长整型值。
public boolean nextBoolean(): 返回一个随机布尔型值。
public float nextFloat(): 返回一个随机单精度浮点型值。
public double nextDouble(): 返回一个随机双精度浮点型值。
public double nextGaussian():返回一个概率密度为高斯分布的双精度浮点型值
Biglnteger类
BigInteger类的数字范围较Integer类的数字范围要大得多。前文介绍过Integer类是int的包装类,int的最大值为231-1,如果要计算更大的数字,使用Integer类就无法实现了,所以Java中提供了BigInteger类来处理更大的数字。BigInteger类支持任意精度的整数,也就是说,在运算中BigInteger类可以准确地表示任何大小的整数值而不会丢失信息。在BigInteger类中封装了多种操作,除了基本的加、减、乘、除操作,还提供了绝对值、相反数、最大公约数以及判断是否为质数等操作。使用BigInteger类,可以实例化一个BigInteger对象,并自动调用相应的构造函数。BigInteger类具有很多构造函数,但最直接的一种方式是参数以字符串形式代表要处理的数字。例如,将2转换为 Biglnteger 类型,可以使用以下语句进行初始化操作:
Biglnteger twolnstance = new Biglnteger("2");
一旦创建了对象实例,就可以调用 BigInteger 类中的一些方法进行运算操作,包括基本的数学运享和位运算以及一些取相反数、取绝对值等操作。下面列举了 BigInteger 类中常用的几种运算方法:
public BigInteger add(BigInteger val): 做加法运算。
public BigInteger subtract(BigInteger va): 做减法运算
public BigInteger multiply(BigInteger val): 做乘法运算
public BigInteger divide(BigInteger val): 做除法运算。
public BigInteger remainder(BigInteger val): 做取余操作。
public BigInteger]] divideAndRemainder(BigInteger val): 用数组返回余数和商,结果数组中lt爱险法的商一个值为商,第二个值为余数。
public BigInteger pow(int exponent): 进行取参数的 exponent 次方操作。
public BigInteger negate0: 取相反数。
public BigInteger shifLef(int n): 将数字左移n位,如果n为负数,做右移操作
public BigInteger shiftRight(int n):将数字右移n位,如果n为负数,做左移操作
public BigInteger and(BigInteger val): 做与操作。
public BigInteger or(Biglnteger val): 做或操作。
public int compareTo(BigInteger val): 做数字比较操作。
public boolean equals(Object x): 当参数 x是 BigInteger 类型的数字并且数值与对象实例的数相等时,返回 true。
public BigInteger min(BigInteger val): 返回较小的数值。
public BigInteger max(BigInteger val): 返回较大的数值 。
Biglnteger twolnstance = new Biglnteger("2");
一旦创建了对象实例,就可以调用 BigInteger 类中的一些方法进行运算操作,包括基本的数学运享和位运算以及一些取相反数、取绝对值等操作。下面列举了 BigInteger 类中常用的几种运算方法:
public BigInteger add(BigInteger val): 做加法运算。
public BigInteger subtract(BigInteger va): 做减法运算
public BigInteger multiply(BigInteger val): 做乘法运算
public BigInteger divide(BigInteger val): 做除法运算。
public BigInteger remainder(BigInteger val): 做取余操作。
public BigInteger]] divideAndRemainder(BigInteger val): 用数组返回余数和商,结果数组中lt爱险法的商一个值为商,第二个值为余数。
public BigInteger pow(int exponent): 进行取参数的 exponent 次方操作。
public BigInteger negate0: 取相反数。
public BigInteger shifLef(int n): 将数字左移n位,如果n为负数,做右移操作
public BigInteger shiftRight(int n):将数字右移n位,如果n为负数,做左移操作
public BigInteger and(BigInteger val): 做与操作。
public BigInteger or(Biglnteger val): 做或操作。
public int compareTo(BigInteger val): 做数字比较操作。
public boolean equals(Object x): 当参数 x是 BigInteger 类型的数字并且数值与对象实例的数相等时,返回 true。
public BigInteger min(BigInteger val): 返回较小的数值。
public BigInteger max(BigInteger val): 返回较大的数值 。
BigDecimal类
BigDecimal类和BigInteger类都能实现大数字的运算,不同的是BigDecimal类加入了小数的概念。一般的float型和double型数据只可以用来做科学计算或工程计算,但由于在商业计算中要求数字精度比较高,所以要用到BigDecimal类。BigDecimal类支持任何精度的定点数,可以用它来精确计算货币值。BigDecimal类型的数字可以用来做超大的浮点数的运算,如加、减、乘、除等,但是在所有的运算中除法是最复杂的,因为在除不尽的情况下商小数点后的末位的处理是需要考虑的。
System类
System类是JDK中提供的系统类,该类是用final修饰的,所以不允许被继承。System类提供了很多系统层面的操作方法,并且这些方法全部都是静态的。
控制台输出字符
System类提供了标准输入、标准输出和错误输出流,也就是说,System类提供了3个静态对象:in、out和err。本书中的代码多次使用了这些对象,最常见的就是out对象。在控制台输出字符串,输出的方法有两种
不会自动换行的print()方法
print()方法的语法如下:
System.out.print("Hello!");
此方法输出“Hello”文字,输出完毕后,光标会停留在“Hello”文字末尾,不会自动换行。
System.out.print("Hello!");
此方法输出“Hello”文字,输出完毕后,光标会停留在“Hello”文字末尾,不会自动换行。
可以自动换行的println()方法
println()方法在print后面加上了“ln”后缀(就是line的简写),语法如下:
System.outprintln("书籍是人类进步的阶梯!");
此方法输出“书籍是人类进步的阶梯!”后会自动换行。光标停留在下一行的开头。
System.outprintln("书籍是人类进步的阶梯!");
此方法输出“书籍是人类进步的阶梯!”后会自动换行。光标停留在下一行的开头。
计时
System.currentTimeMillis()方法可以获取自1970年1月1日零点至今的毫秒数。虽然Date日期类也有类似的方法,但代码会比System类多,所以System.currentTimeMillis()方法是为获取当前毫秒数最常用的方法。因为该方法的返回值精确到毫秒,所以可以利用该方法来记录程序的运行时间。
Scanner类
与C语言不同,Java从控制台中读出用户输入的值,用到的不是一行可以直接使用的代码,而是由一个叫Scanner的类来实现的。Scanner英文直译就是扫描仪,它的用途就和现实生活的扫描仪一样,可以把数字化信息流转为人类可识别的文字。控制台输出内容用到了System.out就表示向控制台输出,System.in就表示从控制台输入,让Scanner扫描System.in就可以获取用户输入的值了。使用Scanner类首先要引入该类,其语法如下:
import iava.util.Scanner;//引入Scanner类
使用Scanner类扫描控制台的代码如下:
Scanner sc = new Scanner(System.in);
import iava.util.Scanner;//引入Scanner类
使用Scanner类扫描控制台的代码如下:
Scanner sc = new Scanner(System.in);
时间日期类
Date类
Date类用于表示日期时间,使用该类表示时间需要使用其构造方法创建对象。
使用 Date类的第2种构造方法创建一个 Date类的对象,代码如下:
long timeMillis=System.currentTimeMillis();
//当前系统时间所经历的毫秒数
Date date = new Date(timeMillis);上述代码中的System类的currentTimeMillis0方法主要用来获取当前系统时间距标准基准时间的毫秒数。另外,这里需要注意的是,创建 Date 对象时使用的是 long 型整数,而不是 double 型,这主要是因为 double类型可能会损失精度。
使用 Date类的第2种构造方法创建一个 Date类的对象,代码如下:
long timeMillis=System.currentTimeMillis();
//当前系统时间所经历的毫秒数
Date date = new Date(timeMillis);上述代码中的System类的currentTimeMillis0方法主要用来获取当前系统时间距标准基准时间的毫秒数。另外,这里需要注意的是,创建 Date 对象时使用的是 long 型整数,而不是 double 型,这主要是因为 double类型可能会损失精度。
日期时间格式化类
DateFormat 类是日期时间格式化子类的抽象类,可以按照指定的格式对日期或时间进行格式化DateFormat 类提供了很多类方法,以获得基于默认或给定语言环境和多种格式化风格的默认日期时间Formatter,格式化风格主要包括SHORT、MEDIUM、LONG和FULL4种:
SHORT:完全为数字,如12.13.52或3:30pm。
MEDIUM:较长,如Jan 12,1952。
LONG:更长,如January12,1952或3:30:32pm。
FULL:完全指定,如Tuesday、April12、1952AD或3:3042pm PST
另外,使用DateFormat类还可以自定义日期时间的格式。要格式化一个当前语言环境下的日期,首先需要创建DateFormat类的一个对象,由于它是抽象类,因此可以使用其静态方法getDateInstance()进行创建,语法如下:
DateFormat df = DateFormat.getDateInstance();
使用getDateInstance()方法获取的是所在国家或地区的标准日期格式。另外,DateFormat类还提供了一些其他静态方法。例如,使用getTimeInstance()方法可获取所在国家或地区的时间格式,使用getDateTimeInstance()方法可获取日期和时间格式。例如,将当前日期按照DateFormat类默认格式输出:
DateFormat df = DateFormat.getInstance();
System.out.println(df.format(new Date()));
输出长类型格式的当前时间:
DateFormat df = DateFormat.getTimeInstance(DateFormat.LONG);
System.out.println(df.format(new Date()));
输出长类型格式的当前日期:
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);
System.out.println(df.format(new Date()));
输出长类型格式的当前日期和时间:
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
System.out.println(df.format(new Date()));
由于DateFormat类是一个抽象类,不能用new创建实例对象。因此,除了使用getXXXInstance()方法创建其对象,还可以使用其子类,如SimpleDateFormat类,该类是一个以与语言环境相关的方式来格式化和分析日期的具体类,它允许进行格式化(日期→文本)、分析(文本→日期)和规范化。SimpleDateFormat类提供了19个格式化字符,可以让开发者随意编写日期格式。
SHORT:完全为数字,如12.13.52或3:30pm。
MEDIUM:较长,如Jan 12,1952。
LONG:更长,如January12,1952或3:30:32pm。
FULL:完全指定,如Tuesday、April12、1952AD或3:3042pm PST
另外,使用DateFormat类还可以自定义日期时间的格式。要格式化一个当前语言环境下的日期,首先需要创建DateFormat类的一个对象,由于它是抽象类,因此可以使用其静态方法getDateInstance()进行创建,语法如下:
DateFormat df = DateFormat.getDateInstance();
使用getDateInstance()方法获取的是所在国家或地区的标准日期格式。另外,DateFormat类还提供了一些其他静态方法。例如,使用getTimeInstance()方法可获取所在国家或地区的时间格式,使用getDateTimeInstance()方法可获取日期和时间格式。例如,将当前日期按照DateFormat类默认格式输出:
DateFormat df = DateFormat.getInstance();
System.out.println(df.format(new Date()));
输出长类型格式的当前时间:
DateFormat df = DateFormat.getTimeInstance(DateFormat.LONG);
System.out.println(df.format(new Date()));
输出长类型格式的当前日期:
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);
System.out.println(df.format(new Date()));
输出长类型格式的当前日期和时间:
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
System.out.println(df.format(new Date()));
由于DateFormat类是一个抽象类,不能用new创建实例对象。因此,除了使用getXXXInstance()方法创建其对象,还可以使用其子类,如SimpleDateFormat类,该类是一个以与语言环境相关的方式来格式化和分析日期的具体类,它允许进行格式化(日期→文本)、分析(文本→日期)和规范化。SimpleDateFormat类提供了19个格式化字符,可以让开发者随意编写日期格式。
Calendar类
打开Java API文档可以看到java.util.Date类提供的大部分方法都已经过时了,因为Date类在设计之初没有考虑到国际化,而且很多方法也不能满足用户需求,比如需要获取指定时间的年月日时分秒信息,或者想要对日期时间进行加减运算等复杂的操作,Date类已经不能胜任,因此JDK提供了新的时间处理类——Calendar日历类。Calendar类是一个抽象类,它为特定瞬间与一组诸如YEAR、MONTH、DAY_OF_MONTH、HOUR等日历字段之间的转换提供了一些方法,并为操作日历字段(如获得下星期的日期)提供了一些方法。另外,该类还为实现包范围外的具体日历系统提供了其他字段和方法,这些字段和方法被定义为protected。Calendar 提供了一个类方法 getInstance0,以获得此类型的一个通用的对象。Calendar 类的getInstance0方法返回一个Calendar对象,其日历字段已由当前日期和时间初始化,其使用方法如下:
Calendar rightNow = Calendar.getlnstance();
Calendar rightNow = Calendar.getlnstance();
Runtime类
Runtime类是JDK提供的运行时类,该类为Java程序提供了与当前运行环境相连接的一个通道,Java程序可以利用该类对当前的运行环境执行一些简单的操作。Runtime类不能使用new关键字创建实例,只能通过Runtime. getRuntime()方法获取实例。
执行本地命令
本地命令指的是操作系统的命令。例如,在Linux系统下就表示shell命令,在Windows系统下就表示cmd命令。Runtime类提供exec0方法让Java代码可以执行系统的命令,exec0方法有很多重载的形式,例如:
Process exec(String command)
Process exec(Stringl cmdarray)
Process exec(String command)
Process exec(Stringl cmdarray)
查看内存
Runtime类可以通过freeMemory()方法查看当前Java虚拟机可用内存的剩余量。如果程序能够实时监控内存剩余量,就可以尽量控制程序对内存的占用,从而避免出现“内存溢出”的情况。同样,也可以用来对测试程序性能,检验程序算法是否导致内存紧张。
收藏
0 条评论
下一页