java从入门到精通
2023-12-19 12:07:56 21 举报
AI智能生成
java入门
作者其他创作
大纲/内容
面向对象的程序设计语言
1.1.1 什么是java语言
桌面应用开发系统
嵌入式开发系统
电子商务应用
企业级应用开发
交互式系统开发
多媒体系统开发
分布式系统开发
WEB应用开发
移动端应用开发
1.1.2 java单独应用领域
jdk1.0~jdk15
所有代码都是开源代码。在Oracle jdk中但凡有产权的代码都被替换掉了,不存在知识产权纠纷,所以完全免费,任何人都可以随意下载
虽然都是代码开源的,但功能不完整,只包含了jdk中最精简的功能
不包含orcaljdk的deployment(部署)功能
不能使用java的咖啡杯商标
性能不如orcaljdk高
openjdk的特点
Javase和javaee
1.1.3 java的版本
明确目标,基础学习,了解模式
1.1.4 怎样学好java
1.1 java简介
简单
面向对象
分布性
可移植性
解释型
安全性
健壮性
多线程
高性能
动态
1.2 java语言的特性
jdk下载
在Windows10系统下搭建jdk环境
1.3 搭建java环境
一、初识java
它基于java语言编写,是目前最流行的java集成开发工具之一。
下载Eclipse:浏览器输入网址https://www.eclipse.org/downloads/
2.1 熟悉Eclipse
2.2.1 创建java项目
2.2.2 创建java类文件
1、打开编译器
2、编写代码
2.2.3 使用编译器编写程序代码
2.2 使用Eclipse
设置断点是程序调试中必不可少的手段,java调试器每次遇到程序断点时都会将单前线程挂起,即暂时当前程序的运行。
1、断点
要在Eclipse中调试HelloJava程序,可以在“包资源管理器”视图中的Hellojava文件处右击,在弹出的快捷菜单中选择“调试方式”命令
2、以调试方式运行java程序
程序执行到断点被暂停后,可以通过“调试”视图工具栏上的按钮执行相应的调试操作。
3、程序调试
2.3 程序调试
二、熟悉Eclipse开发工具
1、包声明:一个JAVA应用程序是由若干个类组成的.在例题3.1中就是一个类名为Frist的类,语句package Number为声明该类所在的包,package为包的关键字。
2、声明成员变量和局部变量:通常将类的属性称为类的全局变量(成员变量),将方法中的属性称为局部变量。全局变量声明在类体中,局部变量声明在方法体中。全局变量和局部变量都有各自的应用范围。在例题3.1中,s1是成员变量,s2是局部变量。
3、编写主方法:main()方法是类体中的主方法。该方法从“{”开始,至“}”结束。public、static和void分别是main()方法的权限修饰符、静态修饰符和返回值修饰符,Java程序中的main()方法必须声明为public static void。String[]args是一个字符串类型的·数组,它是main()方法的参数。main()方法是程序开始执行的位置。
4、导入API类库:在java语言中可以通过import关键字导入相关的类。在·JDK的API中(应用程序接口)提供了130多个包,如java.awt、java.io等。可以通过JDK的API文档来查看这些包中的类,把握类的继承结构、类的应用、成员变量表。构造方法表等,并对每个变量的使用目的进行了解,API文档是程序开发人员不可或缺的工具。
代码中的所有标点符号都是英文字符。不要在中文输入法状态下输入标点符号,还要注意大小写。
java程序的基本组成单元是类,类体中又包括属性和方法两部分。每一个应用程序都必须包含一个main()方法,含有main()方法的类称为主类
3.1 java主类结构
整数类型简称整型,用来存储整数数值,即没有小数部分的数值。可以是正数,也可以是负数。整型数据根据它所占内存大小的不同,可分为byte、short、int、和long4种类型。它们具有不同的取值范围,如下图所示。
3.2.1 整数类型
浮点类型简称浮点型,用来存储含有小数部分的数值。JAVA语言中浮点类型分为单精度浮点类型(float)和双精度浮点类型(double),它们具有不同的取值范围,如下图所示。
3.2.2 浮点类型
(1)char型:字符类型(char)用于存储单个字符,占用16(两个字节)的内存空间。在定义字符型变量时,要以单引号表示,如's'表示一个字符。但是“s”则表示一个字符串,虽然只有一个字符,但由于使用双引号,它仍然表示字符串,而不是字符。
(2)转义字符:转义字符是一种特殊的字行变量,它以反斜杠“\\”开头,后跟一个或多个字符。转义字符具有特定的含义,不同于字符原有的意义,故称“转义”。例如,printf的数的格式串中用到的“\”就是一个转义字符,意恩是“回车换行”。Java 中的转义字符如下表所示:
3.2.3 字符类型
布尔类型又称逻辑类型,简称布尔型,通过关键字boolean来定义布尔类型变量。布尔类型只有true和false两个值,分别代表布尔逻辑中的“真”和“假”。布尔值不能与整数类型进行转换。布尔类型通常被用在流程控制中,作为判断条件。
3.2.4 布尔类型
3.2 基本数据类型
1、标识符:标识符可以简单地理解为一个名字,是用来标识类名、变量名、方法名、数组名、文件名的有效字符序列。Java语言规定标识符由任意顺序的字母、下划线(___)、美元符号($)和数字组成,并且第一个字符不能是数字。标识符不能是Java中的关键字(保留字)。
2、关键字:关键字又称保留字,是Java语言中已经被赋予特定意义的一些单词,不可以把这些单词作为标识符来使用。
3.3.1 标识符和关键字
声明变量:变量的使用是程序设计中一个十分重要的环节。声明变量就是告诉编译器这个变量的数据类型,这样编译器才知道需要配置多少空间给它,以及它能存放什么样的数据。在程序运行过程中,空间内的值是变化的,这个内存空间就称为变量。为了便于操作,给这个空间取个名字,称为变量名。变量的命名必须是合法的标识符。内存空间内的值就是变量值。在声明变量时可以是没有赋值,也可以直接赋给初值。
对于变量的命名不是随意的,应遵循以下几条规则:1、变量名必须是一个有效的标识符。2、变量名不可以使用java中的关键字。 3、变量名不能重复。 4、应选择有意义的单词作为变量名。
3.3.2 声明变量
在程序运行过程中一直不会改变的量称为常量(constant),通常也被称为“final变量”。常量在整个程序中只能被赋值一次。在为所有的对象共享值时,常量是非常有用的。
3.3.3 声明常量
在类体中所声明的变量被称为成员变量,成员变量在整个类中都有效。类的成员变量又可分为两种,即静态变量和实例变量。
1、成员变量
在类的方法体中声明的变量(方法内部定义,“{”与“}”之间的代码中声明的变量)称为局部变量。局部变量只在当前代码块中有效,也就是只能在“{”与“}”之内使用。在类的方法中声明的变量,包括方法的参数,都属于局部变量。局部变量只在当前定义的方法内有效,不能用于类的其他方法中。局部变量的生命周期取决于方法,当方法被调用时,java虚拟机会为方法中的局部变量分配内存空间,当该方法的调用结束后,则会释放方法中局部变量占用的内存空间,局部变量也会被销毁。
2、局部变量
由于变量被定义出来后只是暂存在内存中,等到程序执行到某一个点,该变量会被释放掉,也就是说变量有它的生命周期。因此,变量的有效范围是指程序代码能够访问该变量的区域,若超出该区域,则在编译器会出现错误。在程序中,一般会根据变量的“有效范围”将变量分为“成员变量”和“局部变量”。
3.3.4 变量的有效范围
3.3 变量与常量
赋值运算符以符号“=”表示,它是一个二元运算符(对两个操作数作处理),其功能是将右方操作所含的值赋给左方的操作数。(从右往左运行)
3.4.1 赋值运算符
Java中的算术运算符主要有+(加)、-(减)、*(乘)、/(除)、%(求余),它们都是二元运算符。
3.4.2 算术运算符
自增、自减运算符是单目运算符,可以放在操作元之前,也可以放在操作元之后。操作元必须是一个整形或浮点型变量。自增、自减运算符的作用是使变量的值增1或减1。放在操作元前面的自增、自减运算符,会先将变量的值加1(减1),然后再使该变量参与表达式的运算。放在操作元后面的自增、自减运算符,会先使变量参与表达式的运算,然后再将该变量加1(减1)。(符号在前先运算再使用,符号再后先试用再运算。)
3.4.3 自增和自减运算符
比较运算符属于二元运算符,用于程序中的变量之间、变量和自变量之间以及其他类型的信息之间比较。比较运算符的运算结果是boolean型。当运算符对应的关系成立时,运算结果为true,否则为false。所有比较运算符通常作为判断的依据用在条件语句。比较运算符共有6个,如下图所示。
3.4.4 比较运算符
返回类型为布尔型的表达式,如比较运算符,可以被组合在一起构成一个更复杂的表达式。这是通过逻辑运算符来实现的。逻辑运算符包括&(&&)(逻辑与)、||(逻辑或)、!(逻辑非)。逻辑运算符的操作元必须是boolean型数据。在逻辑运算符中,除了“!”是一元运算符,其他都是二元运算符。下表给出了逻辑运算符的用法和含义。
结果为boolean型的变量或表达式可以通过逻辑运算符组合为逻辑表达式。用逻辑运算符进行逻辑运算是如下图所示:
3.4.5 逻辑运算符
(1)“按位与”运算(两者都为1,结果才是1)如图所示。
(2)“按位或”运算(只要有一者为1,结果就是1)如图所示。
(4)“按位异或”运算(两者相同即为0,不同为1)如图所示
(5)移位操作:除了上述运算符,还可以对数据按二进制位进行移位操作。Java中的移位运算符有一下3种:<<:左移(整体左移,空位补零,溢出去掉),>>:右移(整体右移,正数补零,负数补一,溢出去掉),>>>:无符号右移。(整体右移,空位补零,溢出去掉)。如图所示。
位运算符除“按位与”和“按位或”运算符外,其他只能用于处理整数的操作数,包括byte、short、char、int和long等数据类型。
3.4.6 位运算符
三元运算符的使用格式为:条件式 ? 值1:值2 运算规则为:若条件式的值为true,则整个表达式取值1,否则取值2.
3.4.7 三元运算符
通常,优先级由高到低的顺序依次是:增量和减量运算——>算术运算——>比较运算——>逻辑运算——>赋值运算
3.4.8 运算符优先级
3.4 运算符
从低级类型向高级类型的转换,系统将自动执行,程序员无须进行任何操作。这些类型按精度从低到高的顺序为byte<short<int<long<float<double。
3.5.1 隐式类型转换(自动转换类型,一定不会丢失数据)
当把高精度的变量的值赋给低精度的变量时,必须使用显式类型转换运算,语法为:(类型名)要转换的值 除boolean类型外,其他基本类型都能以显式类型转换的方法实现转换。
3.5.2 显示类型转换(强制类型转换,有可能会丢失数据)
3.5 数据类型转换
1、单倍注释:“//”为单行注释标记,从符号“//”开始直到换行为止的所有内容均作为注释而被编译器忽略。语法为://注释内容
2、多行注释:”/* */“为多行注释标记,符号”/*“与符号”*/\"之间的所有内容均为注释内容。注释的内容可以换行。语法为:/* 注释内容 注释内容 …… */
3、文档注释:“/** */“为文档注释标记。符号”/**“与”*/“之间的内容均为文档注释内容。
3.6 代码注释与编码规范
三、java语言基础
Java语言的复合语句是以整个块区为单位的语句。所以又称块语句。符合语句由开括号“{”开始,闭括号“}”结束。
4.1 复合语句
1.简单的if条件语句语法:if(布尔表达式){ 语句序列 } ·布尔表达式:必要参数,表示最后返回的结果必须是一个布尔值。它可以是一个单纯的布尔变量或常量,也可以是使用关系或布尔运算符的表达式。语句序列:可选参数。可以是一条或多条语句,当表达式的值为true时执行这些语句。若语句序列中仅有一条语句,则可以省略条件语句中的“{}”。
if……else语句是条件语句中最常用的一种形式,它会针对某种条件有选择地做出处理。通常表现为“如果满足某种条件,就进行某种处理,否则就进行另一种处理”。语法为:if(条件表达式){语句序列1}else{语句序列2} if后面“()”内的表达式的值必须是boolean型的。如果表达式的值为true,则执行紧跟if语句的复合语句;如果表达式的值为false,则执行else后面的复合语句。同简单的if条件语句一样,如果if……else语句的语句序列中只有一条语句(不包括注释),则可以省略该语句序列外面的“{}”。有时为了编程的需要,else或if后面的“{}”中可以没有语句。
2、if…else语句
if……else if多分支语句用于针对某一事件的多种情况进行处理。通常表现为“如果满足某种条件,就进行某种处理,否则如果满足另一种条件则执行另一种处理”。语法为:if(条件表达式1){ 语句序列1}else if(条件表达式2){ 语句序列2}……else if(条件表达式n){ 语句序列n} 条件表达式1~条件表达式n:必要参数。可以由多个表达式组成,但最后返回的结果一定要为boolean类型。·语句序列:可以是一条或多条语句,当条件表达式1的值为true时,执行语句序列1;当条件表达式2的值为true时,执行语句序列2,以此类推。当省略任意一组语句序列时,可以保留其外面的“{}”,也可以将“{}”替换为“;”。
3、if…else if多分支语句
在编程中,一个常见的问题就是检测一个变量是否符合某个条件,如果不符合,再用另一个值来检测,以此类推。在Java中,可以用Switch语句将动作组织起来,以一个较简单明了的方式来实现“多选一”的选择。语法如下:switch(表达式){case 常量值1: 语句块1 [break]……case 常量值n: 语句块n [break]default: 语句块n+1 [break]} switch语句中表达式的值必须是整型、字符型、字符串类型或枚举类型,常量值1~n的数据类型必须与表达式的值的类型相同。switch语句首先计算表达式的值,如果表达式的计算结果和某个case后面的常量值相同,则执行该case语句后的若干个语句直到遇到break语句为止。同一个 switch语句,case的常量值必须互不相同。在 switch语句中,case语句后常量表达式的值可以为整数,但绝不可以是非整数的实数。
4、switch多分支语句
4.2.1 if条件语句 if条件语句是一个重要的编程语句,用于告诉程序在某个条件成立的情况下执行某段语句,而在另一种情况下执行另外的语句。
4.2 条件语句
while语句也称条件判断语句,它的循环方式为利用一个条件来控制是否要继续反复执行这个语句。语法如下:while(条件表达式){语句序列} 当条件表达式的返回值为真时,则执行“{}”中的语句,当执行完“{}”中的语句后,重新判断条件表达式的返回值,直到表达式返回的结果为假时,退出循环。
4.3.1 while循环语句
do……while循环语句与while循环语句类似,它们之间的区别是while语句为先判断条件是否成立,再执行循环体,而do……while循环语句则先执行一次循环后,再判断条件成立。也就是说,do……while循环语句“{}”中的程序段至少要被执行一次。语法如下:do{语句序列}while(条件表达式) do……while语句与while语句的一个明显的区别是,do……while语句在结尾处多了一个分号。
4.3.2 do……while循环语句
传统的for语句中有3个表达式,其语法如下:for(表达式1;表达式2;表达式3){ 语句序列} 表达式1:初始化表达式,负责完成变量的初始化。表达式2:循环条件表达式,值为Boolean型的表达式,指定循环条件。等同于while循环里的表达式。表达式3:每次循环结束后执行的语句,通常用来改变循环条件在执行for循环时,首先执行表达式1,完成某一变量的初始化工作;下一步判断表达式2的值,若表达式的值为true,则进入循环体;在执行完循环体后紧接着计算表达式3,这部分通常是增加或减少循环控制变量的一个表达式。这样一轮循环就结束了。第2轮循环从计算表达式2开始,若表达式2返回true,则继续循环,否则跳出整个for语句。
1、for语句
foreach语句是for语句的特殊简化版本,不能完全取代for语句,但任何foreach语句都可以改写为for语句版本。 foreach并不是一个关键字,习惯上将这种特殊的for语句格式称为 foreach语句。语法如下:for(元素类型 x:遍历对象obj){ 引用了x的Java语句;} foreach语句中的元素变量x,不必对其进行初始化。
2. foreach语句
for循环是Java程序设计中最有用的循环语句之一。一个for循环可以用来重复执行某条语句,直到某个条件得到满足。for循环有两种语句,一种是传统的for语句,一种是foreach语句
4.3.3 for循环语句
4.3 循环语句
使用 break语句可以跳出Switch结构。在循环结构中,同样也可以 break语句跳出当前语句结束循环体。从而中断当前循环。循环嵌套情况下,break语句将只会使程序流程跳出包含它的最内层的循环结构,即只跳出一层循环。如果想让break跳出外层循环,Java提供了“标签”的功能,语法如下:标签名:循环体{ break标签名;} 标签名:任意表示符循环体:任意循环语句break标签名:break跳出指定的循环体,此循环体的标签名必须与break的标签名一致。带有标签的break可以指定跳出的循环,这个循环可以是内层循环,也可以是外层循环。
4.4.1 break语句
continue语句是针对break语句的补充。 continue不是立即跳出循环体,而是跳过本次循环,回到循环的条件测试部分,重新开始执行循环。在for循环语句中遇到 continue后,首先执行循环的增量部分,然后进行条件测试。与break语句一样,continue也支持标签功能,语法如下: 标签名:循环体{continue标签名} 标签名:任意标识符循环体:任意循环语句continue标签名:continue跳出指定的循环体,此循环体的标签名必须与continue的标签名一致。
4.4.2 continue语句
4.4 循环控制
四、流程控制
数组是最常见的一种数据结构,是同类型的用一个标识符封装到一起的基本类型数据序列或对象序列。可以用一个统一的数组名和下标来唯一确定数组中的元素。实质上,数组是一个简单的线性序列,因此访问速度很快。数组是具有相同数据类型的一组数据的集合。在程序设计中,可以将这些集合称为数组。数组中的每一个元素具有相同的数据类型。在Java中同样将数组看作一个对象,虽然基本数据类型不是对象,但由基本数据类型组成的数据确是对象。
5.1 数组概述
在上图中,arr为数组名称,方括号“[]”中的值为数组下标。数组通过下标来区分数组中不同的元素。数组下标是从0开始。由于创建的数组aar中有5个元素,因此数组中元素下标为0~4.
1.先声明,再用new关键字进行内存分配声明一维数组有下列两种方式:(1)数组元素类型 数组名字[];(2)数组元素类型[]数组名字;数组元素类型决定了数组的数据类型,它可以是Java中任意的数据类型,包括简单类型数据,包括简单类型和组合类型。数组名字为一个合法的标识符,符号“【】”指明该变量是一个数组类型变量。单个“[]”表示要创建的数组是一个一维数组。声明一维数组,代码为:int arr[]; //声明int型数组,数组中每一个元素都是int型数值 声明数组后,还不能立即访问它的任何元素,因为声明数组只是给出了数组名字和元素的数据类型,要想真正使用数组,还要为它分配内存空间。在为数组分配内存空间时必须指明数组长度。为数组分配内存空间的语法格式如下:数组名字=new数组元素的类型[数组元素的个数];数组名称:被连接到数组变量名称。数组元素的个数:指定数组中变量的个数,即数组的长度。通过上面的语法可知,使用new关键字为数组分配内存时,必须指定数组元素的类型和数组元素的类型和数组元素的个数,即数组长度。为数组分配内存,代码为:arr=new int[5]; 以上代码表示要创建一个含有5个元素的整形数组,并且将创建的数组对象赋给引用变量arr,即通过引用变量arr来引用这个数组,如右图所示:
2.声明的同时为数组分配内存 这种创建数组的方法是将数组的声明和分配合在一起执行。语法如下: 数组元素的类型 数组名 =new数组元素的类型[数组元素的个数]; 声明并为数组分配内存,代码为:int month[]=new int[12] 上面的代码创建数组month,并指定了数组长度为12的。这种创建数组的方法也是Java程序编写过程中普遍的做法。
数组作为对象允许使用new关键字进行内层分配。在使用数组之前,必须首先定义数组变量所属的类型。一维数组的创建有两种形式。
5.2.1 创建一维数组
5.2.2 初始化一维数组
结果如上:
例题5.1 使用一维数组输出1~12月每个月份的天数
5.2.3 使用一维数组
一维数组实质上是一组相同类型数据的线性集合,当在程序中需要处理一组数据,或者传递一组数据时,可以应用这种类型的数组。
5.2 一维数组
1、先声明,再用new关键字进行内存分配声明二维数组的语法如下:数组元素的类型 数组名字[][];数组元素的类型[][] 数组名字;声明二维数组,代码如下: int a[][]; 同一维数组一样,二维数组在声明时也没有分配内存空间,同样要使用new关键字来分配内存,然后才可以访问每个元素。对于高维数组,有两种为数组分配内存的方式。第一种内存分配方式是直接为每一维分配内存空间,代码如下:a==new int[2][4] 上述代码创建了二维数组a,二维数组a中包括两个长度为4的数组,内存分配图如右所示
第二种内存分配方式是分别为每一维分配内存,代码如下:a = new int[2][];a[0]=new int[2];a[1]=new int[3]; 上述代码创建了二维数组a,但是只声明了a第一维的长度,也就是“行数”,第二维的长度也就是“列数”,则是为每一行单独声明的,因此创建的数组a是“不定长数组”,其内存分配如右图所示。
2、声明的同时为数组分配内存 第二种创建方式与第一种实现的功能相同,只不过声明与赋值合并到同一行代码中。例如,创建一个2行4列的二维数组,代码如下: int a=new int[2][4]
二维数组可以看作是特殊的一维数组,因此二维数组的创建同样有两种方式。
5.3.1 创建二维数组
5.3.2 初始化二维数组
代码结果
代码为: public class Matrix { //创造类 public static void main(String[] args) { //主方法 int a[][] = new int[3][4]; //定义二维数组 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(); //输出空格 } }}
例5.2 输出一个3行4列且所有元素都为0的矩阵
5.3.3 使用二维数组
如果一维数组中各个元素仍然是一个数组,那么它就是一个二维数组。二维数组常用于表示表,表中的信息以行和列的形式组织,第一个下标代表元素所在的行,第二个下标代表元素所在的列。
5.3 二维数组
例5.3 呈梯形输出二维数组中的元素
遍历数组就是获取数组中的每一个元素。通常遍历数组都是使用for循环来实现。遍历二维数组需使用双层for循环,通过数组的length属性可获得数组的长度。
例5.4 使用foreach语句遍历二维数组
在遍历数组时,使用foreach语句可能会更简单。
5.4.1 遍历数组
例5.5 使用fill(方法填充数组元素)
例5.6 使用fill()方法替换数组中的元素
数组中的元素定义完成后,可通过Arrays类的静态方法fill()来对数组中的元素进行替换。该方法通过各种重载形式可完成对任意类型的数组元素的替换。
5.4.2 填充替换数组元素
代码结果·
例5.7 使用sort()方法将数组排序后输出
5.4.3 对数组进行排序
例5.8 复制数组
例5.9按照索引复制数组
Arrays类的copyOf()方法与copyOfRange()方法可以实现对数组的复制。copyOf()方法是复制数组至指定长度,copyOfRange()方法则将指定数组的指定长度复制到一个新数组中。
5.4.4 复制数组
例5.10 查找元素在数组中的索引位置
代码为: import java.util.Arrays; //导入java.util.Arrays类public class Rakel { //创造类 public static void main(String[] args) { //主方法 String str[] = new String[] {\"ab\
例5.11在指定范围内查找元素在数组中的索引位置
Arrays类的binarySearch()方法,可使用二分搜索法来搜索指定数组,以获得指定对象,该方法返回要搜索元素的索引值。binarySearch()方法提供了多种重裁形式,用于满足各种类型数组的查找需要。
5.4.5 查询数组
5.4 数组的基本操作
冒泡排序是最常用的数组排序算法之一,它排序数组元素的过程总是将较小的数往前放、较大的数往后放,类似水中气泡往上升的动作,所以称为冒泡排序。
5.5.1 冒泡排序
直接选择排序属于的基本思想是将排序位置元素与其他数组元素分别对比,如果满足条件就交换元素值。
5.5.2 直接选择排序
反转排序的基本思想比较简单,也很好理解,其实现思路就是把数组最后一个元素与第一个元素替换,倒数第二个元素与第二个元素替换,以此类推,直到把所有数组元素反转替换。
5.5.3 反转排序
5.5 数组排序算法
五、数组
现实生活中,随处可见的一种事物就是对象。对象是事物存在的实体,如人、书桌、计算机、高楼大厦等。人类解决问题的方式总是将复杂的事物简单化,于是就会思考这些对象都是由哪些部分组成的。通常都会将对象划分为两个部分,即静态部分与动态部分。顾名思义,静态部分就是不能动的部分,这个部分被称为“属性”,任何对象都会具备其自身属性,如一个人,其属性包含高矮、胖瘦、性别、年龄等。动态部分即对象可执行的动作,这部分称为“行为”,也是一个值得探讨的部分,同样对于一个人,其可以哭泣、微笑、说话、行走,这些都是这个人具备的行为。人类通过探讨对象的属性和观察对象的行为来了解对象。在计算机的世界中,面向对象程序设计的思想要以对象来思考问题,首先要将现实世界的实体抽象为对象,然后考虑这个对象具备的属性和行为。
6.1.1 对象
不能将一个事物描述成一类事物,如一只鸟不能称为鸟类。但如果要给某一事物一个统称,就需要用到类这个概念。类及时同一类事物的统称,如果将现实世界中的一个事物抽象成对象,类就是这类对象等等统称,如鸟类、家禽类、人类等。类是构造对象时所依赖的规范,如一只鸟有一对翅膀,它可以用这对翅膀飞行,而基本上所有的鸟都具有“有翅膀”这个特性和飞行的技能,这样具有相同特性和行为的一类事物就称为类,类的思想就是这样产生的。类是封装对象的属性和行为的载体,反过来说,具有相同属性和行为的一类实体被称为类。在JAVA语言中,类对象的行为是以方法的形式定义的,对象的属性是以成员变量的形式定义的,所以类包括对象的属性和方法
6.1.2 类
面向对象程序设计具有一下特点:封装性、继承性和多态性。封装是面向对象编程的核心思想。将对象的属性和行为封装起来,其载体就是类,类通常对客户隐藏其实现细节,这就是封装思想。例如,用户使用计算机时,只需要使用手指敲击键盘就可以实现一些功能,无须知道计算机内部是如何工作原理,但在使用计算机时也并不完全依赖于计算机工作原理等细节。采用封装的思想保证了类内部数据结构的完整性,使用类的用户不能轻易地直接操作类的数据结构,只能执行类允许公开的数据。这样就避免了外部操作对内部数据的影响,提高了程序的可维护性。
6.1.3 封装
从上图中可以看出,继承关系可以使用树形关系来表达,父类与子类存在一种层次关系。一个类处于继承体系中,它既可以是其他类型的父类,为其他类提供属性和行为,也可以是其他类的子类,继承父类的属性和方法,如三角形类既是图形类的子类也是等边三角形的父类。
类与类之间同样具有关系,这种关系被称为关联。关联主要描述两个类之间的一般二元关系。例如,一个百货公司类与销售员类就是一个关联,学生类与教师类就是一个关联。两个类之间的关系有很多种,继承是关联的一种。
6.1.4 继承
6.1.5多态
在程序开发初期,人们使用结构化开发语言。随着软件的规模越来越庞大,结构化语言的弊端也逐渐暴露出来,开发周期越来越长,产品的质量也不尽人意。这时人们开始将另一种开发思想引入程序中,即面向对象的开发思想。面向对象思想是人类最自然的一种思考方式,它将所有预处理的问题抽象为对象,通过了解这些对象具有哪些相应的属性以及展示这些对象行为,以解决这些对象面临的一些实际问题。在程序开发中引入面向对象设计的概念,其实质上就是对现实世界中的对象进行建模操作。
6.1 面向对象概述
在Java中,对象的属性也称为成员变量,成员变量可以是任意类型,整个类中均是成员变量作用范围。
6.2.1 成员变量
在Java语言中,使用成员方法对应于类对象的行为。一个·成员方法可以有参数,这个参数可以是对象,也可以是基本数据类型的变量,同时成员方法有返回值和不返回任何值的选择,如果方法需要返回值,可以在方法体中使用return关键字,使用这个关键字后,方法的执行将被终止。
6.2.2 成员方法
6.2.3 仅限修饰符
局部变量是在方法被执行是创建,在方法执行结束时销毁。局部变量在使用时必须进行赋值操作或被初始化,否则会出现编译器错误。
6.2.4 局部变量
可以将局部变量的有效范围称为变量的作用域,局部变量的有效范围从该变量的声明开始到该变量的结束为止。
6.2.5 局部变量的有效范围
语法:public void setName(String name){ //定义一个setName()方法 this.name = name; // 将参数值赋予类中的成员变量
6.2.6 this关键字
6.2 类
构造方法是一个与类同名的方法,对象的创建就是通过构造方法完成的。构造方法符特点为:构造方法没有返回值,构造方法的名称要与本类的名称相同
6.3 类的构造方法
静态就是static,可以有静态常量、静态变量、静态方法和多个语句静态静态是这个类的专属,只有这个类可以用,就是这个文件可以用,只要它们在一个文件里就行
6.4静态变量和静态方法
、运行结果
然后输入,用换行隔开
点击,然后以下操作
package b; public class s { public static void main(String [] args) {//主方法 for(int i=0;i<args.length;i++) {//根据参数个数做循环操作 System.out.println(args[i]);//打印结果 } }} 在代码运行前要先设置参数,右击界面
(String [] args)有什么用,怎么用
6.5 类的主方法
test对象被创建出来时,就是一个对象的引用,这个引用在内存中为对象分配了存储空间
6.6.1 对象的创建
6.6.2 反问对象的属性和行为
真正的操作标识符实质上是一个引用,引用的语法 类名 对象的引用变量b d1 =new b();b是类名,d1是引用名,new b对象的实体
6.6.3对象的引用
虽然JAVA的垃圾回收机制已经很完善,但垃圾回收只能回收那些由new操作符创建的对象某些对象不是通过new创造并获得存储空间的这些对象是无法被垃圾回收机制所识别finalize()那么JAVA提供了一个finalize方法这个方法是object类方法,他被声明为protected,用户可以在自己的类中定义这个方法,定义了这个方法后,垃圾回收时会首先调用该方法system.gc()由于垃圾回收不受人为控制,具体的执行时间也不能明确的确定,所以finalize()方法也就无法执行,因此JAVA又提供了system.gc()方法来强制启动垃圾回收器,会主动告知垃圾回收器来清理垃圾
为什么要销毁对象每个对象都有生命周期,当对象的生命周期结束时,分配给该对象的内存地址需要被回收垃圾回收器在其他语言中,需要用户手动回收废弃的对象,JAVA拥有一套完整的垃圾回收机制,用户不必担心废弃的对象占用内存,垃圾回收器会自动回收无用却占用内存的资源怎么判断对象会被JAVA虚拟机视为垃圾?主要包括两种情况:1、对象引用超过其作用范围,这个对象将被视为垃圾。2、将对象赋值为null
6.6.4 对象的销毁
6.6 对象
六、类和对象
7.1 类的继承
getClass()方法是Object类定义的方法,它会返回对象执行时的Class实例,然后使用此实例调用getName()方法可以取得类的名称。语法如下:getClass().getname();可以将getClass()方法与toString()方法联合使用。
getClass()方法
toString()方法的功能是将一个对象返回为字符串形式,它会返回一个String实例。在实际的应用中通常重写toString()方法,为对象提供一个特定的输出模式。当这个类转换为字符串或与字符串连接时,将自动调用重写的toString()方法。
toString()方法
在Java语言中,有两种比较对象的方式,分别为“==”运算符与equals()方法。两者的区别在于:“==”比较的两个对象引用内地地址是否相等,而equals()方法比较的是两个对象的实际内容。
equals()方法
Object类是比较特殊的类,它是所有类的父类,是Java类层中最高层类。用户创建一个类时,除非已经指定要从其他类继承,否则它就是从Java.lang.Object类继承而来的。Java中的每个类都源于Java.lang.Object类,如String类、Integer类等都是继承Object类。除此之外,自定义的类也都继承于Object类。在Object类中,主要包括clone()、finalize()、equals()、toString()等方法,由于所有的类都是Object类的子类,所以任何类都可以重写Object类中的方法。注意:Object类中的getClass()、notify()、notifyAll()、wait()等方法不能被重写,因为这些方法被定义为final类型。
7.2 Object类
向上转型可以被理解为将子类类型的对象转换为父类类型的对象,即把子类类型的对象之间赋值给父类类型的对象,进而实现按照父类描述子类的效果。
7.3.1 向上转型
向下转型可以被理解为将父类类型的对象转换为子类类型的对象。但是,运用向下转型,如果把一个较抽象的类的对象转换为一个较具体的类的对象,这样的转型通常会出现错误。
7.3.2 向下转型
7.3 对象类型的转换
当在程序中执行向下转型操作时,如果父类对象不是子类对象的实例,就会发生ClassCastException异常,所以在执行向下转型之前需要养成一个良好的习惯,就是判断父类对象是否为子类对象的实例。可以使用instanceof关键字判断是否一个类实现了某个接口,也可以用它来判断一个实例对象是否属于一个类。语法如下:myobject instanceof ExampleClassmyobject:某类的对象引用ExampleClass:某个类
7.4 使用instanceof关键字判断对象类型
方法的重载就是在同一个类中允许存在一个以上的同名方法,只要这些方法的参数个数或类型不同即可。
7.5 方法的重载
final关键字可用于变量声明,一旦该变量被设定,就不可以再改变该变量的值。通常,由final定义的变量为常量。final关键字定义的变量必须声明时对其进行赋值操作。final除了可以修饰基本数据类型的常量还可以修饰对象的引用,也可以用来修饰数组。一旦一个对象引用被修饰为final后,它就只能恒定指向一个对象,无法将其改变以指向另一个对象。
7.6.1 final变量
将方法定义为final类型,可以防止子类修改父类的定义与实现方式,同时定义为final的方法的执行效率要高于非final方法。如果一个父类的某个方法被设置为private,子类将无法访问该方法,自然无法覆盖该方法。
7.6.2 final方法
定义为final的类不能被继承。如果希望一个类不被任何类继承,并且不允许其他人对这个类进行任何改动,可以将这个类设置为final类。语法如下:final 类名{}如果将某个类设置为final类,则该类中的所有方法都被隐式设置为final方法,但是final类中的成员变量可以被定义为final或非final形式。版权协议,转载请附上原文出处链接及本声明。
7.6.3 final类
7.6 final关键字
从实例中可以看出,以不同类对象为参数调用draw()方法,可以处理不同的图形绘制问题。使用多态节省了开发和维护时间,因为程序员无须在所有的子类中定义执行相同功能的方法,避免了大量重复代码的编写。同时,只要实例化一个继承父类的子类对象,即可调用相应的方法,如果需求发生了变更,只需要维护一个draw()方法即可。
class Shape1{}; //图形类class Square1 extends Shape1{}; //正方形类继承图形类class Circular1 extends Shape1{}; //图形类继承图形类 public class Demo6 { public static void draw(Shape1 s) { //绘制方法 if(s instanceof Square1) { //如果是正方形 System.out.println(\"绘制正方形\"); }else if(s instanceof Circular1) { //如果是圆形 System.out.println(\"绘制圆形\"); }else { //如果是其他类型 System.out.println(\"绘制父类图形\"); } } public static void main(String[]args) { draw(new Shape1()); draw(new Square1()); draw(new Circular1()); }}
多态的意思是多种形态,利用多态可以使程序具有良好的扩展性,并可以对所有类对象进行通用的处理。已经学习过子类对象可以作为父类的对象实例使用,这种将子类对象视为父类对象的做法称为“向上转型”。
7.7 多态
抽象方法:修饰符 abstract 返回参数 方法名(传入参数); 使用abstract关键字定义的类称为抽象类,而使用这个关键字定义的方法称为抽象方法。抽象方法没有方法体,没有意义,除非它被重写,而承载这个抽象方法的抽象类必须被继承,实际上抽象类除了被继承没有任何意义。语法如下: public abstract class Parent{ //修饰类 abstract class 类名 abstract void testAbstract(); //定义抽象方法 如果声明一个抽象方法,就必须将承载这个抽象方法的类定义为抽象类,不能在非抽象中获取抽象方法。只要类中有一个抽象方法,此类就被标记为抽象类。抽象类被继承后需要实现其中所有的抽象方法,也就是保证以相同的方法名称、参数列表和返回值类型创建出非抽象方法,当然也可以是抽象方法。
7.8.1 抽象类
Java中不允许出现多重继承,但使用接口就可以实现多重继承。一个类可以同时实现多个接口,因此可以将所有需要继承的接口放置在implement关键字后并使用逗号隔开。实现多个接口的语法如下:class 类名 implement 接口1,接口2,····,接口n但这可能会在一个类中产生庞大的代码量,因为继承一个接口时需要实现接口中所有的方法。一个接口可以继承另一个接口,语法如下:interface intf1{}interface intf2 extendsintf1{} //接口继承接口
interface Paintable{ //可绘制接口 public void draw(); //绘制抽象方法} class Quadrangle6{ public void doAnything() { System.out.println(\"四边形提供的方法\"); }} //平行四边形类,继承四边形类,并实现了可绘制接口class Parallelogram extends Quadrangle6 implements Paintable{ public void draw() { System.out.println(\"绘制平行四边形\"); }}//正方形类,继承四边形类,并实现了可绘制接口class Square5 extends Quadrangle6 implements Paintable{ public void draw() { System.out.println(\"绘制正方形\"); }} //圆形类,仅实现了可绘制接口class Circular2 implements Paintable{ public void draw() { System.out.println(\"绘制圆形\"); }}public class Demo7 { public static void main(String[]args) { Square5 s = new Square5(); s.draw(); s.doAnything(); Parallelogram p = new Parallelogram(); p.draw(); p.doAnything(); Circular2 c = new Circular2(); c.draw(); }}
接口是抽象类的延伸,可以将它看作纯粹的抽象类,所有的方法都是抽象方法,接口中的所有方法都设有方法体。Java语言每个语言每个类可以实现多个接口。接口使用interface关键字进行定义,语法如下: public interface Paintable{ void draw(); //定义接口方法可省略public abstract关键字} public:修饰符。interface:定义接口关键字Paintable:接口名称
7.8.2 接口
7.8 抽象类与接口
七、继承、多态、抽象类与接口
Java中每个接口或类都来自不同的类包,无论是Java API中的类与接口,都需要隶属于某一个类包,这个类包包含了一些类和接口。如果没有包存在,管理程序中的类名称将是一件麻烦的事情。为了避免类名重叠的问题,则需创建新的类。
8.1.1 类名冲突
一个完整的类名需要包名和类名的组合,每个类都隶属一个类包,只要保证同一类包的类不同名,就可以有效避免同名类冲突的情况。
8.1.2 完整的类路径
创建自定义Math类 package com.mr; //指定包名public class Math { public static void main(String[] args) { System.out.println(\"不是java.lang.Math类,而是com.mr.Math 类\"); }}
(1)在项目的src节点上右击,选择“新建”/“包”命令(英文为New/Package)。(2)弹出“新建Java包”(New java Package)对话框,在“名称”(Name)文本框中输入新建的包名,然后单击“完成”(Finish)按钮。(3)在Eclipse中创建类时,可以在新建立的包上右击,选择“新建”(New)命令,这样新建的类会默认保存在该包中。另外也可以在New Java Class对话框中指定新建类的所在包。 在Java中包含设计应与文件系统结构相对应。没有定义包的类会被归纳在默认包(defaul package)中。在类中定义包名的语法为:**package 包名**
8.1.3 创建包
使用Import导入静态成员 package com.mr;import static java.lang.Math.max; //导入静态成员方法import static java.lang.System.out; //导入静态成员变量public class ImportTest { public static void main(String[] args) { out.println(\"1和4的较大值为:\
1.使用import关键字导入包语法如下:**import com.mr.*; // 导入com.mr包中的所有类。** **import com.mr/Math //导入com.mr包中的Math类**2.使用import导入静态成员语法:import static 静态成员
8.1.4 导入包
8.1 Java类包
成员内部类不止可以在外部类中使用,在其他类中也可以使用。语法如下:外部类 outer = new 外部类();外部类.内部类 inner = outer.new 内部类();注意:(1)如果在外部类和非静态方法之外实例化内部类对象,需要使用“外部类.内部类”的形式指定该对象的类型。(2)内部类对象会依赖于外部类对象,除非已经存在一个外部类对象,否则类中不会出现内部类对象。
使用成员内部类模拟发动机点火 public class Car { //成员变量 private String brand; //构造方法 public Car(String brand) { this.brand = brand; } //成员方法 //成员内部类(发动机类) class Engine{ String model; private String brand; public Engine(String model) { this.model = model; } public void ignite() {//点火方法 System.out.println(\"发动机\"+ this.model +\"点火\"); } } public void start() {//启动汽车方法 System.out.println(\"启动\" + this.brand); } public static void main(String[] args) { Car car = new Car(\"大众郎行\");//创建汽车对象并为汽车品牌赋值 car.start(); //汽车类对象调用启动汽车方法 //创建内部类对象,并为发动机型号赋值 Car.Engine engine = car.new Engine(\"EA211\"); engine.ignite();//发动机类对象调用点火方法 } }
在一个类中使用内部类,可以在内部类中直接存取其所在类的语法如下: class OuterClass{ class InnerClass{ } }
1.成员内部类简介
在内部类中调用外部类对象 public class TheSameName { private int x = 7; private class lnnre{ private int x = 9; public void doit() { int x = 11; x++; this.x++; TheSameName.this.x++; } }}
如果在外部类中定义的成员变量与内部类的成员变量名称相同,可以使用this关键字。
2、使用this关键字获取内部类与外部类的引用
使用匿名内部类创建一个抽象狗类的对象 abstract class Dog{//抽象类 String color; public abstract void call();//抽象方法 public abstract void move();//抽象方法}public class Demo { public static void main(String[] args) { // TODO Auto-generated method stub Dog wenin = new Dog() { //匿名内部类 public void move(){ System.out.println(\"四腿狂奔\"); } public void call() { System.out.println(\"汪汪汪\"); } }; wenin.color = \"灰色\"; wenin.move(); wenin.call(); }}
匿名类是只在创建对象时才会编写类体的一种写法。匿名类的特点是“现写现用”,其语法如下:new 父类/父类口(){ 子类实现的内容 };
3、匿名内部类
使用匿名类时应该遵循以下原则:1、匿名类不能写构造方法。2、匿名类不能定义静态的成员。3、如果匿名类创建的对象没有赋值给任何应用变量,会导致该对象用完一次就会被Java虚拟机销毁。
在一个文件中定义两个类,则其中任何一个类都不在另一个类的内部,如果在类中再定义一个类,则将在类中再定义的那个类称为内部类。
8.2 内部类
八、包和内部类
程序运行的结果报告发生了算术异常ArithmeticException,系统不再执行下去,提前结束。这种情况就是所说的异常
例 9.1 0可以作为除数吗? public class Baulk { //创建类Baulk public static void main(String[] args) { //主方法 int result = 3/0; //定义int型变量并赋值 System.out.println(result); //将变量输出 }}
在程序中,异常可能是由程序员没有预料到的各种情况产生,也可能由超出了程序员可控范围的环境因素产生。异常是一个程序执行期间发生的事件,它中断了正在执行的程序的正常指令流。
9.1 异常概述
结果可以看出,报出的是NumberFormatException异常。提示信息“lili年龄是”已经输出,可知该句代码之前并没有异常,而变量age没有输出,可知程序在执行类型代码转换代码时已经终止。
例9.2 控制台输出“lili年龄是:20L” public class Thunderiing { //创建类 public static void main(String[] args) {//主方法 String str = \"lili\"; //定义字符串 System.out.println(str+\"年龄是:\"); //输出的提示信息 int age = Integer.parseInt(\"20L\"); //数据类型的转换 System.out.println(age); //输出信息 }}
异常抛出后,如果不做·任何处理,程序就会被终止。
9.2.1 抛出异常
从结果可以看出,程序仍然输出最后的提示信息,没有因为异常终止。在上例题中,将可能出现的异常代码用try-catch语句块处理,当try语句块中的语句发生异常时,程序就会跳转到catch语句块执行。执行完catch语句块中的程序代码后,将继续执行catch语句块后的其他代码,而不会执行try语句块中发生异常语句后面的代码。Java的异常处理是结构化的,不会因为一个异常影响整个程序的执行。
例 9.3 捕获例9.2中主方法抛出的异常 public class Take { //创造类 public static void main(String[] args) { try { //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\");//输出信息 }}
1.try-catch语句块
完整的异常处理语句一定要包含finally语句,无论程序有无异常发生,并且无论之前的try-catch语句块是否顺利执行完毕,都会执行finally语句。但是,在一下4中特殊情况下,finally块不会被执行: 1、在finally语句块中发生了异常2、在前面的代码中使用了System.exit()退出程序3、程序所在的线程死亡4、关闭CPU。
2.finally 语句块
Java语言的异常捕获结构由try、catch和finally 3部分组成·。其中,try语句块存放的是可能发生异常的Java语句:catch语句块在try语句块之后,用来激发被捕获的异常;finally语句块是异常处理结构的最后执行部分,无论try语句块中的代码如何退出都会执行finally语句块。语法如下: try{ //程序代码块 } catch(Exceptiontype1 e){ //对Exceptiontype1的处理 } catch(Exceptiontype2 e){ //对Exceptiontype2的处理 } …… finally { //程序代码块 }
9.2.2 捕捉异常
为了保证程序有效地执行,需要抛出的异常进行相应的处理。
9.2 异常的抛出与捕捉
9.3 Java常见的异常类
例9.4 如何创建自定义异常 public class MyException extends Exception{ //创建自定义异常,继承Exception类 public MyException(String ErrorMessage) {//构造方法 super(ErrorMessage);//父类构造方法 }}
在程序中使用自定义异常类,大体可分为以下几个步骤:1、创建自定义异常类2、在方法中通过throw关键字抛出异常对象3、如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理,否则在方法的声明处通过throws关键字指明要抛出给方法调用者异常,继续进行下一步操作。4、在出现异常的方法的调用者中捕获并处理异常。
9.4 自定义异常
如结果所示,使用throws关键字将异常抛给上一级后,如果不想处理异常,可以继续向上抛出,但最终要有能够处理该异常的代码。
例 9.6 指明异常起源于何处 public class Shoot { //创建类 static void pop()throws NegativeArraySizeException{ //定义方法并抛出NegativeArraySizeException异常 int[]arr = new int[-3]; //创建数组 } public static void main(String[] args) { //主方法 try { //try语句处理异常信息 pop(); //调用pop()方法 }catch(NegativeArraySizeException e) { System.out.println(\"pop()方法抛出的异常\"); //输出异常信息 } }}
throws关键字通常被应用在声明方法时,用来指定方法可能抛出的异常。多个异常可使用逗号分隔。
9.5.1 使用throws关键字抛出异常
例9.7创建自定义异常类 public class MyException extends Exception{ //创建自定义异常类 String message; //定义String类型变量 public MyException(String ErrorMessage) { //父类方法 message = ErrorMessage; } public String getMessage() { //覆盖getMessage()方法 return message; }}
throw关键字通常用于方法体中,并且抛出一个异常对象。程序在执行到throw语句时立即终止,它后面的语句都不执行。通过throw抛出异常后,如果想在上一级代码中捕获并处理异常,则需要在抛出异常的方法中使用throws关键字在方法的声明中指明要抛出的异常;如果要捕捉throw抛出的异常,则必须使用try-catch语句块。
9.5.2 使用throw关键字抛出异常
9.5 在方法中抛出异常
九、异常处理
在java语言中,字符串必须包含在一对双引号(\" \")之内。在Java中由双引号(\" \")包围的都是字符串,不能作为其他数据类型来使用。可以通过String str;语句来声明字符串变量。String:指定该变量为字符串类型。str:任意有效的标识符,表示字符串变量的名称。声明的字符串变量必须经过初始化才能使用,否则编译器会报出“变量未被初始化错误”。
10.1.1 声明字符串
在Java语言中,将字符串作为对象来处理,因此可以像创建其他类对象一样来创建字符串对象。创建对象要使用类的构造方法。
10.1.2 创建字符串
10.1 String 类
例 10.1先连接一幅对联的上、下联,再分行输出在控制台上 public class Join { //创造类 public static void main(String[] args) { //主方法 String s1 = new String(\"春风绿千里\"); //声明String对象s1 String s2 = new String(\"马蹄香万家\"); //声明String对象s2 String s =s1 +\"\\"+s2; //将对象s1、\"/n\"和对象s2连接并结果赋值给s System.out.println(s); //将s输出 }}
使用“+”运算符可实现连接多个字符串的功能。“+”运算符可以连接多个String对象并产生一个新的String对象。
10.2.1 连接多个字符串
例 10.2 统计每天的阅读和上机时间 public class Link { //创建类 public static void main(String[] args) { //主方法 int booktime = 4; //声明的int型变量booktime float practice = 2.5f; //声明的float型变量practice //将字符串与整型、浮点型变量相连,并将结果输出 System.out.println(\"我每天花费\"+booktime+\"小时看书;\"+practice+\"小时上机练习\"); }}
字符串也可同其他基本数据类型进行连接。如果将字符串同其他数据类型数据进行连接,会将其他数据类型的数据直接转换成字符串。
10.2.2 连接其他数据类型
10.2 连接字符串
使用Sring类型的length()方法可获取声明的字符串对象的长度。语法:str.length();其中,str为字符串对象
10.3.1 获取字符串长度
该方法用于放回参数字符串s在指定字符串中首次出现的索引位置。当调用String类的indexOf()方法时,会从当前字符串的开始位置搜索s的位置。如果没有检索到字符串s,该方法的返回值是-1。语法:indexOf(substr)str:任意字符串对象。substr:要搜索的字符串。
1、indexOf(String s)
该方法用于指定字符串最后一次出现的索引位置。当调用String类的lastlndexOf()方法时,会从当前字符串的开始位置检索参数字符串str,并将最后一次出现str的索引位置返回。如果没有检索到字符串str,该方法返回-1。语法:str.lastIndexOf(substr)str:任意字符串substr:要搜索的字符串
2、lastlndexOf(String str)
例3:用两种方式判断字符串的长度 public class Text { //创造类 public static void main(String[] args) { //主方法 String str = \"We are students\"; //定义字符串str int size = str.lastIndexOf(\"\"); //将空字符串在str中的索引位置赋值给变量size System.out.println(\"空字符串在字符串str中的索引位置是:\"+size); //将变量size输出 System.out.println(\"字符串str的长度是:\"+str.length()); //将字符串str的长度输出 }}
例4:查看指定索引位置上的字符 public class Ref { //创造类 public static void main(String[] args) { //主方法 String str = \"hello world\"; //定义字符串str char mychar = str.charAt(6); //将字符串str中索引位置6的字符返回 System.out.println(\"字符串str中索引位置是6的字符为:\"+mychar); //输出信息 }}
使用charAt()方法可将指定索引处的字符返回。语法如下:str:任意字符串。index:整型值,用于指定要返回字符的下标。
10.3.3 获取指定索引位置的字符
10.3.2 字符串查找
10.3 获取字符串信息
该方法返回的是从指定的索引位置开始截取直到该字符串结尾的子串。语法如下:str.substring(int beginlndex)其中,beginlndex指定从某一索引处开始截取字符串。
1.substring(int beginlndex)
例5:《将进酒》的作者是哪位诗人? public class Subs { //创建类 public static void main(String[] args) { //主方法 String str = \"《将进酒》:李白(唐)\
通过String类的substring()方法可对字符串进行截取。substring()方法被两种不同的重载形式,来满足不同的需要。这些形式的共同点就是都利用字符串的下标进行截取,且应明确字符串下标是从0开始的。
10.4.1 获取子字符串
例6:去掉字符首、尾的空格 public class Blak { //创建类 public static void main(String[] args) { //主方法 String str = \" java class \"; //定义字符串str System.out.println(\"字符串原来的长度:\"+str.length()); //将str原来的长度输出 System.out.println(\"去掉空格后的长度:\"+str.trim().length()); }}
trim()方法返回字符串的副本,忽略前导空格和尾部空格。语法如下:str.trim其中,str为任何字符串对象。
10.4.2 去除空格
例7:将单词中的字母a替换为字母A public class NewStr { //创建类 public static void main(String[] args) { //主方法 String str = \"address\"; //定义字符串str String newstr = str.replace(\"a\
10.4.3 字符串替换
该方法用于判断当前字符串对象的前缀是否为参数指定的字符串。语法:str.startsWith(String prefix)其中,prefix是指作为前缀的字符串。
1.startsWith()方法
该方法用于判断当前字符串是否为给定的子字符串。语法:str.endsWith(String suffix)其中,suffix是指作为后缀的字符串。
2.endsWith()方法
例8:判断字符串是否以指定的内容开始或结束 public class StartOrEnd { //创造类 public static void main(String[] args) { //主方法 String num1 = \"22045612\"; //定义字符串num1 String num2 = \"21304578\"; //定义字符串num2 boolean b = num1.startsWith(\"22\"); //判断字符串num1是否以‘22’开头 boolean b2 = num2.endsWith(\"78\"); //判断字符串num2是否以‘78‘结束 System.out.println(\"字符串num1是以'22'开始的吗?\"+b); System.out.println(\"字符串num2是以'78'结束的吗?\"+b2); //输出信息 }}
startsWith()方法与endsWith()方法分别用于判断字符串是否以指定的内容开始或结束。这两个方法的返回值都为boolean类型。
10.4.4.判断字符串的开始和结尾
如果两个字符串具有相同的字符和长度,则使用equals()方法进行比较时,返回true。否则返回false。语法:str.equals(String otherstr)其中,str、otherstr是要比较的两个字符串对象。
1.equals()方法
使用equals()方法对字符串进行比较时是否分大小写的,而使用equalsLgnoreCase()方法是在忽略了大小写的情况下比较两个字符串是否相等,返回结果仍为boolean类型。语法如下:str.equalsLgnoreCase(String otherstr)其他,str、otherstr是要比较的两个字符串对象。
2.equalsLgnoreCase()方法
例9:判断“abc”与“ABC”是否相等 public class Opinion { //创造类 public static void main(String[] args) { //主方法 String s1 = new String(\"abc\"); //创建字符串对象s1 String s2 = new String(\"ABC\"); //创建字符串对象s2 boolean b = s1.equals(s2); //使用equals()方法比较s1与s2 boolean b2 = s1.equalsIgnoreCase(s2); //使用equalsIgnoreCase()方法比较s1与s2 System.out.println(s1+ \" equals \" +s2 +\":\"+ b); //输出信息 System.out.println(s1+ \" equalsIgnoreCas \"+s2+\":\"+b2); }}
对字符串对象进行比较不能简单地使用比较运算符“==”,因为比较运算符比较的是两个字符串的地址是否相同。即使两个字符串的内容相同,两个对象的内存地址也是不同的,使用两个字符串的内容相同,两个对象的内存地址也是不同的,使用比较运算符仍然会返回false。此时,布尔型变量b的值为false,因为字符串是对象,tom、jerry是引用。因此,要比较两个字符串内容是否相等,应使用equals()方法和equalsIgnoreCase()方法。A版权协议,转载请附上原文出处链接及本声明。
10.4.5.判断字符串是否相等
例10:判断字母b的位置 public class Wordbook { //创造类 public static void main(String[] args) { //主方法 String str = new String(\"b\"); //用于比较的3个字符串 String str2 = new String(\"a\"); String str3 = new String(\"c\"); System.out.println(str + \" compareTo \" + str2 +\":\"+str.compareTo(str2)); //将str与str2比较的结果输出 System.out.println(str + \" compareTo \" + str3 +\":\"+str.compareTo(str3)); //将str与str3比较的结果输出 }}
compareTo()方法为按字典顺序比较两个字符串,该比较基于字符串中各个字符的Unicode值,按字典顺序将String对象表示的字符序列与参数字符串所表示的字符序列进行比较。如果按字典顺序此String对象位于参数字符串之前,则比较结果为一个负整数;如果按字典顺序此String对象位于参数字符串之后,则比较结果为一个正整数;如果这两个字符串相等,则结果为0。语法如下:str.compareTo(String otherstr)其中,str、otherstr是要比较的两个字符串对象。
10.4.6.按字典顺序比较两个字符串
该方法将字符串中的所有大写字母转换为小写。如果字符串中没有应该被转换的字符,则将原字符串返回;否则将返回一个新的字符串,将原字符串中每个大写字母都转换成小写,字符串长度不变。语法如下:str.toLowerCase()其中,str是要进行转换的字符串。
1.toLowerCase()方法
该方法将字符串中所有的小写字母转换为大写。如果字符串中没有应该被转换的字符,则将原字符串返回;否则返回一个新字符串,将原字符串中每个小写字母都转换为大写,字符串长度不变,语法如下:str.toUpperCase()其中,str是要进行转换的字符串。
2.toUpperCase()方法
例11:字母大小写转换 public class UpAndLower { //创造类 public static void main(String[] args) { //主方法 String str = new String(\"Oh My God\"); //创建字符串str String newstr = str.toLowerCase(); //使用toLowerCase()方法实行小写转换 String newstr2 = str.toUpperCase(); //使用toUpperCase()方法实行大写转换 System.out.println(newstr); //将转换后的结果输出 System.out.println(newstr2); }}
String类的toLowerCase()方法可将字符串中的所有大小字母改写为小写字母,而toUpperCase()方法可将字符串中的所有小写字母改写为大写字母
10.4.7.字母大小写转换
该方法可根据给定的分割符对字符串进行拆分。语法:str.split(String sign)其中,sign 为分割字符串的分割符,也可以使用正则表达式。
1.split(String sign)
例12:按要求分割“192.168.0.1” public class Division { //创造类 public static void main(String[] args) { //主方法 String str = \"192.168.0.1\"; //创建字符串 String[] firstArray = str.split(\"\\\\.\"); //按照“.”进行分割,使用转义字符“\\\\.” String[] secondArray = str.split(\"\\\\.\
使用split()方法可以使字符串按指定的分割字符或字符串进行分割,并将分割后的结果存放在字符串数组中。split()方法提供了以下两种字符串分割形式
10.4.8.字符串分割
10.4 字符串操作
Sting 类的静态format()方法用于创建格式化的字符串。format()方法有两种重载形式
例13:按照格式输出今天的年、月、日 import java.util.Date; //导入java.util.Date类public class Eval { //新建类 public static void main(String[] args) { //主方法 Date date = new Date(); //创建Date对象date String year = String.format(\"%tY\
1.日期格式化
例14:按照格式输出当下的时、分、秒 import java.util.Date; //导入java.util.Date类public class GetDate { //新建类 public static void main(String[] args) { //主方法 Date date = new Date(); //创建Date对象date String hour = String.format(\"%tH\
使用 format()方法不仅可以完成日期的格式化也可以实现时间的格式化。时间的格式化转换符要比日期的格式化转换符更多、更精确,它可以将时间格式化为时、分、秒、毫秒等。
2.时间格式化
例15:按照格式输出当下的年、月、日 import java.util.Date; //导入java.util.Date类public class DateAndTime { //新建类 public static void main(String[] args) { //主方法 Date date = new Date(); //创建Date对象date String time = String.format(\"%tc\
格式化日期与时间组合的转换符定义了各种日期时间组合式,其中常见的如图所示
3.格式化常见的日期时间组合
在应用程序设计中,经常需要显示日期和时间。如果想输出满意的日期和时间格式,一般需要编写大量的代码、经过各种算法才能实现。formatI()方法通过给定的特殊转换符作为参数来实现对日期和时间的格式化。
10.5.1.日期和时间字符串格式化
例16:使用转换符获取表达式的结果 public class General { //新建类 public static void main(String[] args) { //主方法 String str = String.format(\"%d\
常规类型格式化可应用于任何参数类型,可通过表中的转换符来实现。
10.5.2.常规类型格式化
10.5格式化字符串
在正则表达式中,可以使用方括号括起若干个字符来表示一个元字符,该元字特可代表方括号中的任何一个字符。例如,reg =\"[abc]4”,这样字符串 a4、b4、c4 都是和正则表达式匹配的字符串,方括号元字符还可以为其他格式。如:1.[456]: 表 4、5、6之外的任何字符。2.[a-r]: 代表 a~r中的任何一个字母。3.[a-zA-Z]: 可表示任意一个英文字母。4.[a-e[g-z]]: 代表a~e或 g~z中的任何一个字母(并运算)。5.[a-o&&[def]]: 代表字母 d、e、f (交运算)。6.[a-d&&[bc]]: 代表字母a、d (差运算)。
正则表达式通常被用于判断语句中,用来检查某一字符串是否满足某一格式。正则表达式是含有-些具有特殊意义字符的字符串,这些特殊字符称为正则表达式的元字符。例如,“\\d”表示数字0~9中的任何一个,“\\d”就是元字符。正则表达式中的元字符及其意义如表中所示。
在正则表达式中允许使用限定修饰符来限定元字符出现的次数。例如:“A*”代表A可在字符串中出现0次或多次。限定修饰符的用法如表所示。
例:17验证E-mail地址是否“合法” public class Judge { //新建类 public static void main(String[] args) { //主方法 String regex = \
10.6 使用正则表达式
例18:效率比拼 public class Jerque { public static void main(String[] args) { String str=\"\";//创建空字符串 long StarTime=System.currentTimeMillis();//获取字符串执行前的时间 for(int i=0;i<10000;i++) {//循环追加字符串 str=str+i; } long endTime=System.currentTimeMillis();//获取字符串执行后的时间 long time=endTime-StarTime;//计算时间差 System.out.println(\"string消耗的时间:\"+time);//输出 StringBuilder builder=new StringBuilder(\"\");//创建字符串生成器 StarTime=System.currentTimeMillis();//获取字符串执行前的时间 for(int j=0;j<10000;j++) {//循环追加字符串 builder.append(j); } endTime=System.currentTimeMillis();//获取字符串执行后的时间 time=endTime-StarTime;//计算时间差 System.out.println(\"stringBuilder消耗的时间:\"+time);//输出 }}
创建成功的字符串对象,其长度是固定的,内容不能被改变和编译。虽然使用“+”可以达到附加新字符或字符串的目的,但“+”会产生一个新的 String 实例,会在内存中创建新的字符串对象。如重复地对字符串进行修改,将极大地增加系统开销。而JDK 新增了可变的字符序列 StringBuilder类大大提高了频繁增加字符串的效率。
该方法用于向字符串生成器中追加内容。通过该方法的多个重载形式,可实现接受任何类型的数据,如int、boolean、char、String、double 或者另一个字符串生成器等。语法如下:append(comtemt)其中,content表示要追加到字符串生成器中的内容,可以是任何类型的数据或者其他对象。
1.append()方法
10.7.字符串生成器
十、字符串
Java 是一种面向对象语言,Java 中的类把方法与数据连接在一起,构成了自包含式的处理单元。为了提升Java 程序的开发效率,Java 的类包中提供了很多常用类以方便开发人员使用。正所谓,术业有专攻,在常用类中主要包含可以将基本数据类型封装起来的包装类、解决常见数学问题的 Math 类、成随机数的 Random类,以及处理日期时间的相关类等。
Java 是一种面向对象语言,但在 Java 中不能定义基本数据类型的对象,为了能将基本数据类型视为对象进行处理,Java 提出了包装类的概念,它主要是将基本数据类型封装在包装类中,如 int 型的包装类Integer、boolean型的包装类 Boolean等,这样便可以把这些基本数据类型转换为对象进行处理Java中的包装类及其对应的基本数据类型
例1:Integer类的常用方法 public class IntegerDome { public static void main(String[]args) { int num = Integer.parseInt(\"456\");//将字符串转换为int类型 Integer iNum = Integer.valueOf(\"456\");//创建一个Integer对象 System.out.println(\"int数据与Integer对象的比较:\
例2:查看Integer类的常量值 public class GetCon { public static void main(String[] args) { int maxint = Integer.MAX_VALUE;//获取Integer类的常量 int minint = Integer.MIN_VALUE; int intsize = Integer.SIZE; System.out.println(\"int类型可取的最大值:\"+maxint);//将常量值 System.out.println(\"int类型可取的最小值:\"+minint); System.out.println(\"int类型二进制位数是:\"+intsize); }}
Integer 类提供了以下4个常量:1、MAX_VALUE:表示int 类型可取的最大值,即2(31次方)-1。2、MIN_VALUE:表示int 类型可取的最小值,即-2(31次方)。3、SIZE:用来以二进制补码形式表示 int 值的位数。4、TYPE:表示基本类型int的 Class 实例。
ava.lang 包中的 Integer 类、Byte 类、Short 类和 Long 类,分别将基本数据类型 int、byte、short和 long 封装成一个类,由于这些类都是 Number 类的子类,区别就是封装不同的数据类型,其包含方法基本相同,所以本节以Integer 类为例讲解整数包装类。nteger 类在对象中包装了一个基本数据类型 int 的值,该类的对象包含一个 int 类型的字段。此外该类提供了多个方法,能在 int 类型和 String 类型之间互相转换,同时还提供了其他一些处理 int 类时非常有用的常量和方法。Integer 类的常用方法如表:
11.1.1.Integer类
例3:Dounle类的常用方法 public class DoubleDemo { public static void main(String[] args) { Double dNum = Double.valueOf(\"3.14\");//创建一个Double对象 //判断是否为非数字值 System.out.println(\"3.14是否为非数字值:\"+Double.isNaN(dNum.doubleValue())); System.out.println(\"3.14转换为int值为:\"+dNum.intValue());//转换为int类型 //判断大小 System.out.println(\"值为3.14的Double对象与3.14的比较结果:\"+dNum.equals(3.14)); //转换为十六进制 System.out.println(\"3.14的十六进制表示为:\"+Double.toHexString(dNum)); }}
Double类主要提供了以下常量:1、MAX_EXPONENT:返回int 值,表示有限double 变量可能具有的最大指数2、MIN_EXPONENT:返回 int 值,表示标准化 double 变量可能具有的最小指数。3、NEGATIVE_INFINITY:返回 double 值,表示保存 double 类型的负无穷大值的常量。4、POSITIVE_INFINITY:返回double 值,表示保存double 类型的正无穷大值的常量。
Double类和 Float类是对 double、float 基本类型的封装,它们都是Number 类的子类,都是对浮点数进行操作,所以常用方法基本相同,本节将对 Double 类进行讲解。对于 Float 类,可以参考 Double类的相关内容。Double类在对象中包装一个基本类型为 double 的值,每个Double类的对象都包含一个double类的字段。此外,该类还提供多个方法,可以将 double类型转换为 String类型,将 String类型转换为 doubl类型,也提供了其他一些处理 double 类型时有用的常量和方法。Double类的常用方法如表:
11.1.2.Double类
例4:Boolean类的常用方法 public class BooleabDemo { public static void main(String[] args) { Boolean b1 = Boolean.valueOf(\"true\");//创建Boolean对象 Boolean b2 = Boolean.valueOf(\"ok\"); System.out.println(\"b1:\"+b1.booleanValue());//输出 System.out.println(\"b2:\"+b2.booleanValue()); }}
Boolean 提供了以下3个常量:1、TRUE:对应基值 true的 Boolean 对象。2、FALSE:对应基值 false的 Boolean 对象。3、TYPE:基本类型 boolean的 Class 对象。
Boolean 类将基本类型为 boolean 的值包装在一个对象中。一个 Boolean 类型的对象只包含一个类型为boolean 的字段。此外,此类还为 boolean 类型和 String 类型的相互转换提供了许多方法,并提供了处理 boolean 类型时非常有用的其他一些常量和方法。Boolean类的常用方法如表:
11.1.3.Boolean类
例5:Character类的常用方法 public class UpperOrLower { public static void main(String[] args) { Character mychar1 = Character.valueOf('A'); Character mychar2 = Character.valueOf('a'); if(Character.isUpperCase(mychar1)) {//判断是否为大写字母 System.out.println(mychar1 + \"是大写字母\"); //转换为小写并输出 System.out.println(\"转换为小写字母的结果:\" + Character.toLowerCase(mychar1)); } if(Character.isLowerCase(mychar2)) {//判断是否为小写字母 System.out.println(mychar2 + \"是小写字母\"); //转换为大写并输出 System.out.println(\"转换为大写字母的结果:\" + Character.toUpperCase(mychar2)); } }}
Character 类提供了大量表示特定字符的常量,例如:1、CONNECTOR_PUNCTUATION:返回 byte 型值,表示Unicode 规范中的常规类别“Pc”2、UNASSIGNED:返回 byte 型值,表示Unicode 规范中的常规类别“Cn”。3、TITLECASE_LETTER:返回 byte 型值,表示Unicode 规范中的常规类别“Lt”。
11.1.4.Character类
前面介绍了 Java 中的包装类,对于数值型的包装类,它们有一个共同的父类-Number 类,该类是一个抽象类,它是 Byte、Integer、Short、Long、Float 和 Double 类的父类,其子类必须提供将表示的数值转换为 byteint、short、long、float 和 double 的方法。例如,doubleValue()方法返回双精度浮点值,floatValue0方法返回单精度浮点值,这些方法如表:
11.1.5.Number类
11.1 包装类
在 Java 语言中,提供了一个执行数学基本运算的 Math 类,该类包括常用的数学运算方法,如角函数方法、指数函数方法、对数函数方法、平方根函数方法等一些常用数学函数方法。除此之外还提供了一些常用的数学常量,如PI、E等。本节将讲解 Math 类以及其中的一些常用方法。在实际开发中,随机数的使用是很普遍的,所以要掌握生成随机数的操作。在Java 中主要提供了两种生成随机数的方式,分别为调用 Math 类的random0方法生成随机数和调用 Random类生成各种据类型的随机数。在Java中,还提供了大数字的操作类,即javamath.BigInteger类与javamath.BigDecimal类。这两个类用于高精度计算,其中 BigInteger 类是针对大整数的处理类,而 BigDecimal类则是针对大小数的处理类。
在本实例中可以看到,代码的第一行使用import 关键字将javatext.DecimalFormat 这个类导入,这是告知系统下面的代码将使用到 DecimalFormat类。然后定义了两个格式化数字的方法,这两个方法参数都为两个,分别代表数字格式化模板和具体需要格式化的数字。虽然这两个方法都可以实现数字的格式化,但采用的方式有所不同,SimgleFormat()方法是在实例化 DecimalFormat对象时设置数字格式化模板,而UseApplyPattemMethodFormat()方法是在实例化 DecimalFormat 对象后调用applyPattern()方法设置数字格式化模板。最后,在主方法中根据不同形式模板格式化数字。在结果中可以看到以“0特殊字符构成的模板进行格式化时,当数字某位不存在时,将显示0:而以“#”特殊字符构成的模板进行格式化操作时,格式化后的数字位数与数字本身的位数一致。在DecimalFormat类中,除了可通过格式化模板来格式化数字,还可以使用一些特殊方法对数字进行格式化设置。
数字格式化在解决实际问题时应用非常普遍,如表示某超市的商品价格,需要保留两位有效数字数字格式化操作主要针对的是浮点型数据,包括 double 型和 foat 型数据。在 Java 中使用 java.textDecimalFormat格式化数字,本节将着重讲解DecimalFormat类。在Java 中,没有格式化的数据遵循以下原则:1、如果数据绝对值大于0.001 并且小于10000000,使以常规小数形式表示2、如果数据绝对值小于0.001或者大于10000000,使用科学记数法表示。由于上述输出格式不能满足解决实际问题的要求,通常将结果格式化为指定形式后输出。在 Java中,可以使用DecimalFormat类进行格式化操作DecimalForat类是NumberFormat 的一个子类,用于格式化十进制数字。它可以将一些数字格式化为整数、浮点数、百分数等。通过使用该类可以为要输出的数字加上单位或控制数字的精度。一般情况下,可以在实例化 DecimalFormat 对象时传递数字格式,也可以通过 DecimalFormat 类中的applyPatten0方法来实现数字格式化。当格式化数字时,可在 DecimalFormat类中使用一些特殊字符构成一个格式化模板,使数字按照-定的特殊字符规则进行匹配。表中列举了格式化模板中的特殊字符及其所代表的含义。
11.2.1.数字格式化
例7:在java代码中进行三角函数运算 public class TrigonometricFunction { public static void main(String[] args) { System.out.println(\"90度的正弦值:\"+Math.sin(Math.PI/2));//取90°的正弦 System.out.println(\"o度的余弦值:\"+Math.cos(0));//取0°的余弦 System.out.println(\"60度的正切值:\"+Math.tan(Math.PI/3));//取60°的正切 //取2的平方根与2商的反正弦 System.out.println(\"2的平方根与2的商色反正弦值:\"+Math.asin(Math.sqrt(2)/2)); //取2的平方根与2商的反余弦 System.out.println(\"2的平方根与2的商色反余弦值:\"+Math.acos(Math.sqrt(2)/2)); System.out.println(\"1的反正切值:\"+Math.atan(1));//取1的反正切 System.out.println(\"120度的弧度值:\"+Math.toRadians(120.0));//取120°的弧度值 System.out.println(\"Π/2的角度值:\"+Math.toDegrees(Math.PI/2));//取Π/2的角度 }}
1.三角函数方法 Math 类中包含的三角函数方法如下:public static 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):将狐度转换为角度。以上每个方法的参数和返回值都是 double型的。将这些方法的参数的值设置为 double 型是有一定道理的,参数以弧度代替角度来实现,其中1°等于π /180 弧度,所以180°可以使用π弧度来表示。除了可以获取角的正弦、余弦、正切、反正弦、反余弦、反正切,Math 类还提供了角度和弧度相互转换的方法 toRadians()和 toDegrees()。但需要注意的是,角度与弧度的转换通常是不精确的。
例8:在java代码中进行指数函数运算 public class ExponentFunction { public static void main(String[] args) { System.out.println(\"e的平方根:\"+Math.exp(2));//取e的2次方 System.out.println(\"以e为底2的对数值:\"+Math.log(2));//取以为底2的对数 System.out.println(\"以10为底2的对数值:\"+Math.log10(2));//取10为底2的对数 System.out.println(\"4的平方根值:\"+Math.sqrt(4));//取4的平方根 System.out.println(\"8的立方根值:\"+Math.cbrt(8));//取8的立方根 System.out.println(\"2的2次方值:\
例9:各场景下取整函数的运算结果 public class IntFunction { public static void main(String[] args) { System.out.println(\"使用ceil()方法取整:\"+Math.ceil(5.2));//返回一个大于等于参数的整数 System.out.println(\"使用floor()方法取整:\"+Math.floor(2.5));//返回一个小于等于参数的整数 System.out.println(\"使用rint()方法取整:\"+Math.rint(2.7));//返回与参数最接近的整数 System.out.println(\"使用rint()方法取整:\"+Math.rint(2.5));//返回与参数最接近的整数 //将参数加上0.5后返回最接近的整数 System.out.println(\"使用found()方法取整:\"+Math.round(3.4f)); //将参数加上0.5后返回最接近的整数,并将结果强制转换为长整型 System.out.println(\"使用round()方法取整:\"+Math.round(2.5)); }}
3.取整函数方法在具体的问题中,取整操作使用也很普遍,所以 Java 在 Math 类中添加了数字取整方法。Math类中主要包括以下几种取整方法:public static double ceil(double a): 返回大于等于参数的最小整数。public static double floor(double a):返回小于等于参数的最大整数。public static double rint(double a): 返回与参数最接近的整数,如果存在两个同样接近的整数V则结果取偶数。public staticintround(float a):将参数加上0.5后返回与参数最近的整数。public static longround(double a): 将参数加上0.5 后返与参数最近的整数,然后强制转换为长整型。
例10:取最大值、最小值、绝对值的方法 public class AnyFunction { public static void main(String[] args) { System.out.println(\"4和8较大者:\
Math 类提供了众多数学函数方法,主要包括三角函数方法,指数函数方法,取整函数方法,取最大值、最小值,以及平均值函数方法。这些方法都被定义为 static 形式,所以在程序中应用比较简便可以使用如下形式调用:Math.数学方法在Math 类中,除函数方法外还存在一些常用数学常量,如 PI、E等。这些数学常量作为Math类的成员变量出现,调用起来也很简单。可以使用如下形式调用:Math.PIMath.EMath 类中的常用数学运算方法较多,大致可以将其分为四大类别,分别为三角函数方法,指数函数方法,取整函数方法,以及取最大值、最小值和绝对值函数方法。
11.2.2.Math类
例11:获取不同取值范围、不同类型的随机数 import java.util.Random; public class RandomDemo { public static void main(String[] args) { Random r = new Random();//实例化一个Random类 //随机产生一个整数 System.out.println(\"随机产生一个整数:\"+r.nextInt()); //随机产生一个大于等于0且小于10的整数 System.out.println(\"随机产生一个大于0小于10的整数:\"+r.nextInt(10)); //随机产生一个布尔型的值 System.out.println(\"随机产生一个布尔型的值:\"+r.nextBoolean()); //随机产生一个双精度浮点型的值 System.out.println(\"随机产生一个双精度浮点型的值:\"+r.nextDouble()); //随机产生一个单精度浮点型的值 System.out.println(\"随机产生一个单精度浮点型的值:\"+r.nextFloat()); //随机产生一个概略密度为高斯分布的双精度浮点型的值 System.out.println(\"随机产生一个概略密度为高斯分布的双精度浮点型的值:\"+r.nextGaussian()); }}
在Random 类中,提供了获取各种数据类型随机数的方法,下面列举几个常用的方法:public intnextInt():返回一个随机整数。public int nextInt(int n): 返回大于等于0且小于n的随机整数。public long nextLong0: 返回一个随机长整型值。public boolean nextBoolean0: 返回一个随机布尔型值。public float nextFloat0:返回一个随机单精度浮点型值。日 public doublenextDouble0:返回一个随机双精度浮点型值。public double nextGaussian():返回一个概率密度为高斯分布的双精度浮点型值。
Random 类是JDK 中的随机数生成器类,可以通过实例化一个 Radom 对象创建一个随机数生器,语法如下:Random r = new Random();以这种方式实例化对象时,Java 编译器将以系统当前时间作为随机数生成器的种子。因为每时刻的时间不可能相同,所以产生的随机数不同。但是如果运行速度太快,也会产生两个运行结果相同的随机数。用户也可以在实例化 Random 类对象时,设置随机数生成器的种子。语法如下:Random r = new Random(seedValue);r: Random类对象。seedValue:随机数生成器的种子。
11.2.3.Random类
例12:使用BigInteger类进行数学运算 import java.math.BigInteger;public class BiglntegerDemo { public static void main(String[] args) { BigInteger b1 = new BigInteger(\"987654321987654321\");//第1个大数字 BigInteger b2 = new BigInteger(\"123456789123456789\");//第2个大数字 System.out.println(\"加法操作:\"+b1.add(b2));//加法运算 System.out.println(\"减法操作:\"+b1.subtract(b2));//减法运算 System.out.println(\"乘法操作:\"+b1.multiply(b2));//乘法运算 System.out.println(\"除法操作:\"+b1.divide(b2));//除法运算 System.out.println(\"取商:\"+b1.divideAndRemainder(b2)[0]);//取商运算 System.out.println(\"取余数:\"+b1.divideAndRemainder(b2)[1]);//取余运算 System.out.println(\"做2次方操作:\"+b1.pow(2));//2次方运算 System.out.println(\"取相反数操作:\"+b1.negate());//相反数运算 }}
一旦创建了对象实例,就可以调用 Bielncger 类中的一些方法进行运算操作,包括基本的数学这算和位运算以及一些取相反数、取绝对值等操作。列举了 BigInteger 类中常用的几种运算方法:public BigInteger add(BigInteger val): 做加法运算。public BigInteger subtract(BigInteger val): 做减法运算。public BigInteger multiply(BigInteger val): 做乘法运算。public BigInteger divide(BigInteger val): 做除法运算。public BigInteger remainder(BigInteger val): 做取余操作。public BigInteger divideAndRemainder(Biplntegcr val): 用数组返回余数和商,结果数组中第一个值为商,第二个值为余数。public BigInteger pow(intexponent): 进行取参数的exponent 次方操作。public BigInteger negate0: 取相反数。public BigInteger shifLeft(intn):将数字左移n位,如果n为负数,做右移操作。public BigInteger shiftRight(intn):将数字右移n位,如果n为负数,做左移操作。public BigInteger and(BigInteger val): 做与操作。口 public BigInteger or(BigInteger val):做或操作。publicintcompareTo(BigInteger val):做数字比较操作。public boolean equals(Object x):当参数x是BigInteger类型的数字并且数值与对象实例的数值相等时,返回true。public BigInteger min(BigInteger val):返回较小的数值。public BigInteger max(BigIntegerval):返回较大的数值。
Biginteger 类的数字范围较 Integer 类的数字范围要大得多。前文介绍过 Integer 类是 int 的包装类int 的最大值为 23-1,如果要计算更大的数字,使用 nteer 类就无法实现了,所以 Java 中提供]BigInteger 类来处理更大的数字。Biginteger 类支持任意精度的整数,也就是说,在运算中 BigIntege类可以准确地表示任何大小的整数值而不会丢失信息。在 BigInteger 类中封装了多种操作,除了基本的加、减、乘、除操作,还提供了绝对值、相反数最大公约数以及判断是否为质数等操作。使用 BigInteger类,可以实例化一个 BigInteger 对象,并自动调用相应的构造函数。BigInteger类具有很多构造函数,但最直接的一种方式是参数以字符串形式代表要处理的数字。例如,将2转换为 BigInteger 类型,可以使用以下语句进行初始化操作:BigIntege twoInstance = new BigIntege(“2”);
11.2.4.BigInteger类
BigDecimal类和BigInteger类都能实现大数字的运算,不同的是 BigDecimal类加入了小数的概念般的foat 型和 double 型数据只可以用来做科学计算或工程计算,但由于在商业计算中要求数字精度比较高,所以要用到 BigDecimal类。BigDecimal类支持任何精度的定点数,可以用它来精确计算货币值。在BigDecimal类中,常用的两个构造方法如表:
BigDecimal类型的数字可以用来做超大的浮点数的运算,如加、减、乘、除等,但是在所有的运算中除法是最复杂的,因为在除不尽的情况下商小数点后的末位的处理是需要考虑的。BigDecimal类实现的加、减、乘、除的方法 下表:
在上述方法中,BigDecimal类中divide()方法有多种设置,用于返回商小数点后的末位的处理,这些模式的名称与含义下表
例13:使用BigDecimal类进行数学运算 import java.math.BigDecimal;import java.math.RoundingMode;public class BigDecimalDemo { public static void main(String[] args) { BigDecimal b1 = new BigDecimal(\"0.00987654321987654321\");//第1个大小数 BigDecimal b2 = new BigDecimal(\"0.00123456789123456789\");//第2个大小数 System.out.println(\"两个数字相加结果:\"+b1.add(b2));//加法运算 System.out.println(\"两个数字相减结果:\"+b1.subtract(b2));//减法运算 System.out.println(\"两个数字相乘结果:\"+b1.multiply(b2));//乘法运算 //除法运算,商小数点后保留9位,并将结果进行四舍五入操作 System.out.println(\
11.2.5.BigDecimal类
11.2 数字处理
System 类提供了标准输入、标准输出和错误输出流,也就是说,System 类提供了3 个静态对象:in、out 和 err。本书中的代码多次使用了这些对象,最常见的就是 out 对象。在控制台输出字符事,验出的方法有两种:1.不会自动换行的print()方法print()方法语法如下:System.out.print(“Hello”);此方法输出“Hello”文字,输出完毕后,光标会停留在“Hello”文字末尾,不会自动换行。2.可以自动换行的println()方法printin0方法在print后面加上了“In”后缀(就是 line的简写),语法如下:System.out.println(“书籍是人类进步的阶梯!”);此方法输出“书籍是人类进步的阶梯!”后会自动换行。光标停留在下一行的开头。Print()方法和println()方法输出的对比效果下表:
11.3.1.控制台输出字符
例14:查看执行一万次字符串拼接所消耗的时间 public class SystemTimeDmeo { public static void main(String[] args) { long start = System.currentTimeMillis();//程序开始记录时间 String str = null;//创建null字符串 for(int i = 0;i < 10000;i++) {//循环一万次 str += i;//字符串与循环变量拼接 } long end = System.currentTimeMillis();//记录循环结束时间 System.out.println(\"循环用时:\"+(end - start)+\"毫秒\"); }}
System.currentTimeMillis()方法可以获取1970年1月1日零点至今的毫秒数。虽然 Date日期也有类似的方法,但代码会比System 类多,所以System.currentTimeMillis()方法是为获取当前毫秒梦最常用的方法。因为该方法的返回值精确到毫秒,所以可以利用该方法来记录程序的运行时间。
11.3.2.计时
System类是JDK中提供的系统类,该类是用final修饰的,所以不允许被继承。System类提供了很多系统层面的操作方法,并且这些方法全部但是静态的。
11.3 System类
使用Scanner类扫描控制台的代码如下:Scanner sc = new Scanner(System.in);
与C语言不同,Java从控制台中读出用户输入的值,用到的不是一行可以直接使用的代码,而是由一个叫Scanner的类来实现的。Scanner英文直译就是扫描仪,它的用途就和现实生活中的扫描仪一样,可以把数字化信息流为人类可识别的文字。控制台输出内容用到了System.out就表示向控制台输出,System.in就表示从控制台输入,让Scanner扫描System.in就可以获取用户输入的值了。使用Scanner类首先要引入该类,其语法如下:import java.util.Scanner;Scanner类提供了下表中的几种常用的方法,通过这些方法可以获取控制台输入的不同类型的值。
11.4 .Scanner类
Date类用于表示日期时间,使用该类表示时间需要使用其构造方法创建对象,其构造方法及其说明如下图:
使用Date类的第2种构造方法创建一个Date类的对象,代码如下:long timeMillis = System.currentTimeMillis();Date date = new Date(TimeMillis);上述代码中的System类的currentTimeMillis()方法主要用于获取当前系统时间距标准时间的毫秒数。另外,这里需要注意的是,创建Date类对象时使用的是long型整数,而不是double型,这主要是因为double类型可能会损失精度。Date类的常用方法及其说明,图如下:
例16:获取当前的日期和时间 import java.util.Date;public class DateDemo { public static void main(String[] args) { Date date = new Date(); //创建现在的日期 long value = date.getTime(); //获取毫秒数 System.out.println(\"日期:\"+date);//输出 System.out.println(\"到现在所经历的毫秒数为:\"+value); }}
11.5.1.Date类
由于DateFormat类是一个抽象类,不能用new 创建实例对象。因此,除了使用getXXXInstance()方法创建其对象,还可以使用其子类,如 SimpleDateFormat 类,该类是一个以与语言环境相关的方式来格式化和分析日期的具体类,它允许进行格式化(日期一文本)、分析(文本一日期)和规范化。SimpleDateFormat类提供了19个格式化字符,可以让开发者随意编写日期格式,这19个格式化字符下表:
通常表中的字符出现的数量会影响数字的格式。例如,yyyy 表示4 位年份,这样输入会显示202l:yy 表示两位,这样输入就会显示为 21; 只有一个y的话,会按照 yyyy 显示:如果超过4个一些常用的日期时间格式如表中所示。y,如yyyyyy,会在4位年份左侧补0,结果为02021。一些常用的日期时间格式下表:
DateFormat 类提供的Date parse(String source)方法可以将字符串转为其字面日期对应的 Date对象,整个过程相当于日期格式化的逆操作。
例17:以中文形式打印当前的日期和时间 import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Date;public class DateFormatDemo { public static void main(String[] args) { DateFormat df = new SimpleDateFormat(\"yyy年MM月dd日EEEEE HH时mm分ss秒\"); System.out.print(\"各位观众大家好,现在是\"); System.out.print(df.format(new Date())); System.out.println(\
11.5.2.日期时间格式化
例18:具体离中华人民共和国成立100周年差多少天 import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;public class CountDown { public static void main(String[] args) { System.out.println(\"——————————————中华人民共和国成立100周年倒计时——————————————\"); Date date = new Date();//当前时间 //创建SimpleDateFormat对象,指定目标格式 SimpleDateFormat simpleDateFormat = new SimpleDateFormat(\"yyy年MM月dd日\"); //创建format方法,格式化时间,转换为指定格式 String today = simpleDateFormat.format(date); System.out.println(\"今天是\
最后对 Calendar 类的使用做出几点总结:c.set(Calendar.DAY OF_MONTHO)获取的是上个月的最后一天,所以调用前需要将月份往后加一个月。Calenda.rMONTH 的第一个月是使用0记录的,所以在获得月份数字后要加1。年和日是从1开始记录的,不需要加 1。Calendar.DAY_OF_WEEK 的第一天是周日,周一是第二天,周六是最后一天。
打开JavaAPI 文档可以看到 iava.utilDate 类提供的大部分方法都已经过时了,因为 Date类在设计之初没有考虑到国际化,而且很多方法也不能满足用户需求,比如需要获取指定时间的年月日时分和信息,或者想要对日期时间进行加减运算等复杂的操作,Date 类已经不能胜任,因此JDK 提供了新的时间处理类–Calendar日历类。Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR等日历字段之间的转换提供了一些方法,并为操作日历字段(如获得下星期的日期)提供了一些方法。另外,该类还为实现包范围外的具体日历系统提供了其他字段和方法,这些字段和方法被定义为 protected。Calendar 提供了一个类方法 getInstance(),以获得此类型的一个通用的对象。Calendar 类的getInstance()方法返回一个 Calendar 对象,其日历字段已由当前日期和时间初始化,其使用方法如下:Calendar rightNow = Calendar.getInstance();
11.5. 日期时间类
例19:让java程序执行Windows系统的help命令 import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;public class RuntimeExecDemo { public static void main(String[] args) { Runtime r= Runtime.getRuntime();//获取本地 Runtime 对象 try { Process p = r.exec(\"help\"); InputStream is = p.getInputStream();//获取本地 Runtime 对象 //将字节输入流转换为字符输入流 BufferedReader br = new BufferedReader(new InputStreamReader(is)); String str = null;//创建 null 字符串 while ((str = br.readLine()) != null) {//如果字符流中可以获取非空内容 System.out.println(str);//打印获取的内容 } }catch(IOException e) { e.printStackTrace(); } }}
例20:监控虚拟机内存使用情况 public class MemoryDemo { public static void main(String[] args) { Runtime r= Runtime.getRuntime();//获取本地 Runtime对象 Integer ints[] = new Integer[10000];//创建长度为10000的整型数组 long before = r.freeMemory();//获取当前空闲内存数 System.out.println(\"赋值前空闲内存字节数:\
Runtime 类可以通过 freeMemory()方法查看当前Java 虚拟机可用内存的剩余量。如果程序能够实时监控内存剩余量,就可以尽量控制程序对内存的占用,从而避免出现“内存溢出”的情况。同样,也可以用来对测试程序性能,检验程序算法是否导致内存紧张。
11.6.2.查看内存
11.6 Runtime类
十一、常用类库
java.util包中提供了一些集合类,这些集合类又被称为容器。集合类与数组的不同之处:数组的长度是固定的,集合的长度是固定的,集合的长度是可变的;数组用来存放基本类型的数据,集合用来存放对象的引用。
常用集合类的继承关系 如右图所示
12.1 集合类概述
通常遍历集合,都是迭代器来实现。Collection接口中的Iterator()方法可返回在此Collection进行迭代的迭代器。右边实例是遍历集合的例题
Collection接口是层次结构中的根接口,构成Collection的单位称为元素。Collection接口通常不能直接使用,但该接口提供了添加元素、删除元素、管理数据的方法。由于List接口与Set接口都继承了Collection接口,因此这些方法掉Lish集合与Set集合是通用的。Collection接口的常用方法如右图所示。
12.2 Collection接口
List接口继承了 Collection接口,因此包含 Collection接口中的所有方法。此外,List接口还定义了以下两个非常重要的方法: get(int index):获取指定索引位置对对对元素 set(int index,Object obj):将集合中指定索引位置的对象修改为指定的对象。
12.3.1 List接口
右边代码举例说明List集合的常用方法
List接口的常用实现类有ArrayList类与LinkedList类,简述如下: ArrayList类实现了可变的数组,允许保存所有元素,包括null,并可以根据索引位置对集合进行快速的随机访问。缺点是向指定的索引位置插入对象或删除对象的速度较慢。 LinkedList类采用链表结构保存对象。这种结构的优点是便于向集合中插入和删除对象。需要向集合插入、删除对象时,使用LinkedList类实现的List集合的效率较高;但对于随机访问集合的对象,使用LinkedList类实现List集合的效率较低。 List<E>list = new ArrayList<>(); List<E>list2 = new LinkedList<>();
12.3.2 List接口的实现类
List集合包括List接口以及List接口的所有实现类。List集合中的元素允许重复,各元素的顺序就是对象插入的顺序。类似Java数组,用户可通过使用索引来访问集合中的元素。
12.3 List集合
Set集合中的对象不按特定的方式排序,只是简单地把对象加入集合中,但Set集合中不能包含重复对象。Set集合由Set接口和Set接口的实现类组成。Set接口继承了Collection接口,因此包含Cpllection接口的所有方法。
Set接口常用的实现类有HashSet类与TreeSet类简述: HashSet类实现Set接口,由哈希表支持,它不保证Set集合的迭代顺序,特别是它不保证该顺序恒久不变。此类允许使用null元素。 TressSet类不仅实现了Set接口,还实现了java.util.SortedSet接口,因此TreeSet类实现的Set集合在遍历集合时按照自然顺序递增排序,也可以按照指定比较器递增排序,既可以通过比较器对用TreeSet类实现的Set集合中的对象进行排序。
TreeSet类新增的方法如右图所示
实例 :使用TreeSet类自然排序
12.4 Set集合
Map 集合没有继承 Collection 接口,其提供的是 key 到 value 的映射。Map 集合中不能包含相同的kcy,每个 key 只能映射一个value。key 还决定了存储对象在映射中的储位置,但不是由ky 对象身决定的,而是通过一种“散列技术”进行处理,产生一个散列码的整数值。散列码通常用作一个信移量,该偏移量对应分配给映射的内存区域的起始位置,从而确定存储对象在映射中的存储位置。Ma集合包括 Map 接口以及 Map 接口的所有实现类。
Map接口提供了将key映射到值的对象。一个映射不能包含重复的key,每一个key最多只能映射到一个值。除集合的常用的方法外,其他特殊方法如右图
12.5.1 Map接口
例题
HashMap类是基于哈希表的Map接口的实现,此实现提供所有可选的映射操作,并允许使用null值和null值,但必须保证键的唯一性。HashMap类通过哈希表对其内部的映射关系进行快速查找。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。TreeMap类不仅实现了Map接口,还实现了java.utli.SortedMap接口,因此集合中的映射关系具有一定的顺序。但在添加、删除和定位映射关系,TreeMap类比HashMap类性能稍差。由于TreeMap类实现的Map集合中的映射关系是根据键对象按照一定的顺序排列的,因此不允许键对象是null。
12.5.2 Map接口的实现类
12.5 Map集合
十二、集合类
例题.分别创建四季接口常量和枚举
13.1.1 使用枚举类型设置常量
打印四季枚举中的所有枚举值
1.values()方法枚举类型实例包含一个values()方法,该方法可以将枚举类型成员以数组的形式返回
使用字符串创建一个季节的枚举值,并判断季节的位置
2. valueOf()方法与compareTo()方法枚举类型中静态方法valueOf()方法可以将普通字符串转换为枚举类型,而compareTo()方法用于比较两个枚举类型对象定义时的顺序。
输出每一个季节的索引位置
3.ordinal()方法枚举类型中的ordinal()方法用于获取某个枚举对象的位置索引值
enum 枚举类型名称{ Constants_A(\"我是枚举成员A\
无论是有无参构造方法还是有参构造方法,修饰权限都为private.
为四季枚举创建构造方法,记录每一个季节的特性
4.枚举类型中的构造方法枚举类型定义的构造方法语法如右所示
子主题
类型安全。紧凑有效的数据定义。可以和程序其他部分完美交互。运行效率高。
13.1.3 使用枚举类型的优势
13.1 枚举类型
public class Test { private Object b; //定义object类型成员变量 public Object getB() { //设置相应的getXXX()方法 return b; } public void setB(Object b) { //设置相应的setXXX()方法 this.b = b; } public static void main(String[] args) { Test t = new Test(); t.setB(Boolean.valueOf(true)); //向上转型操作 System.out.println(t.getB()); t.setB(Float.valueOf(\"12.3\")); //向下转型操作 Float f = (Float)t.getB(); System.out.println(f); }}
在介绍泛型之前,先来看一个例子,在项目中创建Test类,在该类中使基本类型向上转型为object类型
13.2.1 回顾向上转型与向下转型
Object类为最上层的父类,为了提前预防发生异常,Java提供了泛型机制其语法:类名<T> 其中,T是泛型的名称,代表某一种类型。如果不指定具体类型,T则采用Object类型。
例题.创建带泛型的图书类
13.2.2 定义泛型类
1.定义泛型类时声明多个类型
定义泛型类时也可以声明数组类型。
例题. 定义泛型数组
2.定义泛型类时声明数组类型
例题. 使用泛型约束集合的元素类型
3.集合类声明容器的元素
13.2.3 泛型的常规用法
默认可以使用任何类型来实例化一个泛型类对象,但Java中也对泛型类实例的类型做了限制,语法如下:class 类名称<T extends anyClass>其中anyClass指某个接口或类。使用泛型限制后半泛型类的类型必须实现或者继承anyClass这个接口或类,无论anyclass是接口还是类,在进行泛型限制时都必须使用extends关键字
例题 限制泛型的类型必须是List的子类
1.限制泛型可用类型
2.使用类型通配符
3.继承泛型类与接口
泛型的高级用法包括限制泛型可用类型和使用类型通配符等。
13.2.4 泛型的高级用法
总结一下泛型的使用方法。1泛型类型参数只能是类类型,不可以是简单类型,比如A< int>这种泛型定义就是错误的。2.泛型的类型个数可以是多个3.可以使用extends关键字限制泛型的类型4.可以使用通配符限制泛型的类型
13.2.5 泛型总结
泛型实质上就是使程序员定义安全的类型。在没有出现泛型之前,Java也提供了对object类型的引用“任意化” 操作,这种“任意化”操作就是对object类型引用进行向下转型及向下转型操作,但某些强制类型转换的错误也许不会被编译器捕捉,而在运行后出现异常,可见强制类型转换存在安全隐患,所以在此提供了泛型机制。
13.2 泛型
十三、枚举类型与泛型
1.lambda表达式可以用非常少的代码实现抽象方法。2.lambda表达式不能独立执行,因此必须实现函数式接口,并且会返回一个函数式接口的对象。3.lambdab表达式的语法非常特殊
语法格式:()-> 结果表达式 参数-> 结果表达式(参数1,参数2...,参数n)-> 结果表达式第1行实现无参方法,单独写一对圆括号表示方法无参数,操作符右侧的结果表达式表示方法的返回值。第2行实现只有一个参数的方法,参数可以写在圆括号里,或者不写圆括号。第3行实现多参数的方法,所有参数按顺序写在圆括号里,且圆括号不可以省略。
lambda表达式也可以实现复杂方法,将操作符右侧的结果表达式换成代码块即可语法格式如下:()->{代码块)参数->(代码块}(参数1,参数2,..参数n)->{代码块)第1行实现无参方法,方法体是操作符右侧代码块。第2行实现只有一个参数的方法,方法体是操作符右侧代码块。第3行实现多参数的方法,方法体是操作符右侧代码块。
lambda表达式的功能归纳总结,语法理解为:() -> {代码块}这个方法 按照 这样的代码来实现简单总结:操作符左侧的方法参数,操作符右侧是方法体
14.1.1 lambda表达式简介
开发者可以常见自定义的函数式接口例如:interface MyInterface{ void method();}如果接口中包含一个以上的抽象方法,则不符合函数式接口的规范,这样的接口不能用Iambda表达式创建匿名对象
1. 函数式接口
很多函数式接口的抽象方法是无参数的,如线程接口Runnable接口只有一个ryn()方法,这样的无参抽象方法在lambda表达式中使用\"()\"表示
使用lambda表达式实现打招呼接口
2.Iambda表达式实现无参数抽象方法
如果抽象方法中只有一个参数,lambda表达式则可以省略圆括号
例题. 使用lambda表达式做加法计算
3.lambda表达式实现有参抽象方法
lambda表达式会自动判断返回值类型是否符合抽象方法的定义
4.lambda表达式使用代码块
14.1.2 lambda表达式实现函数式接口
局部变量在lambda表达式中默认被定义为final(静态)的,也就是说,lambda表达式只能调用局部变量,却不能改变其值。
结果可以看到,更改局部变量的相关代码被标注编译有误。
1.lambda表达式无法更改局部变量
类成员变量是在lambda表达式中不是被final修饰的,所以lambda表达式可以改变其值
例题. 使用lambda表达式修改类成员变量
从上述代码结果中可以看出以下几点:lambda 表达式可以调用并修改类成员变量的值lambda表达式只是描述了抽象方法是如何实现的,在抽象方法没有被调用前,lambda表达式中的代码并没有被执行,所以运行抽象方法之前类成员变量的值不会发生变化只要抽象方法被调用,就会执行lambda 表达式中的代码,类成员变量的值就会被修改。
2.lambda表达式可以更改类成员变量
这些外部的变量有些可以被更改,有些则不能。例如,lambda表达式无法更改局部变量的值,但是却可以更改外部类的成员变量(也可以叫做类属性)的值他。
14.1.3 Iambda表达式调用外部变量
lambda 表达式中并有抛出异常的语法,这是因为lambda表达式会默认抛出抽象方法原有的异常,当此方法被调用时则要进行异常处理。
例题 防沉迷接口
14.1.4 Iambda表达式与异常处理
14.1 lambda表达式
语法:类名::静态方法名 新的操作符“::”,中间无空格,左边表示方法所属的类名,右边是方法名,语法中方法名是没有括号的。
例题. 使用lambda表达式引用静态方法
从代码结果可以看出,接口的方法得出的结果正是按照add()方法中的逻辑计算出来的
14.2.1 引用静态方法
引用成员方法的语法:对象名::成员方法名操作符左侧必须是一个对象名,而不是类名。
例题. 使用lambda表达式引用成员方法
结果可以看出,抽象方法的结果是按照类成员方法的逻辑计算出来的
14.2.2 引用成员方法
语法:类名::new注意:new关键字之后没有圆括号,也没有参数的定义
例题. 使用lambda表达式引用无参构造方法
结果可以看出,如果接口方法没有参数,调用的就是无参的构造方法
1.引用无参构造方法
引用有参构造方法的语法与引用无参构造方法一样。区别就是函数式接口的抽象方法是有参数的
例题. 使用lambda表达式引用有参数的构造方法
结果可以看出,无参构造方法没有被调用,接口方法使用的就是有参数的构造方法
2.引用有参构造方法
语法;类名[]::new
3.引用数组构造方法
Iambda表达式有3种引用构造方法的语法,分别是引用无参数构造方法、引用有参构造方法和引用数构造方法
14.2.3 引用构造方法
这个接口有以下两个泛型:T:被操作的类型,可以理解为方法参数类型。R:操作结果类型,可以理解为方法的返回类型。Function 接口是函数式接口,所以只有一个抽象方法,但是Function 接口还提供方法以方便开发者对函数逻辑进行更深层的处理。
14.2.4 Fuction接口
14.2 方法的引用
流处理的接口都定义在java.uil.stream 包下。BaseStream接口是最基础的接口,但最常用的是BaseStream 接口的一个子接口——Stream 接口,基本上绝大多数的流处理都是在Stream 接口上实现的。Stream 接口是泛型接口,所以流中操作的元素可以是任何类的对象。Collection 接口新增两个可以获取流对象的方法。第一个方法最常用,可以获取集合的顺序流,方法如下:Stream stream();第二个方法可以获取集合的并行流,方法如下:Stream parallelstream();因为所有集合类都是Collection 接口的子类,如ArrayList类、HashSet类等,所以这些类都可以进行流处理。例如:List list = new ArrayList(); //创建集合Streamcinteger> s = list.stream();//获取集合流对象
14.3.1 Stream接口简介
Optional 类是用final 修饰的,所以不能有子类。Optional类是带有泛型的类,所以该类可以保存任何对象的值。从Optional类的声明代码中就可以看出这些特性,JDK中的部分代码如下public final class Optional<T>{private final T value;} //省略其他代码Optional 类中有一个叫作value的成员属性,这个属性就是用来保存具体值的。value 是用泛型了修饰的,并且还用了final 修饰,这表示一个 Optional 对象只能保存一个值。
14.3.2 Optional类
Collectors类为收集类,该类实现了java.util.Collector接口
14.3.3 Collectors类
filterO方法是Stream 接口提供的过滤方法。该方法可以将lambda表达式作为参数,然后按照lambda表达式的逻辑过滤流中的元素。过滤出想要的流元素后,还需使用Stream 提供的collectO方法按照指定方法重新封装。
1. filter()方法
该方法可以去除流中的重复元素,效果与SQL语句中的DISTINCT关键字一样
2. distinct()方法
Iimit()方法是Stream接口提供的方法,该方法可以获取流中前N个元素
3. Iimit()方法
skip()方法是Stream接口提供的方法,该方法可以忽略流中的前N个元素
4. skip方法
数据过滤就是在杂乱的数据中筛选出需要的数据,类似 SQL 语句中的WHERE 关键字,给出一定的条件,将符合条件的数据过滤并展示出来。
14.3.4 数据过滤
数据的映射和过滤概念不同:过滤是在流中找到符合条件的元素,映射是在流中获得具体的数据。Stream 接口提供了mapO方法用来实现数据映射,mapO方法会按照参数中的函数逻辑获取新的流对象,新的流对象中元素类型可能与旧流对象元素类型不相同。
14.3.5数据映射
该方法会判断流中的元素是否全部符合某一条件,返回结果是boolean值
1.allMatch()方法
该方法会判断流中的元素是否有符合某一条件
2.anyMatch方法()方法
该方法会判断流中的所有元素是否都不符合某一条件
3.noneMatch()方法
这个方法会返回符合条件的第一个元素
4.findFirst()方法
14.3.6 数据查找
不仅可以筛选出特殊元素,还可以对元素的属性进行统计计算
1.数据统计
将流中元素按照指定的条件分开保存数据分组有一级分组和多级分组一级分组:将所有数据按照一个条件进行分类
2.数据分组
14.3.7 数据收集
流处理有点类似数据库的 SQL 语句,可以执行非常复杂的过滤、映射、查找和收集功能,并且代码量很少。唯一的缺点是代码可读性不高。
14.3 流处理
十四、lambda表达式与流处理
流是一组有序的数据序列,可分为输入流和输出流两种。程序从指向源的输入流中读取源中数据,源可以是文件、网络、压缩包或者其他数据源。
输出流的指向是数据要到达的目的地,输出流的目标可以是文件、网络、压缩包、控制台和其他数据输出目标。
InputStream类是字节输入流的抽象类,他是所有字节输入流的父类。InputStream类的具体层次结构如下:
1、read()方法:从输入流中读取数据的下一字节。返回0~255的int字节值。如果因为已经到达流末尾而没有可用的字节,则返回值为-1.2、mark(int readlimit)方法: 在输入流的当前位置放置一个标记,readlimit参数告知此输入流再标记位置失效之前允许读取的字节数。3、reset()方法:将输入指针返回到当前所做的标记处。4、skip(long n)方法:跳过输入流上的n个字节并返回实际跳过的字节数。5、markSupported()方法:如果当前流支持mark()/reset()操作就返回turn。6、close方法:关闭此输入流并释放与该流关联的所有系统资源。并不是所有的 InputStream类的子类都支持 InputStream 类中定义的所有方法、如skip0、mark0、Tset0等方法只对某些子类有用。Java 中的字符是Unicode 编码,是双字节的。InputStream 类是用来处理字节的,并不适合处理字符文本。Java为字符文本的输入专门提供了一套单独的类,即Reader 类,但Reader 类并不是InputStear类的替换者,只是在处理字符串时简化了编程。Reader 类是字符输入流的抽象类,所有字符输入流的实现都是它的子类。Reader 类的具体层次结构如下图所示。
15.1.1 输入流
OutputStream类是字节输出流的抽象类,此抽象类是表示输出字节流的所有类的超类
15.1.2 输出流
15.1 输入/输出流
该构造方法通过将给定的路径名字符串转换为抽象路径名来创建一个新File实例。语法如下:new File(String pathname) 其中,pathname代表路径名称(包含文件名)。例如File file = new File(\"d:/1.txt\");
1. File(String pathname)
在D盘创建文本文件
可以使用File类创建一个文件对象。通常使用以下3种构造方法来创建文件对象。
15.2.1 文件的创建与删除
例题. 读取文本文件的名称、长度和隐藏属性
15.2.2 获取文件信息
File 类是 java.io包中唯一代表磁盘文件本身的类。File类定义了一些与平台无关的方法来操作文件,可以通过调用 File类中的方法,实现创建、删除、重命名文件等操作。File类的对象主要用来获取文件本身的一些信息,如文件所在的目录、文件的长度、文件读写权限等。数据流可以将数据写入文件中,文件也是数据流最常用的数据媒体
15.2 File类
FilelnputStream 类与FileOutputStream类都用来操作磁盘文件。如果用户的文件读取需求比较简单,则可以使用FileInputStream 类,该类继承自 InputStream 类。FileOutputStream 类与FilelmputStream类对应,提供了基本的文件写入能力。FileOutputStream类是OutputStream类的子类。
FileinputStream 类常用的构造方法如下: FileinputStream(String name)。 FilelnputStream(File file)。第一个构造方法使用给定的文件名 name 创建一个FilelnputStream对象,第二个构造方法使用File对象创建FilelnputStream 对象。第一个构造方法比较简单,但第二个构造方法允许在把文件连接输入流之前对文件做进一步分析。FileOutputStream 类有与FilelnputStream类相同的参数构造方法,创建一个FileOutputStream 对象时,可以指定不存在的文件名,但此文件不能是一个已被其他程序打开的文件。下面的实例就是使用FileinputStream 类与FileOutputStream类实现文件的读取与写入功能的。
向文本文件中写入内容,再读取出来
15.3.1 FilelnputStream 与 Fileouisieam 类
例题. 使用字符流读写文本文件
15.3.2 FileReader 和 FileWriter类
程序运行期间,大部分数据都在内存中进行操作,当程序结束或关闭时,这些数据将消失。如果需要将数据永久保存,可使用文件输入/输出流与指定的文件建立连接,将需要的数据永久保存到文件中。本节将讲解文件输入/输出流。
15.3 文件输入/输出流
15.4.1 BufferedInputStream 与BufferedOutputStream类
BufferedReader 类与BufferedWriter 类分别继承Reader 类与Writer 类。这两个类同样具有内部缓存机制,并能够以行为单位进行输入/输出。根据BufferedReader类的特点,可以总结出如下图所示的带缓存的字符数据读取文件的过程。
例题. 使用缓冲流读写文本文件
15.4.2 BufferedReader 与 BufferedWriter类
缓存是I/O的一种性能优化。缓存流为I/O流增加了内存缓存区,使得在流上执行skip()、mar()和reset()方法都成为可能
15.4 带缓存的输入/输出流
数据输入/输出流(DataInputStream 类与DataOutputStream类)允许应用程序以与机器无关的方式从底层输入流中读取基不)ava数据类型。也就是说,当读取一不数据时,不必再关心这个数值应当是哪种字节。DatalnputStream 类与DataOutputStream类的构造方法如下。
1. DatalnputStream(InputStream in):使用指定的基础 InputStream 对象创建一个DataInputStream对象。2. DataOutputStream(OutputStream out):创建一个新的数据输出流,将数据写入指定基础输出流。DataOutputStream 类提供了将字符串、double 数据、int 数据、boolean数据写入文件的方法。其中,将字符串写入文件的方法有 3种,分别是writeBytes(String s)、writeChars(String s)、writeUTF(String s)。由于Java 中的字符是Unicode 编码,是双字节的,writeBytes( )方法只是将字符串中的每一个字符的低字节内容写入目标设备中;而writeChars( )方法将字符串中的每一个字符的两个字节的内容都写到目标设备中;writeUTF( )方法将字符串按照UTF 编码后的字节长度写入目标设备,然后才是每一个字节的UTF 编码。DatalnputStream 类只提供了一个readUTF( )方法返回字符串。这是因为要在一个连续的字节流读取一个字符串,如果没有特殊的标记作为一个字符串的结尾,并且不知道这个字符串的长度,就无法知道读取到什么位置才是这个字符串的结束。DataOutputStream 类中只有writeUTF( )方法向目标设备中写入字符串的长度,所以也能准确地读回写入字符串。
15.5 数据输入/输出流
十五、I/O(输入、输出)
Constructor 类中提供的常用方法
例如,判断对象 constructor 所代表的构造方法是否被 private 修饰,以及以字符串形式获得该构造方法的所有修饰符的典型代码如下:int modifiers = constructor.getModifiers(); boolean isEmbellishByPrivate = Modifier.isPrivate(modifiers); String embelishment = Modifier.toString(modifiers);
Modifier 类中的常用解析方法
例题 . 反射一个类的所有构造方法在com.mr包下创建一个Demo1类,在该类声明一个Strin型成员变量和3个int型成员变量,并提供三个构造方法
编写测试类ConstructorDemo1,在该类中通过反射访问com.mr.Demo1类中的所有构造方法,并将该构造方法是否允许带有可变数量的参数、入口参数类型和可能抛出的异常类型信息输出到控制台。
16.1.1 访问构造方法
在通过下列一组方法访问成员变量时,将返回Field 类型的对象或数组。每个Field对象代表一个成员变量,利用Ficld 对象可以操纵相应的成员变量:getFields()getField(String name)getDeclaredFields()getDeclaredField(String name)如果是访问指定的成员变量,可以通过该成员变量的名称来访问。例如,访问一个名称为birthday的成员变量,访问方法如下:object. getDeclaredField(\"birthday\");
Field 类中提供的常用方法
例题. 反射一个类的所有成员变量在com.mr包下创建一个Demo2类
16.1.2 访问成员变量
Method 类中提供的常用方法
例题. 反射一个类的所有成员方法
16.1.3 访问成员方法
众所周知,所有Java 类均继承了 Object 类,在Object 类中定义了一个 getClassO方法,该方法返回一个类型为Class 的对象。例如下面的代码:JTextField textField = new JTextFieldO); //创建 JTextField 对象Class textFieldC = textField.getClass(); //获取Class对象利用Class 类的对象 textFieldC,可以访问用来返回该对象的textField对象的描述信息。可以访问的主要描述信息如下表所示。
16.1 反射
内置注解:@Override :限定重写父类方法作用范围成员方法@SuppressWarnings :抑制编译器警告作用范围类、成员属性、成员方法@Deprecated :标示已过时作用范围类、成员属性、成员方法在定义Annotation 类型时,也需要用到用来定义接口的interface 关键字,但需要在interface关键字前加一个“@”符号,即定义Annotation 类型的关键字为@interface,这个关键字的隐含意思是继承了 java.lang.annotation.Annotation 接口。例如,下面的代码就定义了一个 Annotation 类型:public @interface NoMemberAnnotation{}上面定义的Annotation类型@NoMemberAnnotation未包含任何成员,这样的Annotation类型被称为marker annotation。下面的代码定义了一个只包含一个成员的Annotation类型:public @interface OneMemberAnnotation {String value();}String:成员类型。可用的成员类型有 String、Class、primitive、enumerated和annotation,以及所列类型的数组value:成员名称。如果在所定义的Annotation 类型中只包含一个成员,通常将成员名称命名为value下面的代码定义了一个包含多个成员的Annotation类型:public @interface MoreMemberAnnotation {String describe();Class type();}在为Annotation 类型定义成员时,也可以为成员设置默认值。例如,下面的代码在定义Annotation型时就为成员设置了默认值:public @interface DefaultValueAnnotationString describe() default \"<默认值>\";Class type() default void.class;}
在定义Annotation 类型时,还可以通过 Annotation 类型@Target 来设置Annotation类型适用的程序元素种类。如果未设置@Target,则表示适用于所有程序元素。枚举类 ElementType 中的枚举常量用来设置@Targer
通过 Amotaion 类型@Retenion 可以设置Amnotation 的有效范围。枚举类RetentioPolicy 中的枚举常量用来设置@Rctention, 如表所示。如果未设置@Retention,Annotation 的有效范围为枚举常量CLASS 表示的范围
16.2.1 定义Annotation类型
16.2.2 访问Annotation 信息
该功能可用于类、构造方法、成员变量、成员方法、参数等的声明中。该功能并不会影响程序的运行,但是会对编译器警告等辅助工具产生影响
16.2 Annotation注解功能
十六、反射与注释
1.搜索栏内输入cmd,以管理员身份运行。
2.登入MySQL
3.创建数据库和表
一、数据库内操作
二、java内部操作
//注册驱动 获取链接 public void getConnection() throws SQLException{ //第一步:注册驱动 DriverManager.registerDriver(new Driver());
1.注册驱动
coonection = DriverManager.getConnection(\"jdbc:mysql://localhost:3306/school_java\
2.获取链接
PreparedStatement prepareStatedment = coonection.prepareStatement(\
3.获取statment对象
ResultSet resultSet=prepareStatedment.executeQuery();
4. 执行SQL语句返回结果集
while(resultSet.next()) { System.out.print(resultSet.getInt(\"id\")); System.out.println(resultSet.getString(\"name\")); }
5.遍历结果集
```javaresultSet.close(); prepareStatedment.close(); ```//关闭连接private void close() throws SQLException{ coonection.close(); }
6.关闭连接释放资源
7.整体代码
三、连接数据库
十七、数据库操作
String包的层次结构和继承关系如下
常用的Swing组件如下表:
18.1 Swing概述
JFrame 类的常用构造方法包括以下两种形式:public JFrame():创建一个初始不可见、没有标题的窗体。public JFrame(String title):创建一个不可见、具有标题的窗体。例如,创建一个不可见、具有标题的窗体,关键代码如下:JFrame jf = new JFrame(“登录系统”);Container container = jf.getContentPane();在创建窗体后,先调用getContentPaneO方法将窗体转换为容器,再调用addO方法或者removeO方法向容器中添加组件或者删除容器中的组件。向容器中添加按钮,关键代码如下:JButton okBtn= new JButton(“确定“)container.add(okBtn);删除容器中的按钮,关键代码如下:container.remove(okBtn);
Java 语言提供了多种窗体的关闭方式,常用的有4种,如表所示。
例题.. 第一个窗体程序
18.2.1 JFrame 窗体
例题.. 在窗体中弹出对话框
18.2.2 JDialog 对话框
例题. 弹出对话框并1询问
1.自定义对话框参数说明如下:parentComponent:指明对话框在哪个窗体上显示,如果传入具体的窗体对象,对话框会在该窗体居中位置显示,如果传入null则在屏幕中间弹出对话框。message:提示的信息。title:对话框的标题。optionType:指定可用于对话框的选项的整数:DEFAULT_OPTION、YES NO_OPTION.YES NO_CANCEL_OPTION 或 OK_CANCEL_OPTION。messageType:指定消息种类的整数,主要用于确定来自可插入外观的图标ERRORMESSAGE、INFORMATION_MESSAGE、WARNING_MESSAGE、QUESTION_MESSAGE 或 PLAIN_MESSAGE。icon:在对话框中显示的图标。options:指示用户可能选择的对象组成的数组。如果对象是组件,则可以正确呈现,非String对象使用其toString方法呈现;如果此参数为null,则由外观确定选项。initialValue:表示对话框的默认选择的对象,只有在使用options 时才有意义,可以为null。
例题.. 弹出对话框并询问
例题.. 弹出对话框,让用户输入自己的姓名
例题..弹出警告对话框
JOptionPane提供了4种创建对话框的方法
18.2.3 JOptionPane 小型对话框
18.2 Swing常用窗体
特点:硬性指定组件在容器中的位置和大小,组件的位置通过绝对坐标的方式来指定。
例题..使用绝对布局定位按钮的大小和位置
18.3.1 null绝对布局
例题.. 使用流布局排序按钮
18.3.2 FlowLayout 流布局管理器
例题.. 使用边界布局排列按钮
18.3.3 BorderLayout 边界布局管理器
例题. 使用网格布局排列按钮
18.3.4 GridLayout 网络布局管理器
18.3 常用布局管理器
18.4.1 JPanel 面板
JScrollPane 滚动面板 不能使用布局管理器,且只能容纳一个组件
例题.. 为窗体添加上下滚动条
18.4.2 JScrollPane 滚动面板
18.4 常用面板
18.5.1 JLable 标签
在Swing 程序设计中,图标经常被添加到标签、按钮等组件,使用javax.swing.Imagelcon类可以依据现有的图片创建图标。ImageIcon类实现了Icon接口,它有多个构造方法,常用的如下:public ImagelconO:创建一个 Imagelcon 对象,创建 ImageIcon对象后,使用其调用 setImage(Image image)方法设置图片。public Imagelcon(Image image):依据现有的图片创建图标。public ImageIcon(URL url):依据现有图片的路径创建图标。
18.5.2 图标的使用
18.5 文字标签组件与图标
Button 类的常用方法及其说明
18.6.1 JButton 按钮
18.6.2 JRadinButton 单选按钮
18.6.3 JCheckBox 复选框
18.6 按钮组件
JComboBox 类的常用构造方法如下:public JComboBox(ComboBoxModeldataModel):创建一个 JComboBox对象,下拉列表中的列表项使用ComboBoxModel中的列表项,ComboBoxModel 是一个用于组合框的数据模型。public JComboBox(Object[]arrayData):创建一个包含指定数组中的元素的JComboBox对象。public JComboBox(Vector vector):创建一个包含指定 Vector 对象中的元素的JComboBox 对象.Voetor对象中的元素可以通过整数索引进行访问,而且 Vector 对象中的元素可以根据需求被添加或者移除。
JComboBox类的常用方法及其说明
18.7.1 JComboBox 下拉列表框
JList类的常用构造方法如下:public void JList():创建一个空的JList对象。public void JList(Object[] listData):创建一个显示指定数组中的元素的JList对象。public void JList(Vector listData):创建一个显示指定 Vector 中的元素的JList对象。public void JList(ListModel dataModel):创建一个显示指定的非 null模型的元素的JList对象。
18.7.2 JList 列表框
18.7 列表组件
18.8.1 JTextField文本框
18.8.2 JPasswordField 密码框
18.8.3 JTextArea 文本域
18.8 文本组件
18.9.1 创建表格
DefaultTableModel类提供的常用构造方法
18.9.2 DefaultTableModel 表格数据模型
18.9.3 维护表格模型
18.9 表格组件
动作事件( ActionEvent)监听器是Swing中比较常用的事件监听器,很多组件的动作都会使用它监听,如按钮被单击等。下表描述了动作事件监听器的接口与事件源等。
18.10.1 ActionEvent动作事件
当向文本框中输入内容时,将发生键盘事件。KeyEvent类负责捕获键盘事件,可以通过为组件添加实现了KeyListener接口的监听器类来处理相应的键盘事件。KeyListener接口共有三个抽象方法,分别在发生击键事件(按下并释放键)、按键被按下(手指按下键但不松开)和按键被释放(手指从按下的键松开)时被触发,具体如下: public interface KeyListener extends EventListener { public void keyTyped(KeyEvent e); //发生击键事件时被触发 public void keyPressed(KeyEvent e); //按键被按下时被触发 public void keyReleased(KeyEvent e); //按键被释放时被触发}
18.10.2 KeyEvent键盘事件
MouseEvent鼠标事件所有组件都能发生鼠标事件,MouseEvent类负责捕获鼠标事件,可以通过为组件添加实现MouseListener接口的监听器来处理相应的鼠标事件。MouseListener接口共有5个抽象方法,分别在光标移入或者移出组件、鼠标按键被按下或释放和发生单击事件时被触发。所谓单击事件,就是按键被按下并释放。需要注意的是,如果按键是在移出组件之后才被释放,则不会触发单击事件。MouseListener接口的具体定义如下: public interface MouseListener extends EventListener { public void mouseEntered(MouseEvent e); //光标移入组件时被触发 public void mousePressed(MouseEvent e); //鼠标按键被按下时被触发 public void mouseReleased(MouseEvent e); //鼠标按键被释放时被触发 public void mouseClicked(MouseEvent e); //发生单击事件时被触发 public void mouseExited(MouseEvent e); //光标移出组件时被触发}
在上述每个抽象方法中,均传入了MouseEvent类的对象。MouseEvent类中比较常用的方法
当 需要判断触发此次事件的按键时,可以通过表18.12中的静态常量判断由getButton()方法返回的int型值代表的键。
18.10.3 MouseEvent 鼠标事件
18.10 事件监听器
十八、Swing程序设计
Grapics 类是所有图形上下文的抽象基类,它允许应用程序在组件以及闭屏图像上进行绘制。Graphics 类封装了Java 支持的基本绘图操作所需的状态信息,主要包括颜色、字体、画笔、文本、图像等。 Graphics 类提供了绘图常用的方法,利用这些方法可以实现直线、钜形、多边形、椭面、圆弧等形状和文本、图片的绘制操作。另外,在执行这些操作之前,还可以使用相应的方法设置给图的颜色和字体等状态属性。
19.1.1 Graphics 类
使用Graphics 类可以完成简单的图形绘制任务,但是它所实现的功能非常有限,如无法改变线条的粗细、不能对图片使用旋转和模糊等过滤效果。 Graphics2D 类继承Graphics 类,实现了功能更加强大的绘图操作的集合。由子Graphies2D类是Graphics 类的扩展,也是推荐使用的Java 绘图类。
19.1.2 Graphics2D类
19.1 绘图类
Java 可以分别使用Graphics 类和 Graphics2D 类绘制图形,Graphics类使用不同的方法实现不同图形的给制。例如,drawLine0方法可以绘制直线,drawRect()方法用于绘制矩形,drawOval0方法用于绘制椭圓形等。
Graphics2D类是在继承Graphics 类的基础上编写的,它包含了Graphics类的绘图方法并添加了更强的功能,在创建绘图类时推荐使用该类。Graphics2D类可以分别使用不同的类来表示不同的形状,Line2D类、Rectangle2D类等。 要绘制指定形状的图形,需要先创建并初始化该图形类的对象,且这些图形类必须是Shape接口药实现类;然后使用Graphics2D类的draw0方法绘制该图形对象,或者使用610方法填充该图形对象。看法格式如下:draw(Shape form)或fill(Shape form)其中,form 是指实现Shape 接口的对象。java.awt.geom 包中提供了如下常用的图形类,这些图形类都实现了Shape 接口:Arc2D类CubicCurve2D类Ellipse2D类Line2D类Point2D类QuadCurve2D类Rectangle2D类RoundRectangle2D类
19.2 绘制图形
绘图类可以使用setColor()方法设置当前颜色。语法如下:setColor(Color color)其中,参数color是Color对象,代表一个颜色值,如红色、黄色或默认的黑色
19.3.1 设置颜色
19.3.2 设置画笔
19.3 绘图颜色与画笔属性
19.4.1 设置字体
19.4.2 显式文字
19.4 绘制文本
19.5 显示图片
19.6.1 放大与缩小
19.6.2 图片翻转
图像旋转需要调用Graphics2D类的rotateO方法,该方法将根据指定的弧度旋转图像。语法如下:rotate(double theta)其中,theta 是指旋转的弧度
19.6.3 图像旋转
19.6.4 图像倾斜
19.6 图像处理
十九、Java绘图
在Java中,并发机制非常重要,程序员可以在程序中执行多个线程,每个线程完成一个功能,并与其他线程并发执行,这种机制被称为多线程。但是,并不是所有编程语言都支持多线程。 线程的特点:1.进程是资源分配的最小单位,线程是最小的执行单位2.一个进程可以有多个线程3.线程共享进程资源 Windows操作系统是多任务操作系统,它以进程为单位。一个进程是一个包含有自身地址的程序,每个独立执行的程序都称为进程。也就是说每个正在执行的程序都是一个进程。系统可以分配给每一个进程有一段有限的使用CPU的时间(也可以称为CPU时间片),CPU在这段时间中执行某个进程,然后下一个时间片又跳至另一个进程中去执行。由于CPU转换比较快,所以使得每个进程好像是同时执行一样。
20.1 线程简介
Thread 类时 java.lang 包中的一个类,从类中实例化的对象代表线程,程序员启动一个新线程需要建立 Thread 实例。Thread类中常用的两个构造方法如下:public Thread():创建一个新的线程对象。public Thread(String threadName):创建一个名称为threadName的线程对象。继承Thread类创建一个新的线程的语法如下:public class ThreadTest extends Threadf {}完成线程真正功能的代码放在类的run0方法中,当一个类继承Thread类后,就可以在该类中覆盖run0方法,将实现该线程功能的代码写入runO方法中,然后调用 Thread类中的start0方法执行线程也就是调用run0方法。Thread 对象需要一个任务来执行,任务是指线程在启动时执行的工作,该工作的功能代码被写在run0方法中。run0方法必须使用以下语法格式:public void run() {}当执行一个线程程序时,就自动产生一个线程,主方法正是在这个线程上运行的。当不再启动其他线程时,该程序就为单线程程序,如本章以前的程序都是单线程程序。主方法线程启动由Java 虚拟机负责,程序员负责启动自己的线程。代码如下:public static void main(String[] args){ new ThreadTest().start();}
20.2.1 继承Thread类
20.2.2 实现Runnable 接口
20.2 创建线程
虽然多线程看起来像同时执行,但事实上在同一时间点上只有一个线程被执行,只是线程之间切换较快,所以才会使人产生线程是同时进行的假象。在Windows操作系统中,系统会为每个线程分配一小段CPU时间片,一旦 CPU时间片结束就会将当前线程换为下一个线程,即使该线程没有结束。要使线程处于就绪状态,有以下几种方法:调用sleep()方法调用wait()方法。等待输入/输出完成。当线程处于就绪状态后,可以用以下几种方法使线程再次进入运行状态:线程的休眠时间结束输入\\输出结束
20.3 线程的生命周期
一种能控制线程行为的方法是调用sleep()方法,sleep()方法需要一个参数用于指定该线程休眠的时间,该时间以毫秒为单位。sleep()方法语法如下try{ Thread.sleep(2000);}catch(InterruptedException e){ e.printStackTrace(();}
20.4.1 线程的休眠
当某一个线程使用join()方法加入另外一个线程时,另一个线程会等待该线程执行完毕后再继续执行
20.4.2线程的加入
以往有的时候会使用stop()方法停止线程,但当前版本的JDK早己废除了stop()方法,不建议使用stop()方法来停止一个线程的运行。现在提倡在run()方法中使用无限循环的形式,然后使用一个布尔型标记控制循环的停止。 如果线程是因为使用了slcep()或wait()方法进入了就绪状态,可以使用Thread 类中 interrupt()方法使线程离开run()方法,同时结束线程,但程序会抛出InterruptedException异常,用户可以在处理该异常时完成线程的中断业务处理,如终止while循环。 下面的实例演示了某个线程使用interrupted()方法,同时程序抛出了InterruptedException异常,在异常处理时结束了while 循环。在项目中,经常在这里执行关闭数据库连接和关闭Socket连接等操作。
20.4.3线程的中断
Thread 类中提供了一种礼让方法,使用yield()方法表示,它只是给当前正处于运行状态的线程个提醒,告知它可以将资源礼让给其他线程,但这仅是一种暗示,没有任何一种机制保证当前线程会将资源礼让。yield()方法使具有同样优先级的线程有进入可执行状态的机会,在当前线程放弃执行权时会再度回到就绪状体。对于支持多任务的操作系统来说,不需要调用yield()方法,因为操作系统会为线程自动分配CPU时间片来执行。
20.4.4 线程的礼让
20.4 操作线程的方法
每个线程都具有各自的优先级,线程的优先级可以表明在程序中该线程的重要性,如果有很多线程处于就绪状态,系统会根据优先级来决定首先使哪个线程进入运行状态。但这并不意味着低优先级的线程得不到运行,而只是它运行的概率比较小,如垃圾回收线程的优先级就较低。 Thread类中包含的成员变量代表了线程的某些优先级,如Thread.MIN_PRIORITY(常数1)、Thread.MAXPRIORITY(常数10)、Thread.NORM PRIORITY(常数5)。其中,每个线程的优先级都在 Thread.MIN_PRIORITY~Thread.MAX_PRIORITY,在默认情况下其优先级都是Thread.NORM PRIORITY。每个新产生的线程都继承了父线程的优先级。 在多任务操作系统中,每个线程都会得到一小段CPU时间片运行,在时间结束时,将轮换另一个线程进入运行状态,这时系统会选择与当前线程优先级相同的线程予以运行。系统始终选择就绪状态下优先级较高的线程进入运行状态。处于各个优先级状态下的线程的运行顺序
,优先级为5的线程A首先得到CPU时间片;当该时间结束后,轮换到与线程A相同优先级的线程B;当线程 B的运行时间结束后,会继续轮换到线程A,直到线程A与线程B都执行完毕,才会轮换到线程C;当线程C结束后,才会轮换到线程D。线程的优先级可以使用 setPriority()方法调整,如果使用该方法设置的优先级不在1~10,将产生IllegalArgumentException异常。
20.5 线程的优先级
例如,在项目中创建ThreadSafeTest类,该类实现了Rummable接口,在未考虑到线程安全问题的基础上,模拟火车站售票系统的功能的代码如上:
20.6.1 线程安全
1.同步块Java 中提供了同步机制,可以有效地防止资源冲突。同步机制使用synchronized关键字,使用该关键字包含的代码块称为同步块,也称为临界区,语法如下:synchronized(Object) {}通常将共享资源的操作放置在 synchronized 定义的区域内,这样当其他线程获取到这个锁时,就必须等待锁被释放后才可以进入该区域。Object 为任意一个对象,每个对象都存在一个标志位,并具有两个值,分别为0和1。一个线程运行到同步块时首先检查该对象的标志位,如果为0状态,表明此同步块内存在其他线程,这时当期线程处于就绪状态,直到处于同步块中的线程执行完同步块中的代码后,这时该对象的标识位设置为1,当期线程才能开始执行同步块中的代码,并将Object对象的标识位设置为0,以防止其他线程执行同步块中的代码。
修改例题20.7的代码,将共享资源操作放置在用同一个同步方法中
2.同步方法同步方法就是在方法前面用synchronized关键字修饰的方法,其语法如下:synchronized void f(){}当某个对象调用了同步方法时,该对象上的其他同步方法必须等待该同步方法执行完毕后才能被执行。必须将每个能访问共享资源的方法修饰为synchronized,否则就会出错。
20.6.2 线程同步机制
20.6 线程同步
二十、多线程
为了实现两台计算机的通信,必须用一个网络线路连接两台计算机。如下图所示
21.1.1 局域网与互联网
1.IP协议IP是Internet Protocol的简称,是一种网络协议。Internet 网络采用的协议是TCP/IP协议,其全称是Transmission Control Protocol/Internet Protocol。Internet 依靠TCP/IP协议,在全球范围内实现了不同硬件结构、不同操作系统、不同网络系统间的互联。在Internet 网络上存在着数以亿计的主机,每台主机都用网络为其分配的 Internet 地址代表自己,这个地址就是I地址。到目前为止,I地址用4个字节,也就是32位的二进制数来表示,称为IPv4。为了便于使用,通常取用每个字节的十进制数,并且每个字节之间用圆点隔开来表示I地址,如192.168.1.1。现在人们正在试验使用16个字节来表示I地址,这就是IPv6,但IPv6还没有投入使用。TCP/IP 模式是一种层次结构,共分为4层,分别为应用层、传输层、互联网层和网络层。各层实现特定的功能,提供特定的服务和访问接口,并具有相对的独立性,
2. TCP与UDP协议在TCPAIP 协议栈中,有两个高级协议是网络应用程序编写者应该了解的,即传输控制协议(Transmission Control Protocol,TCP)与用户数据报协议(User Datagram Protocol, UDP)。TCP 协议是一种以固接连线为基础的协议,它提供两台计算机间可靠的数据传送。TCP可以保证数据从一端送至连接的另一端时,能够确实送达,而且抵达的数据的排列顺序和送出时的顺序相同。因此,TCP协议适合可靠性要求比较高的场合。就像拨打电话,必须先拨号给对方,等两端确定连接后,相互才能听到对方说话,也知道对方回应的是什么。HTTP、FTP 和Telnet 等都需要使用可靠的通信频道。例如,HTTP从某个URL读取数据时,如果收到的数据顺序与发送时不相同,可能就会出现一个混乱的HTML文件或是一些无效的信息。UDP是无连接通信协议,不保证数据的可靠传输,但能够向若干个目标发送数据,或接收来自若干个源的数据。UDP以独立发送数据包的方式进行。这种方式就像邮递员送信给收信人,可以寄出很多信给同一个人,且每一封信都是相对独立的,各封信送达的顺序并不重要,收信人接收信件的顺序也不能保证与寄出信件的顺序相同。UDP 协议适合于一些对数据准确性要求不高,但对传输速度和时效性要求非常高的网站,如网络聊天室、在线影片等。这是由于TCP协议在认证上存在额外耗费,可能使传输速度减慢,而UDP协议即使有一小部分数据包遗失或传送顺序有所不同,也不会严重危害该项通信。
21.1.2 网络协议
通常,0~1023的端口数用于一些知名的网络服务和应用,用户的普通网络应用程序应该使用1024以上的端口数,以避免端口号与另一个应用或系统服务所用端口冲突。网络程序中的套接字(Socket)用于将应用程序与端口连接起来。套接字是一个假想的连接装置,就像插座一样可连接电器与电线,
21.1.3 端口与套接字
21.1 网络程序设计基础
ava.net包中的InetAddress类是与IP地址相关的类,利用该类可以获取IP地址、主机地址等信息。
21.2.1 InetAddress 类
21.2.2 ServerSocket 类
编写客户端程序,将用户在文本框中输入的信息发送至服务端,并将文本框中输入的信息显示再客户端的文本域中。
21.2.3 TCP网络程序设计
TCP网络程序设计是指利用Socket 类编写通信程序。利用TCP协议进行通信的两个应用程序是有主次之分的,一个称为服务器程序,另一个称为客户机程序,两者的功能和编写方法大不一样。
21.2 TCP程序
21.3.1DatagramPacket类
21.3.2 DatagramSocker 类
21.3.3 UDP网络程序设计
21.3 UDP程序
二十一、网络通信
java从入门到精通
收藏
0 条评论
下一页