Java从入门到精通
2022-06-08 14:42:33 31 举报
AI智能生成
666
作者其他创作
大纲/内容
第一章 初识Java
1.1 Java 简介
认识了什么是java
java是于1995年由Sun公司推出的一种极富创造力的面向对象的程序设计语言。
1.2 搭建Java环境
(1)级系统设置
(2)新建环境变量
(3)分别输入变量名“JAVA-HOME”和变量值(JDK的安装路径)
(4)在环境变量中双击Path变量进行修改,在原变量值的最前端添加“.;%JAVA-HOME%\BIN;%JAVA-HOME%\jre\bin;”变量值。完成环境变量的设置。
(5)在“环境变量”对话框中新建一个SLASSPATH变量,变量值为“.;%JAVA-HOME%\lib\tools.jar”。
(6)JDK安装成功后必须确认环境配置是否正确,以管理员身份运行cmd控制台,输入javac命令然后回车,显示如下则表示JDK换进搭建成功。
1.3 第一个Java程序
java应用程序可以是使用任何一个文本编辑器来编写程序的源代码,然后使用JDK搭配的工具进行编译和运行。
步骤:
(1)新建全英文路径
(2)新建hello java.java文件夹
(3)使用记事本打开方式
(4)敲入代码
(5)先编译再运行(javac hello java.java对代码进行编译)然后回车运行程序。
1.4 Eclipse开发环境
Eclipse是由IBM公司开发的集成开发工具。
下载并安装Eclipse
创建新java项目
1.5 Eclipse的使用
非常好用
1.6 程序调试
程序中设置断点以检测程序是否出现错误
1、在一行代码的第一列右击鼠标,
2、点击“Togoint Breakpoint”,
使用断点该程序暂停后,可以通过Debug(调试)试图工具栏上的按钮执行相应的调试操作。
第二章 Java语言基础
2.1代码注释与编码规范
单行注释
“//”为单行注释标记,从“//”符号开始直到换行为止的所有内容都被作为注释而被编译器忽略,不会被运行。(注释内容不可换行)
语法如下:
多行注释
“/**/”为多行注释标记,符号“/**/”之间的所有内容均为注释内容。(注释内容可以换行)
语法如下:
文档注释
“/** */”为多行注释标记,符号“/** */”之间的所有内容均为注释内容。(注释内容可以换行)</p>
多行注释不能嵌套多行注释,可以嵌套单行注释
编码规范
(1)每条语句要独占一行,一条命令要以分号结束。英文状态下的分号“;”。
(2)为了日后的维护和阅读,尽量让代码更加简洁明了,便于阅读和理解应当多加注释。
2.2 变量与常量
标识符
标识符可以理解为一个名字,用来标识类名、变量名、方法名、数组名等有效的字符序列。
Java语言规定标识符有任意顺序的字母、下划线(-)、美元符号($)、和数字组成,并且第一个字符不能是数字。注意:标识符不能是Java中的关键字。
以下是java中的关键字
变量
声明变量并赋值给变量(可以改变的)
常量
程序运行过程中一直不会改变的量称为常量,常量也称为“final变量”,在整个程序中只能被赋值一次。
2.3 基本数据类型
(1)int型
(2)byte型
byte的声明方式与int型相同。
(3)short型
short型的声明方式与int型相同
(4)long型
long型的取值范围比int型大,属于比int型高级的数据类型,所以要和int做出区分,
需要在整数后面加L或者l。
整型数据在Java程序中有三种表示方式,分别为十进制,八进制,十六进制。
十进制:不能以0作为十进制的开头(0除外);
八进制:八进制必须以0开头;
十六进制:十六进制必须以0X或0x开头;
(5)浮点类型
在默认情况下小数都被看做double型(双精度浮点型),使用float型(单精度浮点型)小数,需要在小数后面添加f或F,也可以在小数后面添加D或d表明是一个double类型数据,无硬性规定,可加可不加。
注意:
浮点值属于近似值,在系统中结果可能与实际值有偏差。
(6)字符类型
(1)char型用于存储单个字符,占用16位的内存空间。
在声明字符型变量时要用单引号表示,如 's' 、'b' 表示一个字符。
(2)转义字符
(7)布尔类型
布尔类型又称逻辑类型,只有ture和false两个值,常用语于控制流程中的判断条件。
子主题
2.4 数据类型转换
1.隐式转换
隐式转换是从低级类型向高级类型的转换,系统将自动转换。
数据类型精度从“低”到“高”的顺序为:
byte < short < int < long < float <double;
数据类型精度从“低”到“高”的顺序为:
byte < short < int < long < float <double;
2.显示转换
当高精度的变量赋值给低精度变量时,必须使用显示转换运算(又称强制转换类型)
执行时可能会导致精度损失。
执行时可能会导致精度损失。
2.5 运算符
1. 赋值运算符——“=”,他是双目运算符,作用时把“=”右边的值赋给左边
2.算数运算符:“+、-、*、/、%”,分别代表加、减、乘、除、求余。
3.自增自减运算符:“a++、a--、++a、--a”符号在前的先计算后使用,符号 在后的先使用后计算。
4.关系运算符:“=、<、>、<=、>=、!=”分别代表等于、小于、大于、小于等于、大于等于、不等于,属于双目运算符,计算结果为布尔类型。
5.逻辑运算符:“&&、||、!”含义分别是逻辑与、逻辑或、逻辑非
6.位运算符:分别有左移<<、右移>>和无符号右移>>>,
第三章 流程控制
3.1 程序结构
顺序结构、选择结构、循环结构
3.2 条件语句
3.2.1 if条件语句
if.....else语句:通常表现为“如果满足某种条件,就执行某种处理,否则就执行另一种处理.条件语句可以有多种嵌套方式,可以根据具体需要进行设计,但一定要注意逻辑关系的正确处理。使用if语句嵌套时要注意else关键字要和if关键字成对出现,并且遵守临近原则,else关键字和自己最近的if语句构成一对。
注意else不能单独使用,必须和关键字if一起出现。
3.2.2 switch多分支语句
switch多分支语句:switch语句中参数必须是整数、字符型、枚举类型、字符串类型。switch语句首先计算参数的值,如果参数的值和某个case后面的常量表达式相同,则执行该case语句后的若干个语句,直到遇到break语句为止。如果switch语句中没有break关键字,即使执行完对应的case的处理语句,switch语句也不会立即停止,而是会继续执行下面所有的case,直到遇到break关键字或者完成执行完所有代码才停止
3.3 循环语句
3.3.1 while 循环语句
循环语句:while循环语句、do...whlie语句、for循环语句 、foreach语句、循环语句的嵌套。while语句的循环方式为利用一个条件来控制是否要继续反复执行这个语句 。当条件表达式的返回值为真时,则执行”{}“中的语句,当执行完“{}”中的语句后,重新判断条件表达式的返回值,直到表达式返回的结果为假时,退出循环。
3.3.2 do ...while 语句
do....while循环语句 :先执行一次循环后,再判断条件是否成立。也就是说do...while循环语句中“{}”中的程序段至少要被执行一次。
3.3.3 while 与do...while 比较
do....while循环语句 :先执行一次循环后,再判断条件是否成立。也就是说do...while循环语句中“{}”中的程序段至少要被执行一次。
3.3.4 for 循环语句
先执行表达式1 。
判断表达式2,若其值为真,则执行for语句中指定的内嵌语句,然后执行3.。若为假,则结束循环,转到5.。
执行表达式3.
返回2.继续执行。
循环结束,执行for语句下面的一个语句。
先执行表达式1 。
判断表达式2,若其值为真,则执行for语句中指定的内嵌语句,然后执行3.。若为假,则结束循环,转到5.。
执行表达式3.
返回2.继续执行。
循环结束,执行for语句下面的一个语句。
for(表达式1;表达式2;表达式3){
语句
}
语句
}
3.3.5 foreach 语句
public class test16 {//创建类
public static void main(String[] args) {//主方法
int arr[]={7,10,1};//声明一维数组
System.out.println("一维数组中的元素分别为:");//输出信息
for(int x:arr){//foreach语句,int x引用的变量,arr指定要循环遍历的数组,最后将x输出
System.out.println(x);//输出x的值
}
}
}//主要作用:遍历数组。
public static void main(String[] args) {//主方法
int arr[]={7,10,1};//声明一维数组
System.out.println("一维数组中的元素分别为:");//输出信息
for(int x:arr){//foreach语句,int x引用的变量,arr指定要循环遍历的数组,最后将x输出
System.out.println(x);//输出x的值
}
}
}//主要作用:遍历数组。
3.3.6 循环语句的嵌套
3.4 跳转语句
3.4.1break 语句
break语句:使用break语句可以跳出switch结构。在循环中可以跳出当前循环体,从而中断当前循环。
如果想要让break跳出外层循环,java提供了标签的功能,语法如下:
标签名:循环体{
break标签名;
}
标签名:任意标识符。
循环体:任意循环语句
break标签名:break跳出指定的循环体,此循环的标签名必须与break的标签名一致。带有标签的break可以制定跳出外层循环,这个循环可以是内层循环,也可以是外层循环。
标签名:循环体{
break标签名;
}
标签名:任意标识符。
循环体:任意循环语句
break标签名:break跳出指定的循环体,此循环的标签名必须与break的标签名一致。带有标签的break可以制定跳出外层循环,这个循环可以是内层循环,也可以是外层循环。
3.4.2 continue 语句
continue语句:continue不是立即跳出循环体,而是跳出本次循环结束前的语句,回到循环的条件测试部分,重新开始执行循环。continue语句也可以使用标签。
第四章 数组
4.1数组的概述
数组(array)是一种最简单的复合数据类型,它是有序数据的集合,数组中的每个元素具有相同的数据类型,可以用一个统一的数组名和不同的下标来确定数组中唯一的元素。根据数组的维度,可以将其分为一维数组、二维数组和多维数组等。
4.2 一维数组
4.2.1 创建一维数组
指的是一组相同数据类型的线性集合
4.2.2 初始化一维数组 分配数组储存空间
int arr[];//声明int型数组,数组的每个元素都是int型数值
double arr[];//声明double型数组,数组的每个元素都是double型数值
数组名字 = new 数组元素类型 [数组元素的个数];
arr = new int [5];//数组长度为五
int arr[];//声明int型数组,数组的每个元素都是int型数值
double arr[];//声明double型数组,数组的每个元素都是double型数值
数组名字 = new 数组元素类型 [数组元素的个数];
arr = new int [5];//数组长度为五
4.2.3 获取数组长度
4、获取数组长度
arrayName[index];其中,arrayName 表示数组变量,index 表示下标,下标为 0 表示获取第一个元素,下标为 array.length-1 表示获取最后一个元素。当指定的下标值超出数组的总长度时,会拋出 Array异常。
package javaProject001;
public class wwwwww {
public static void main(String[] args) {
char a[] = {'A','B','c','D'};
System.out.println("数组a长度为" + a.length);
char b[] = a;
System.out.println("数组b的长度为" + b.length);
}
}
4、获取数组长度
arrayName[index];其中,arrayName 表示数组变量,index 表示下标,下标为 0 表示获取第一个元素,下标为 array.length-1 表示获取最后一个元素。当指定的下标值超出数组的总长度时,会拋出 Array异常。
package javaProject001;
public class wwwwww {
public static void main(String[] args) {
char a[] = {'A','B','c','D'};
System.out.println("数组a长度为" + a.length);
char b[] = a;
System.out.println("数组b的长度为" + b.length);
}
}
4.2.4 使用一维数组
使用一维数组
import java.util.Scanner;//引入方法
public class Test {//创建类
public static void main(String[] args) {//主方法
int[] prices = new int[5]; // 声明数组并分配空间
Scanner input = new Scanner(System.in); // 接收用户从控制台输入的数据
for (int i = 0; i < prices.length; i++) {
System.out.println("请输入第" + (i + 1) + "件商品的价格:");
prices[i] = input.nextInt(); // 接收用户从控制台输入的数据
}
System.out.println("第 3 件商品的价格为:" + prices[2]);
}
}
使用一维数组
import java.util.Scanner;//引入方法
public class Test {//创建类
public static void main(String[] args) {//主方法
int[] prices = new int[5]; // 声明数组并分配空间
Scanner input = new Scanner(System.in); // 接收用户从控制台输入的数据
for (int i = 0; i < prices.length; i++) {
System.out.println("请输入第" + (i + 1) + "件商品的价格:");
prices[i] = input.nextInt(); // 接收用户从控制台输入的数据
}
System.out.println("第 3 件商品的价格为:" + prices[2]);
}
}
4.3 二维数组
4.3.1 创建并使用二维数组
int a [] [];
a = new int [2] [34];//直接分配行列
int b [] [];
int b = new int [2] [];//先分配行,不分配列
b[0] = new int [2];//给第一行分配列
b[1] = new int [2];//给第二列分配列
int a [] [];
a = new int [2] [34];//直接分配行列
int b [] [];
int b = new int [2] [];//先分配行,不分配列
b[0] = new int [2];//给第一行分配列
b[1] = new int [2];//给第二列分配列
4.3.2 初始化二维数组
package boketask;
public class eg1 {
public static void main(String[] args) {
int taderr1 [] [] = {{1,2,5},{5,7,9}};
int tader2 [] [] = new int [] [] {{65,55,12},{97,65,312}};
int tader3 [] [] = new int [2][3];//先给数组分配内存空间
tader3[0] = new int [] {78,88,66};//给第一行分配一个一维数组
tader3[1][0] = 64;//第二行第一列赋值
tader3[1][1] = 21;//第二行第二列赋值
tader3[1][2] = 19;//第二行第三列赋值
}
}
package boketask;
public class eg1 {
public static void main(String[] args) {
int taderr1 [] [] = {{1,2,5},{5,7,9}};
int tader2 [] [] = new int [] [] {{65,55,12},{97,65,312}};
int tader3 [] [] = new int [2][3];//先给数组分配内存空间
tader3[0] = new int [] {78,88,66};//给第一行分配一个一维数组
tader3[1][0] = 64;//第二行第一列赋值
tader3[1][1] = 21;//第二行第二列赋值
tader3[1][2] = 19;//第二行第三列赋值
}
}
4.3.3 使用二维数组
package shuzutask1;//包名
public class asdfdfdfdf {//创建类
public static void main(String[] args) {//主方法
char arr[][] = new char[4][];//创建一个四行的二维数组
arr[0]= new char[] {'春','眠','不','觉','晓'};//给数组赋值
arr[1]= new char[] {'处','处','闻','啼','鸟'};//给数组赋值
arr[2]= new char[] {'夜','来','风','雨','声'};//给数组赋值
arr[3]= new char[] {'花','落','知','多','少'};//给数组赋值
for (int i = 0;i<arr.length;i++) {//循环四行
for (int j = 0;j<5;j++) {循环五列
System.out.print(arr[i][j]);}//输出数组
if(i%2==0) {
System.out.println(",");}//如果1、3句输出逗号
else
{System.out.println("。");//如果2、4句输出句号
}
}
System.out.println("---------------------------------------");//输出一段横线
for (int j=0;j<5;j++) {//列变行
for(int i=3;i>=0;i--) {//行变列,反序输出
System.out.print(arr[i][j]);//输出数组
}
System.out.println();//换行
}
System.out.println("。,。,");//输出标点符号
}}
package shuzutask1;//包名
public class asdfdfdfdf {//创建类
public static void main(String[] args) {//主方法
char arr[][] = new char[4][];//创建一个四行的二维数组
arr[0]= new char[] {'春','眠','不','觉','晓'};//给数组赋值
arr[1]= new char[] {'处','处','闻','啼','鸟'};//给数组赋值
arr[2]= new char[] {'夜','来','风','雨','声'};//给数组赋值
arr[3]= new char[] {'花','落','知','多','少'};//给数组赋值
for (int i = 0;i<arr.length;i++) {//循环四行
for (int j = 0;j<5;j++) {循环五列
System.out.print(arr[i][j]);}//输出数组
if(i%2==0) {
System.out.println(",");}//如果1、3句输出逗号
else
{System.out.println("。");//如果2、4句输出句号
}
}
System.out.println("---------------------------------------");//输出一段横线
for (int j=0;j<5;j++) {//列变行
for(int i=3;i>=0;i--) {//行变列,反序输出
System.out.print(arr[i][j]);//输出数组
}
System.out.println();//换行
}
System.out.println("。,。,");//输出标点符号
}}
4.4 数组的基本操作
4.4.1 遍历数组
Java 的数组要求所有的数组元素具有相同的数据类型。因此,在一个数组中,数组元素的类型是唯一的,即一个数组里只能存储一种数据类型的数据,而不能存储多种数据类型的数据。
4.4.2 填充和批量替换数组元素
使用fill()方法选择要填充的元素索引的范围,前包括,后不包括,然后填入要分配的元素
4.4.3 复制数组
在 Java 中实现数组复制分别有以下 4 种方法:
Arrays 类的 copyOf() 方法
Arrays 类的 copyOfRange() 方法
System 类的 arraycopy() 方法
Object 类的 clone() 方法
使用 copyOf() 方法和 copyOfRange() 方法
srcArray 表示要进行复制的数组,length 表示复制后的新数组的长度。
使用这种方法复制数组时,默认从原数组的第一个元素(索引值为 0)开始复制,目标数组的长度将为 length。如果 length 大于 srcArray.length,则目标数组中采用默认值填充;如果 length 小于 srcArray.length,则复制到第 length 个元素(索引值为 length-1)即止。
注意:目标数组如果已经存在,将会被重构。
package boketask;
import java.util.Arrays;
public class boletask2 {
public static void main(String[] args) {
int arr[] = new int[] {23,43,54,32,564};//定义数组
int newarr[] = Arrays.copyOfRange(arr,0,3);//复制数组
for(int i = 0;i<newarr.length;i++) {//循环遍历赋值后的数组
System.out.println(newarr[i]);//将新的数组中的元素输出
}
}
}//使用copyof方法复制索引从0到3的元素
public class Test20 {//创建类
public static void main(String[] args) {//主方法
// 定义长度为8的数组
int scores[] = new int[] { 57, 81, 68, 75, 91 };
System.out.println("原数组内容如下:");
// 循环遍历原数组
for (int i = 0; i < scores.length; i++) {
System.out.print(scores[i] + "\t");
}
// 复制原数组的前5个元素到newScores数组中
int newScores[] = (int[]) Arrays.copyOfRange(scores, 0, 5);
System.out.println("\n复制的新数组内容如下:");
// 循环遍历目标数组,即复制后的新数组
for (int j = 0; j < newScores.length; j++) {
System.out.print(newScores[j] + "\t");
}
}
}//用copyOfRange方法复制索引0到5的元素的新建新数组
Arrays 类的 copyOf() 方法
Arrays 类的 copyOfRange() 方法
System 类的 arraycopy() 方法
Object 类的 clone() 方法
使用 copyOf() 方法和 copyOfRange() 方法
srcArray 表示要进行复制的数组,length 表示复制后的新数组的长度。
使用这种方法复制数组时,默认从原数组的第一个元素(索引值为 0)开始复制,目标数组的长度将为 length。如果 length 大于 srcArray.length,则目标数组中采用默认值填充;如果 length 小于 srcArray.length,则复制到第 length 个元素(索引值为 length-1)即止。
注意:目标数组如果已经存在,将会被重构。
package boketask;
import java.util.Arrays;
public class boletask2 {
public static void main(String[] args) {
int arr[] = new int[] {23,43,54,32,564};//定义数组
int newarr[] = Arrays.copyOfRange(arr,0,3);//复制数组
for(int i = 0;i<newarr.length;i++) {//循环遍历赋值后的数组
System.out.println(newarr[i]);//将新的数组中的元素输出
}
}
}//使用copyof方法复制索引从0到3的元素
public class Test20 {//创建类
public static void main(String[] args) {//主方法
// 定义长度为8的数组
int scores[] = new int[] { 57, 81, 68, 75, 91 };
System.out.println("原数组内容如下:");
// 循环遍历原数组
for (int i = 0; i < scores.length; i++) {
System.out.print(scores[i] + "\t");
}
// 复制原数组的前5个元素到newScores数组中
int newScores[] = (int[]) Arrays.copyOfRange(scores, 0, 5);
System.out.println("\n复制的新数组内容如下:");
// 循环遍历目标数组,即复制后的新数组
for (int j = 0; j < newScores.length; j++) {
System.out.print(newScores[j] + "\t");
}
}
}//用copyOfRange方法复制索引0到5的元素的新建新数组
用 clone() 方法
clone() 方法也可以实现复制数组。该方法是类 Object 中的方法,可以创建一个有单独内存空间的对象。因为数组也是一个 Object 类,因此也可以使用数组对象的 clone() 方法来复制数组。
clone() 方法也可以实现复制数组。该方法是类 Object 中的方法,可以创建一个有单独内存空间的对象。因为数组也是一个 Object 类,因此也可以使用数组对象的 clone() 方法来复制数组。
用 arraycopy() 方法
srcArray 表示原数组;srcIndex 表示原数组中的起始索引;destArray 表示目标数组;destIndex 表示目标数组中的起始索引;length 表示要复制的数组长度。
使用此方法复制数组时,length+srcIndex 必须小于等于 srcArray.length,同时 length+destIndex 必须小于等于 destArray.length。
注意:目标数组必须已经存在,且不会被重构,相当于替换目标数组中的部分元素。
srcArray 表示原数组;srcIndex 表示原数组中的起始索引;destArray 表示目标数组;destIndex 表示目标数组中的起始索引;length 表示要复制的数组长度。
使用此方法复制数组时,length+srcIndex 必须小于等于 srcArray.length,同时 length+destIndex 必须小于等于 destArray.length。
注意:目标数组必须已经存在,且不会被重构,相当于替换目标数组中的部分元素。
4.5 数组的排序
4.5.1 算法:冒泡排序
冒泡排序(Bubble Sort)是常用的数组排序算法之一,它以简洁的思想与实现方法而备受青睐,也是广大学习者最先接触的一种排序算法。
冒泡排序的基本思想是:对比相邻的元素值,如果满足条件就交换元素值,把较小的元素值移动到数组前面,把大的元素值移动到数组后面(也就是交换两个元素的位置),这样数组元素就像气泡一样从底部上升到顶部。
冒泡排序的算法比较简单,排序的结果稳定,但时间效率不太高。Java 中的冒泡排序在双层循环中实现,其中外层循环控制排序轮数,总循环次数为要排序数组的长度减 1。而内层循环主要用于对比相邻元素的大小,以确定是否交换位置,对比和交换次数依排序轮数而减少。
package javaProject001;//包名
public class BubbleSort {//创建类
public void sort(int[] array) {
for(int i = 1;i<array.length;i++)
{for (int j=0;j<array.length-i;j++) {//比较相邻的两个元素,较大的数往后冒泡
if (array[j]>array[j+1]) {//如果前者比后者大则互换位置
int temp = array[j];//把第一个元素的值保存到临时变量中
array[j]=array[j+1];//把第二个元素值保存到第一个元素单元中
array[j+1]=temp;}//把临时变量(第一个元素的值)保存到第二个元素中
}
}
showArray(array);}//输出冒泡后的数组元素
public void showArray(int[] array) {
System.out.println("冒泡排序结果:");
for (int i :array) {//遍历数组
System.out.println(i+" ");//输出内容
}
System.out.println();//换行
}
public static void main(String[] args) {//主方法
int[] array = {63,3,12,45,54,87,21};//新建无序的数组
BubbleSort sorter = new BubbleSort();//调用排序方法进行排序
sorter.sort(array);//输出内容
}
}
冒泡排序的基本思想是:对比相邻的元素值,如果满足条件就交换元素值,把较小的元素值移动到数组前面,把大的元素值移动到数组后面(也就是交换两个元素的位置),这样数组元素就像气泡一样从底部上升到顶部。
冒泡排序的算法比较简单,排序的结果稳定,但时间效率不太高。Java 中的冒泡排序在双层循环中实现,其中外层循环控制排序轮数,总循环次数为要排序数组的长度减 1。而内层循环主要用于对比相邻元素的大小,以确定是否交换位置,对比和交换次数依排序轮数而减少。
package javaProject001;//包名
public class BubbleSort {//创建类
public void sort(int[] array) {
for(int i = 1;i<array.length;i++)
{for (int j=0;j<array.length-i;j++) {//比较相邻的两个元素,较大的数往后冒泡
if (array[j]>array[j+1]) {//如果前者比后者大则互换位置
int temp = array[j];//把第一个元素的值保存到临时变量中
array[j]=array[j+1];//把第二个元素值保存到第一个元素单元中
array[j+1]=temp;}//把临时变量(第一个元素的值)保存到第二个元素中
}
}
showArray(array);}//输出冒泡后的数组元素
public void showArray(int[] array) {
System.out.println("冒泡排序结果:");
for (int i :array) {//遍历数组
System.out.println(i+" ");//输出内容
}
System.out.println();//换行
}
public static void main(String[] args) {//主方法
int[] array = {63,3,12,45,54,87,21};//新建无序的数组
BubbleSort sorter = new BubbleSort();//调用排序方法进行排序
sorter.sort(array);//输出内容
}
}
4.5.2 算法:选择排序
排序选择
使用选择排序法也可以对上述数组中的元素进行排序,但是它与冒泡排序不同。选择排序是指每一趟从待排序的数据元素中选出最大(或最小)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
package javaProject001;//包名
public class SelectSort {//创建类
public void sort(int[] array) {//定义方法
int index;//int型变量
for(int i=1;i<array.length;i++) {//for循环遍历数组
index =0;//给变量赋值
for(int j=1;j<=array.length - i;j++) {
if (array[j] > array[index]) {//如果前一个元素比后一个元素大则位置互换
index = j;}}//交换位置
int temp = array[array.length-i];
array[array.length-i] = array[index];
array[index] = temp;}
showArray(array);//输出直接选择排序的数组值
}
public void showArray(int[] array) {
System.out.println("选择排序结果为:");
for (int i : array) {//遍历数组
System.out.println(i + " ");//输出
}
System.out.println();//换行
}
public static void main(String[] args) {//主方法
int[] array = {23,1,55,99,56,45,32};//创建无序的数组
SelectSort sorter = new SelectSort();//调用排序对象将数组排序
sorter.sort(array);//输出数组
}
}
使用选择排序法也可以对上述数组中的元素进行排序,但是它与冒泡排序不同。选择排序是指每一趟从待排序的数据元素中选出最大(或最小)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
package javaProject001;//包名
public class SelectSort {//创建类
public void sort(int[] array) {//定义方法
int index;//int型变量
for(int i=1;i<array.length;i++) {//for循环遍历数组
index =0;//给变量赋值
for(int j=1;j<=array.length - i;j++) {
if (array[j] > array[index]) {//如果前一个元素比后一个元素大则位置互换
index = j;}}//交换位置
int temp = array[array.length-i];
array[array.length-i] = array[index];
array[index] = temp;}
showArray(array);//输出直接选择排序的数组值
}
public void showArray(int[] array) {
System.out.println("选择排序结果为:");
for (int i : array) {//遍历数组
System.out.println(i + " ");//输出
}
System.out.println();//换行
}
public static void main(String[] args) {//主方法
int[] array = {23,1,55,99,56,45,32};//创建无序的数组
SelectSort sorter = new SelectSort();//调用排序对象将数组排序
sorter.sort(array);//输出数组
}
}
4.5.3 Array.Sort()方法
Array,Sort(object)//object类
升序
public static void main(String[] args) {//主方法
// 定义含有5个元素的数组
double[] scores = new double[] { 78, 45, 85, 97, 87 };
System.out.println("排序前数组内容如下:");
// 对scores数组进行循环遍历
for (int i = 0; i < scores.length; i++) {
System.out.print(scores[i] + "\t");
}
System.out.println("\n排序后的数组内容如下:");
// 对数组进行排序
Arrays.sort(scores);
// 遍历排序后的数组
for (int j = 0; j < scores.length; j++) {
System.out.print(scores[j] + "\t");
}
}
升序
public static void main(String[] args) {//主方法
// 定义含有5个元素的数组
double[] scores = new double[] { 78, 45, 85, 97, 87 };
System.out.println("排序前数组内容如下:");
// 对scores数组进行循环遍历
for (int i = 0; i < scores.length; i++) {
System.out.print(scores[i] + "\t");
}
System.out.println("\n排序后的数组内容如下:");
// 对数组进行排序
Arrays.sort(scores);
// 遍历排序后的数组
for (int j = 0; j < scores.length; j++) {
System.out.print(scores[j] + "\t");
}
}
降序
利用 Collections.reverseOrder() 方法//包装类
package boketask;//包名
import java.util.Arrays;//引入方法
public class boketask3 {//创建类
public static void main(String[] args) {//主方法
int arr[] = new int [] {23,34,454,56};//new方法新建数组
Arrays.sort(arr);//将数组进行排序
System.out.println("排序后结果为:");//输出内容
for (int i = 0; i<arr.length;i++) {//for循环遍历数组
System.out.println(arr[i]+"");//输出内容
}
}
}
利用 Collections.reverseOrder() 方法//包装类
package boketask;//包名
import java.util.Arrays;//引入方法
public class boketask3 {//创建类
public static void main(String[] args) {//主方法
int arr[] = new int [] {23,34,454,56};//new方法新建数组
Arrays.sort(arr);//将数组进行排序
System.out.println("排序后结果为:");//输出内容
for (int i = 0; i<arr.length;i++) {//for循环遍历数组
System.out.println(arr[i]+"");//输出内容
}
}
}
第五章 字符串
5.1 String类
5.1.1 声明字符串
字符串常量,可以显示任何文字信息。
声明如下
String a;//声明字符串
String a,b;//声明字符串
String a,b;//声明字符串
5.1.2 创建字符串
1、引用字符串常量
String a = "时间就是金钱,我的朋友。";//定义string类型的字符串
String b = "锄禾日当午",c = "小鸡炖蘑菇";//定义a,b两个字符串
String str1,str2;//声明两个String类型的变量
str1="we are student.";//传入字符串
str2="I'm a student.";//传入字符串
String b = "锄禾日当午",c = "小鸡炖蘑菇";//定义a,b两个字符串
String str1,str2;//声明两个String类型的变量
str1="we are student.";//传入字符串
str2="I'm a student.";//传入字符串
2、 利用构造方法实例化
例如:使用new关键词创建String对象;
String a = new String ("我爱清汤小肥羊。");//用new关键字创建String对象
String b = new String (a);//用new关键字创建String对象
String b = new String (a);//用new关键字创建String对象
3、利用字符数组实例化
子主题例如:定义一个字符数组,并创建个字符串;
char[] a = {'t','i','m','e'};//定义字符类型数组创建一个字符串
String b = new String(a);//用new关键字创建String对象
String b = new String(a);//用new关键字创建String对象
4、提取字符数组中的一部分创建子字符串对象
char[] a = ('时','间','就','是','金','钱');//用字符类型创建字符串
String b = new String(a,3,2);//定义字符串b,从索引3开始提取两个字符
char[] a = ('时','间','就','是','金','钱');//用字符类型创建字符串
String b = new String(a,3,2);//定义字符串b,从索引3开始提取两个字符
package boketask;//java包名
public class qwqw {//创建类的名字
public static void main(String[] args) {//主函数
String a = "时间就是金钱,我的朋友。";//直接应用字符串常量
System.out.println("a=" +a);//一个输出语句
String b = new String("我爱清汤小肥羊。");//利用构造方法实例化
System.out.println("b="+b);//一个输出语句
String c= new String(b);//使用已有字符串常量实例化
System.out.println("c="+c);//一个输出语句
char[] charArray = {'t','i','m','e'};//一个字符类型的数组创建字符串
String d = new String (charArray);//利用字符数组实例化
System.out.println("d="+d);//一个输出语句
char[] charArray2 = {'时','间','就','是','金','钱'};//一个字符类型的数组创建字符串
String e = new String(charArray2,4,2);//提取字符数组部分内容,从下标为4的元素开始,截取两个字符
System.out.println("e="+e);//一个输出语句
}
}
public class qwqw {//创建类的名字
public static void main(String[] args) {//主函数
String a = "时间就是金钱,我的朋友。";//直接应用字符串常量
System.out.println("a=" +a);//一个输出语句
String b = new String("我爱清汤小肥羊。");//利用构造方法实例化
System.out.println("b="+b);//一个输出语句
String c= new String(b);//使用已有字符串常量实例化
System.out.println("c="+c);//一个输出语句
char[] charArray = {'t','i','m','e'};//一个字符类型的数组创建字符串
String d = new String (charArray);//利用字符数组实例化
System.out.println("d="+d);//一个输出语句
char[] charArray2 = {'时','间','就','是','金','钱'};//一个字符类型的数组创建字符串
String e = new String(charArray2,4,2);//提取字符数组部分内容,从下标为4的元素开始,截取两个字符
System.out.println("e="+e);//一个输出语句
}
}
运行结果如下:
5.2 连接字符串
5.2.1 连接字符串
使用“+”运算符可以实现拼接多个字符串的功能,并产生一个String对象,出来“+”运算符,“+=”运算符同样可以实现字符串拼接。
java中相连的字符串不能直接分为两行。例如
java中相连的字符串不能直接分为两行。例如
5.2.2 连接其他数据类型
字符串也可以同其他的基本数据类型进行连接。
注意:字符串在计算公式中的前后顺序会影响运算结果;
注意:字符串在计算公式中的前后顺序会影响运算结果;
例如:
String a = "1" +2+3+4 -->"1234"//碰到字符串后,直接输出后面内容
String b = 1+2+3+"4" -->"64" //碰到字符串前,先做运算,后输出内容
String c = "1"+(2+3+4) -->"19" //碰到字符串后,先运算括号中的值,后输出内容
String b = 1+2+3+"4" -->"64" //碰到字符串前,先做运算,后输出内容
String c = "1"+(2+3+4) -->"19" //碰到字符串后,先运算括号中的值,后输出内容
5.3 提取字符串信息
5.3.1 获取字符串长度
定义一个字符串num ,使用length()方法获取其长度。
5.3.2 获取指定字符
package boketask;//包名
public class hqzdzf {//创建类
public static void main(String[] args) {//主方法
String str = "床前明月光,疑是地上霜。";//定义字符串
char chr = str.charAt(4);//将字符串str中索引位置为4的字符赋值给chr
System.out.println("字符串中索引位置为4的字符是:"+chr);//输出chr
}
}
public class hqzdzf {//创建类
public static void main(String[] args) {//主方法
String str = "床前明月光,疑是地上霜。";//定义字符串
char chr = str.charAt(4);//将字符串str中索引位置为4的字符赋值给chr
System.out.println("字符串中索引位置为4的字符是:"+chr);//输出chr
}
}
运行结果如下:
5.3.3 获取子字符串索引位置
String类提供了两种查找字符串的方法,即indexOf()与lastIndexOf()方法。
1. indexOf(String str)
语法如下:
a.indexOf(substr);//indexOf的使用方法
a:任意字符串对象
substr:要搜索的字符串
如下所示:
package boketask;//包名
public class hqzzfcweizhi {//创建类名
public static void main(String[] args) {//主方法
String str = "12345abcde";//创建字符串对象
int charIndex = str.indexOf("abc");//获取字符串str中"abc"首次出现的索引,赋值给charIndex
if (charIndex !=1) {//判断:index的值不等于-1
//如果index不等于-1,则执行这串代码,说明str中存在"abc"字符串
System.out.println("str中存在abc字符串");//输出内容
} else {//如果index=-1,则执行这串代码,说明str中不存在"abc"字符串
System.out.println("str中没有abc字符串");//输出内容
}
}
}
运行结果如下:
语法如下:
a.indexOf(substr);//indexOf的使用方法
a:任意字符串对象
substr:要搜索的字符串
如下所示:
package boketask;//包名
public class hqzzfcweizhi {//创建类名
public static void main(String[] args) {//主方法
String str = "12345abcde";//创建字符串对象
int charIndex = str.indexOf("abc");//获取字符串str中"abc"首次出现的索引,赋值给charIndex
if (charIndex !=1) {//判断:index的值不等于-1
//如果index不等于-1,则执行这串代码,说明str中存在"abc"字符串
System.out.println("str中存在abc字符串");//输出内容
} else {//如果index=-1,则执行这串代码,说明str中不存在"abc"字符串
System.out.println("str中没有abc字符串");//输出内容
}
}
}
运行结果如下:
说明:
如果参数是一个字符串,返回的结果是字符串第一个字母所在位置。
String str = "abcdefg"; //定义一个字符串
str.lastInderOf("def"); //返回值是3
如果参数是一个字符串,返回的结果是字符串第一个字母所在位置。
String str = "abcdefg"; //定义一个字符串
str.lastInderOf("def"); //返回值是3
2. indexOf(String str,int fromIndex)
从指定的索引 fromIndex 开始至字符串最后,返回指定子字符串中第一次出现处的索引。
如果没有检索到字符串str,该方法返回的值为-1。
语法如下:
a.indexOf(str,fromIndex);//该方法的使用格式
解释说明:
a:任意字符对象
str:要搜索的子字符串
fromIndex:开始搜索引的位置
例:
package boketask;//包名
public class PIPIPI {//创建类
public static void main(String[] args) {//主方法
String str = "we are the world";//定义一个字符串
int firstIndex = str.indexOf("r");//获取字符串中r第一次出现的索引位置
//获取字符串中r第二次出现的索引位置,从r第一次出现的索引位置开始查找
int secondIndex = str.indexOf("r",firstIndex+1);//获取字符串中r第二次出现的索引位置
//获取字符串中r第三次出现的索引位置,从r第二次出现的索引位置开始查找
int thirdIndex = str.indexOf("r",secondIndex+1);//获取字符串中r第三次出现的索引位置
//输出三次获取的索引位置
System.out.println("r第一次出现的索引位置是:"+firstIndex);//输出r第一次出现的索引位置
System.out.println("r第二次出现的索引位置是:"+secondIndex);//输出r第二次出现的索引位置
System.out.println("r第三次出现的索引位置是:"+thirdIndex);//输出r第三次出现的索引位置
}
}
运行结果:
如果没有检索到字符串str,该方法返回的值为-1。
语法如下:
a.indexOf(str,fromIndex);//该方法的使用格式
解释说明:
a:任意字符对象
str:要搜索的子字符串
fromIndex:开始搜索引的位置
例:
package boketask;//包名
public class PIPIPI {//创建类
public static void main(String[] args) {//主方法
String str = "we are the world";//定义一个字符串
int firstIndex = str.indexOf("r");//获取字符串中r第一次出现的索引位置
//获取字符串中r第二次出现的索引位置,从r第一次出现的索引位置开始查找
int secondIndex = str.indexOf("r",firstIndex+1);//获取字符串中r第二次出现的索引位置
//获取字符串中r第三次出现的索引位置,从r第二次出现的索引位置开始查找
int thirdIndex = str.indexOf("r",secondIndex+1);//获取字符串中r第三次出现的索引位置
//输出三次获取的索引位置
System.out.println("r第一次出现的索引位置是:"+firstIndex);//输出r第一次出现的索引位置
System.out.println("r第二次出现的索引位置是:"+secondIndex);//输出r第二次出现的索引位置
System.out.println("r第三次出现的索引位置是:"+thirdIndex);//输出r第三次出现的索引位置
}
}
运行结果:
代码注解:
从运行结果可以看出,由于字符串只有两个“r”,所以程序输出了这两个“r”的索引位置,
第三次搜索是找不到“r”,所以返回结果为-1。
3. public int lastIndexOf(String str)
返回指定子字符串在此字符串中最右边出现处的索引,语法如下:
a.lastIndexOf(atr);//该方法的使用格式
解释说明:
a:任何字符串。
str:要搜索的字符串。
例子:
package boketask;//包名
public class StringLastIndexOf {//创建类
public static void main(String[] args) {//主方法
String str = "Let it go!Let it go!";//创建字符串对象
int gIndex = str.lastIndexOf("g");//返回“g”最后一次出现的位置
int goIndex = str.lastIndexOf("go");//返回“go”最后一次出现的位置
int oIndex = str.lastIndexOf("o");//返回“o”最后一次出现的
System.out.println("字符串\"Let in go!Let it go!中:\n");//输出提示内容
System.out.println("\"g\"最后一次出现的位置是:" + gIndex);//输出“g”最后一次出现的位置
System.out.println("\"o\"最后一次出现的位置是:" + oIndex);//输出“o”最后一次出现的位置
System.out.println("\"\"go最后一次出现的位置是:" + goIndex);//输出“go”最后一次出现的位置
}
}
运行结果:
返回指定子字符串在此字符串中最右边出现处的索引,语法如下:
a.lastIndexOf(atr);//该方法的使用格式
解释说明:
a:任何字符串。
str:要搜索的字符串。
例子:
package boketask;//包名
public class StringLastIndexOf {//创建类
public static void main(String[] args) {//主方法
String str = "Let it go!Let it go!";//创建字符串对象
int gIndex = str.lastIndexOf("g");//返回“g”最后一次出现的位置
int goIndex = str.lastIndexOf("go");//返回“go”最后一次出现的位置
int oIndex = str.lastIndexOf("o");//返回“o”最后一次出现的
System.out.println("字符串\"Let in go!Let it go!中:\n");//输出提示内容
System.out.println("\"g\"最后一次出现的位置是:" + gIndex);//输出“g”最后一次出现的位置
System.out.println("\"o\"最后一次出现的位置是:" + oIndex);//输出“o”最后一次出现的位置
System.out.println("\"\"go最后一次出现的位置是:" + goIndex);//输出“go”最后一次出现的位置
}
}
运行结果:
4. lastIndexOf(String str,int fromIndex)
返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。
语法如下:
a. lastIndexOf(str,fronIndex);//该方法使用格式
解释说明:
a:任意字符串。
str:要搜索的子字符串。
fromIndex: 开始搜索的索引位置。
例如下面的代码:
运行结果如下:
package boketask;//包名
public class StringLastIndexOf2 {//创建类
public static void main(String[] args) {//主方法
String str = "01a3a56a89";//创建字符串对象
int lastIndex = str.lastIndexOf("a");//返回字母“a”最后一次出现的索引位置
//返回字母“a”的索引位置otheerIndex
//满足0<=fiveBeforeIndex<=5条件,在满足条件的结果集中,返回最大的数字
int fiveBeforIndex = str.lastIndexOf("a",5);
//返回字母“a”的索引位置otherIndex
//满足0<=threeBeforIndex<=3条件,在满足条件的结果集中,返回最大的数字
int threeBeforIndex = str.lastIndexOf("a",3);
System.out.println("字符串\"01a3a56a89\"中:\n");//输出括号内的内容
System.out.println("字母\"a\"最后一次出现的位置是:"+ lastIndex);
System.out.println("从索引5开始往回搜索,字母\"a\"最后一次出现的位置:"+ fiveBeforIndex);
System.out.println("从索引3开始往回搜索,字母\"a\"最后一次出现的位置" + threeBeforIndex);
}
}
运行结果如下:
返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。
语法如下:
a. lastIndexOf(str,fronIndex);//该方法使用格式
解释说明:
a:任意字符串。
str:要搜索的子字符串。
fromIndex: 开始搜索的索引位置。
例如下面的代码:
运行结果如下:
package boketask;//包名
public class StringLastIndexOf2 {//创建类
public static void main(String[] args) {//主方法
String str = "01a3a56a89";//创建字符串对象
int lastIndex = str.lastIndexOf("a");//返回字母“a”最后一次出现的索引位置
//返回字母“a”的索引位置otheerIndex
//满足0<=fiveBeforeIndex<=5条件,在满足条件的结果集中,返回最大的数字
int fiveBeforIndex = str.lastIndexOf("a",5);
//返回字母“a”的索引位置otherIndex
//满足0<=threeBeforIndex<=3条件,在满足条件的结果集中,返回最大的数字
int threeBeforIndex = str.lastIndexOf("a",3);
System.out.println("字符串\"01a3a56a89\"中:\n");//输出括号内的内容
System.out.println("字母\"a\"最后一次出现的位置是:"+ lastIndex);
System.out.println("从索引5开始往回搜索,字母\"a\"最后一次出现的位置:"+ fiveBeforIndex);
System.out.println("从索引3开始往回搜索,字母\"a\"最后一次出现的位置" + threeBeforIndex);
}
}
运行结果如下:
5.3.4 判断字符串首尾内容
startWith()方法和 endsWith()方法分别用于判断字符串是否以指定内容开始或结束。
这两个方法返回的值都是boolean类型。
这两个方法返回的值都是boolean类型。
1. startWith(String prefix)
package javaProject001;//包名
public class StringStartWith {//创建类
public static void main(String[] args) {//主方法
String myDream1 = "我有一个梦想,幽谷上升,高山下降;";//前半句,创建字符串对象
String myDream2 = "坎坷曲折之路成坦途,圣光披露,满照人间。";//后半句 创建字符串对象
// 打印整句话
System.out.println(myDream1+myDream2 + "\n——马丁·路德金《我有一个梦想》\n");
boolean firstBool = myDream1.startsWith("我有一个梦想");//判断前半句是否以“我有一个梦想”为前缀
boolean secondBool = myDream2.startsWith("我有一个梦想");//判断后半句是否以“我有一个梦想”为后缀
if (firstBool) {
System.out.println("前半句是以\"我有一个梦想\"开始的。");//判断前半句逻辑结果
}else if (secondBool) {
System.out.println("后半句是以\"我有一个梦想\"开始的。");//判断前半句逻辑结果
}}
}
package javaProject001;//包名
public class StringStartWith {//创建类
public static void main(String[] args) {//主方法
String myDream1 = "我有一个梦想,幽谷上升,高山下降;";//前半句,创建字符串对象
String myDream2 = "坎坷曲折之路成坦途,圣光披露,满照人间。";//后半句 创建字符串对象
// 打印整句话
System.out.println(myDream1+myDream2 + "\n——马丁·路德金《我有一个梦想》\n");
boolean firstBool = myDream1.startsWith("我有一个梦想");//判断前半句是否以“我有一个梦想”为前缀
boolean secondBool = myDream2.startsWith("我有一个梦想");//判断后半句是否以“我有一个梦想”为后缀
if (firstBool) {
System.out.println("前半句是以\"我有一个梦想\"开始的。");//判断前半句逻辑结果
}else if (secondBool) {
System.out.println("后半句是以\"我有一个梦想\"开始的。");//判断前半句逻辑结果
}}
}
结果如下:
2. startWith(String prefix,int tooffset)
该方法用于判断从指定索引开始的子字符串是否以指定的前缀开始。
语法如下:
str.startWith(prefix,index);//该方法使用方式
解释说明:
str:任意字符串。
prefix:作为前缀的字符串。
index:开始查找的位置。
例:
package javaProject001;//包名
public class StringStartWith2 {//创建类
public static void main(String[] args) {//主方法
String str = "床前明月光,疑是地上霜。\n举头望明月,低头思故乡。";//创建字符串对象
System.out.println(" 《静夜思》 \n" +str+"\n");//打印古诗
int enterIndex = str.indexOf("\n");//返回换行符所在的位置
boolean flag = str.startsWith("举",enterIndex);//返回换行符之后开始的子字符串前缀是否为“举”
if (flag) {
System.out.println("第二行是以\"举\"开始的");//如果结果为真,则输出此句
}else {
System.out.println("第二行是以\""+str.charAt(enterIndex + 1)+"\"开始的");
//如果结果为假,则输出第二行开头的第一个字符
}
}
}
运行结果如下:
该方法用于判断从指定索引开始的子字符串是否以指定的前缀开始。
语法如下:
str.startWith(prefix,index);//该方法使用方式
解释说明:
str:任意字符串。
prefix:作为前缀的字符串。
index:开始查找的位置。
例:
package javaProject001;//包名
public class StringStartWith2 {//创建类
public static void main(String[] args) {//主方法
String str = "床前明月光,疑是地上霜。\n举头望明月,低头思故乡。";//创建字符串对象
System.out.println(" 《静夜思》 \n" +str+"\n");//打印古诗
int enterIndex = str.indexOf("\n");//返回换行符所在的位置
boolean flag = str.startsWith("举",enterIndex);//返回换行符之后开始的子字符串前缀是否为“举”
if (flag) {
System.out.println("第二行是以\"举\"开始的");//如果结果为真,则输出此句
}else {
System.out.println("第二行是以\""+str.charAt(enterIndex + 1)+"\"开始的");
//如果结果为假,则输出第二行开头的第一个字符
}
}
}
运行结果如下:
3. endsWith(String suffix)
该方法判断字符串是否以指定的后缀结束。
语法如下:
str.endsWith(suffix);//该方法的使用格式
解释说明:
str :任意字符串。
suffix:指定的后缀字符串。
例:
package javaProject001;//包名
public class StringEndsWith {//创建类
public static void main(String[] args) {//主方法
String str1 = "你说完了吗?";//创建字符串对象
String str2 = "我说完了。";//创建字符串对象
boolean flag1 = str1.endsWith("。");//判断str1是否以“。”结尾
boolean flag2 = str2.endsWith("。");//判断str2是否以“。”结尾
System.out.println("字符串str1是以句号结尾的吗?"+flag1);//输出结果
System.out.println("字符串str2是以句号结尾的吗?"+flag2);//输出结果
}
}
运行结果如下:
该方法判断字符串是否以指定的后缀结束。
语法如下:
str.endsWith(suffix);//该方法的使用格式
解释说明:
str :任意字符串。
suffix:指定的后缀字符串。
例:
package javaProject001;//包名
public class StringEndsWith {//创建类
public static void main(String[] args) {//主方法
String str1 = "你说完了吗?";//创建字符串对象
String str2 = "我说完了。";//创建字符串对象
boolean flag1 = str1.endsWith("。");//判断str1是否以“。”结尾
boolean flag2 = str2.endsWith("。");//判断str2是否以“。”结尾
System.out.println("字符串str1是以句号结尾的吗?"+flag1);//输出结果
System.out.println("字符串str2是以句号结尾的吗?"+flag2);//输出结果
}
}
运行结果如下:
5.3.5 获取字符数组
toCharArray()方法可以将一个字符串转化为一个字符数组。
例:
package javaProject001;//包名
public class StringToArray {//创建类
public static void main(String[] args) {//主方法
String str = "这是一个字符串";//创建字符串对象
char[] ch = str.toCharArray();//将字符串转化为字符数组
for (int i = 0;i<ch.length;i++) {//遍历字符数组
System.out.println("数组第"+ i +"个元素为:"+ ch[i]);//输出数组的元素
}
}
}
运行结果如下:
package javaProject001;//包名
public class StringToArray {//创建类
public static void main(String[] args) {//主方法
String str = "这是一个字符串";//创建字符串对象
char[] ch = str.toCharArray();//将字符串转化为字符数组
for (int i = 0;i<ch.length;i++) {//遍历字符数组
System.out.println("数组第"+ i +"个元素为:"+ ch[i]);//输出数组的元素
}
}
}
运行结果如下:
语法如下:
str.toCharArray();//此方法使用格式
其中,str表示任意字符串。
str.toCharArray();//此方法使用格式
其中,str表示任意字符串。
5.3.6 判断子字符串是否存在
contains()方法可以判断字符串中是否包括指定的内容
例:
package javaProject001;//包名
public class zszszsxd {//创建类
public static void main(String[] args) {//主方法
String a = "今日的菜单有:蒸羊羔,蒸熊掌,蒸鹿尾,烤花鸭,烧雏鸡,烧子鹅,卤煮咸鸭,酱鸡,腊肉,松花小肚";//创建字符串对象
System.out.println(a);//输出字符串
boolean request = a.contains("腊肉");//判断字符串中是否有“腊肉”的字样
System.out.println("今天有腊肉吗?" +request);//输出内容
boolean request1 = a.contains("汉堡");//判断字符串中是否有“汉堡”的字样
System.out.println("今天有汉堡吗?" + request1);//输出内容
}
}
运行结果如下:
package javaProject001;//包名
public class zszszsxd {//创建类
public static void main(String[] args) {//主方法
String a = "今日的菜单有:蒸羊羔,蒸熊掌,蒸鹿尾,烤花鸭,烧雏鸡,烧子鹅,卤煮咸鸭,酱鸡,腊肉,松花小肚";//创建字符串对象
System.out.println(a);//输出字符串
boolean request = a.contains("腊肉");//判断字符串中是否有“腊肉”的字样
System.out.println("今天有腊肉吗?" +request);//输出内容
boolean request1 = a.contains("汉堡");//判断字符串中是否有“汉堡”的字样
System.out.println("今天有汉堡吗?" + request1);//输出内容
}
}
运行结果如下:
语法如下:
str.contains (String);//该方法的使用方式
解释说明:
str:任意字符串。
String:查询的子字符串。
str.contains (String);//该方法的使用方式
解释说明:
str:任意字符串。
String:查询的子字符串。
5.4 字符串的操作
5.4.1 截取字符串
1.subString(int bginIndex)
该方法返回一个新的字符串,它是此字符串的一个子字符串。该字符串从指定索引处的字符开始,直到此字符串末尾。
该方法返回一个新的字符串,它是此字符串的一个子字符串。该字符串从指定索引处的字符开始,直到此字符串末尾。
例:
package javaProject001;//包名
public class StringSub {//创建类
public static void main(String[] args) {//主方法
String str = "为革命保护视力,眼保健操开始。";//创建字符串对象
String substr = str.substring(8);//从第八位截取字符串
System.out.println("字符串str的后半句是:"+ substr);//输出内容
}
}
运行结果如下:
package javaProject001;//包名
public class StringSub {//创建类
public static void main(String[] args) {//主方法
String str = "为革命保护视力,眼保健操开始。";//创建字符串对象
String substr = str.substring(8);//从第八位截取字符串
System.out.println("字符串str的后半句是:"+ substr);//输出内容
}
}
运行结果如下:
语法如下:
str.substring(beginIndex);//此方法的使用方式
解释说明:
str:任意字符串。
beeginIndex:起始索引(包括)。
str.substring(beginIndex);//此方法的使用方式
解释说明:
str:任意字符串。
beeginIndex:起始索引(包括)。
2. subString(int beginIndex,int endIndex)
该方法返回一个新字符串,它是此字符串的一个子字符串。该子字符串从指定的 beginIndex 开始,直到索引 endIndex-1处的字符。
该方法返回一个新字符串,它是此字符串的一个子字符串。该子字符串从指定的 beginIndex 开始,直到索引 endIndex-1处的字符。
例:
package javaProject001;//包名
public class StringSub2 {//创建类
public static void main(String[] args) {//主方法
String str = "闭门造车,出门踩屎。";//创建字符串对象
String substr = str.substring(0,4);//从0开始截取值4-1索引位置的子字符串
System.out.println("字符串str的前半句是:" + substr);//输出内容
}
}
运行结果如下:
package javaProject001;//包名
public class StringSub2 {//创建类
public static void main(String[] args) {//主方法
String str = "闭门造车,出门踩屎。";//创建字符串对象
String substr = str.substring(0,4);//从0开始截取值4-1索引位置的子字符串
System.out.println("字符串str的前半句是:" + substr);//输出内容
}
}
运行结果如下:
语法如下:
str.substring(beginIndex,endIndex);//该方法的使用方式
解释说明:
str:任意字符串。
beginIndex:开始索引(包括)。
endIndex:结束索引(不包括)。
str.substring(beginIndex,endIndex);//该方法的使用方式
解释说明:
str:任意字符串。
beginIndex:开始索引(包括)。
endIndex:结束索引(不包括)。
5.4.2 字符串替换
1. replace(CharSequence target,CharSequence repalcement)
该方法可以实现将指定的字符替换成新的字符序列。CharSequence 是一个接口,代表一个可读的字符序列,String、StringBuffer、StringBuilder 都实现了这个接口,所以可以直接将字符串当成参数。
该方法可以实现将指定的字符替换成新的字符序列。CharSequence 是一个接口,代表一个可读的字符序列,String、StringBuffer、StringBuilder 都实现了这个接口,所以可以直接将字符串当成参数。
例:
package javaProject001;//包名
public class Stringreplace {//创建类
public static void main(String[] args) {//主方法
String str = "明月几时有,把酒问青天。";//创建字符串对象
String restr = str.replace("月", "日");//将str中的“月”全部替换成“日”
System.out.println("字符串str替换后的效果:"+restr);//输出内容
}
}
运行结果如下:
package javaProject001;//包名
public class Stringreplace {//创建类
public static void main(String[] args) {//主方法
String str = "明月几时有,把酒问青天。";//创建字符串对象
String restr = str.replace("月", "日");//将str中的“月”全部替换成“日”
System.out.println("字符串str替换后的效果:"+restr);//输出内容
}
}
运行结果如下:
注意:
如果要替换的字符oldstr在字符串中重复出现多次,replace)方法会将所有oldstr全部替换成newstr。例如 String str = "java project";
String str2 = str.replace("j","J");此时,str2 的值为Java proJecto
需要注意的是,要替换的字符oldstr的大小写要与原字符串中字符的大小写保持一致,否则不能成
功地替换例如,上面的实例如果写成如下语句,则不能成功替换。
String str = "java project";
String str3 = str.replace("P","t");
如果要替换的字符oldstr在字符串中重复出现多次,replace)方法会将所有oldstr全部替换成newstr。例如 String str = "java project";
String str2 = str.replace("j","J");此时,str2 的值为Java proJecto
需要注意的是,要替换的字符oldstr的大小写要与原字符串中字符的大小写保持一致,否则不能成
功地替换例如,上面的实例如果写成如下语句,则不能成功替换。
String str = "java project";
String str3 = str.replace("P","t");
语法如下:
str.replace(oldstr,newstr);//该方法的使用方式
解释说明:
str:任意字符串。
oldstr:要被替换的字符序列。
newstr:替换后的字符序列。
replcace()方法返回的是一个新的字符串,如果字符串str中没有找到需要被替换的子字符序列oldstr,则将原字符串返回。
str.replace(oldstr,newstr);//该方法的使用方式
解释说明:
str:任意字符串。
oldstr:要被替换的字符序列。
newstr:替换后的字符序列。
replcace()方法返回的是一个新的字符串,如果字符串str中没有找到需要被替换的子字符序列oldstr,则将原字符串返回。
2.replaceAll(String regex,String replacement)
该方法可以实现将指定的字符串替换成新的字符串,支持正则表达式。
该方法可以实现将指定的字符串替换成新的字符串,支持正则表达式。
例如,“ild”示数字0-9中的任何一个,“\ld”就是元字符
例:分别使用replace0方法和replaceA110方法,利用正则表达式将字符串中所有的数字的
换成“?”。
package javaProject001;//包名
public class StringReplaceAll {//创建类
public static void main(String[] args) {//主方法
String str = "0123456789abc\\d";//创建字符串对象
String restr = str.replace("\\d", "?");//使用replace()将符合"\\d"的表达式字符串替换“?”
String restrAll = str.replaceAll("\\d","?");//使用replace()将符合"\\d"的表达式字符串替换“?”
//输出结果
System.out.println("字符串str:"+str);//输出结果
System.out.println("使用replace()替换的结果:"+restr);//输出结果
System.out.println("使用replaceAll()替换的结果:"+restrAll);//输出结果
}
}
运行结果如下:
例:分别使用replace0方法和replaceA110方法,利用正则表达式将字符串中所有的数字的
换成“?”。
package javaProject001;//包名
public class StringReplaceAll {//创建类
public static void main(String[] args) {//主方法
String str = "0123456789abc\\d";//创建字符串对象
String restr = str.replace("\\d", "?");//使用replace()将符合"\\d"的表达式字符串替换“?”
String restrAll = str.replaceAll("\\d","?");//使用replace()将符合"\\d"的表达式字符串替换“?”
//输出结果
System.out.println("字符串str:"+str);//输出结果
System.out.println("使用replace()替换的结果:"+restr);//输出结果
System.out.println("使用replaceAll()替换的结果:"+restrAll);//输出结果
}
}
运行结果如下:
代码注解:
从这个运行结果可以直观地看出,replace()方法不知道"lld"表达式代表的含义,只是将"lld"当成一个子字符串在str中替换成了"?";而replaceA110知道正则表达式的含义,将所有的数字替换成了"?",但对于字符串中出现的子字符串"lld"没有做任何操作。
从这个运行结果可以直观地看出,replace()方法不知道"lld"表达式代表的含义,只是将"lld"当成一个子字符串在str中替换成了"?";而replaceA110知道正则表达式的含义,将所有的数字替换成了"?",但对于字符串中出现的子字符串"lld"没有做任何操作。
语法如下:
str.replaceAll(regex,replacement);//该方法的使用方式
解释说明:
str:任意字符串。
regex:被替换的字符串或正则表达式。
replacement:替换后的字符串
则表达式是含有一些具有特殊意义字符的字符串,这些特殊字符称为正则表达式的元字符。
str.replaceAll(regex,replacement);//该方法的使用方式
解释说明:
str:任意字符串。
regex:被替换的字符串或正则表达式。
replacement:替换后的字符串
则表达式是含有一些具有特殊意义字符的字符串,这些特殊字符称为正则表达式的元字符。
3. replaceFirst(String regex,String replacement)
该方法可以实现将第一个指定的字符串替换成新的字符串,支持正则表达式。
该方法可以实现将第一个指定的字符串替换成新的字符串,支持正则表达式。
例5.18 现有字符串"8I want to marry you,so I need you!",去掉第一个数字,再把第一次出现的"you"替换成"her"。
package javaProject001;//包名
public class StringReplaceFirst {//创建类
public static void main(String[] args) {//主方法
String str = "8I want to marry you, so I need you!";//创建字符串对象
String noNumber = str.replaceFirst("\\d", "");//将开头的数字替换成两个双引号“”
String youToHer = noNumber.replaceFirst("you", "her");//将第一次出现的“you”替换成“her”
System.out.println("替换之后的结果是:" +youToHer);//输出结果
}
}
运行结果如下:
package javaProject001;//包名
public class StringReplaceFirst {//创建类
public static void main(String[] args) {//主方法
String str = "8I want to marry you, so I need you!";//创建字符串对象
String noNumber = str.replaceFirst("\\d", "");//将开头的数字替换成两个双引号“”
String youToHer = noNumber.replaceFirst("you", "her");//将第一次出现的“you”替换成“her”
System.out.println("替换之后的结果是:" +youToHer);//输出结果
}
}
运行结果如下:
str.replaceFirst(regex,replacement);//该方法的使用方式
解释说明:
str:任意字符串。
regex:第一个被替换的字符串或正则表达式。
replacement:替换后的字符串。
解释说明:
str:任意字符串。
regex:第一个被替换的字符串或正则表达式。
replacement:替换后的字符串。
5.4.3 字符串分割
1. split (String regex)
该方法可根据给定的分隔符对字符串进行拆分,支持正则表达式,最后返回一个字符串数组。
该方法可根据给定的分隔符对字符串进行拆分,支持正则表达式,最后返回一个字符串数组。
例:创建一个字符串,用“,”分割
package javaProject001;//包名
public class StringSplit {//创建类
public static void main(String[] args) {//主方法
String str = "从前有座山,山里有个庙,庙里有个小松鼠。";//创建字符串对象
String[] strArray = str.split(",");//让字符串按照“,”进行分割
for (int i = 0; i<strArray.length;i++)//使用for循环,循环输出数字所有元素
{
System.out.println("数组第" + i + "索引的元素是:" +strArray[i]);//输出内容
}
}
}
运行结果如下:
package javaProject001;//包名
public class StringSplit {//创建类
public static void main(String[] args) {//主方法
String str = "从前有座山,山里有个庙,庙里有个小松鼠。";//创建字符串对象
String[] strArray = str.split(",");//让字符串按照“,”进行分割
for (int i = 0; i<strArray.length;i++)//使用for循环,循环输出数字所有元素
{
System.out.println("数组第" + i + "索引的元素是:" +strArray[i]);//输出内容
}
}
}
运行结果如下:
语法如下:
str.split(regex);//该方法的使用方式
解释说明:
str:任意字符串。
regex:分隔符表达式。
str.split(regex);//该方法的使用方式
解释说明:
str:任意字符串。
regex:分隔符表达式。
如果想定义多个分隔符,可以使用符号“|”。如果用“|”分割字符串,需要用到转义字符“\\|”。
例:同时使用不同的分隔符分割同一个字符串。
package javaProject001;//包名
public class StringSplit2 {//创建类
public static void main(String[] args) {//主方法
String str = "a1b2,c,d e f|gh";//创建字符串对象
String[] a1 = str.split(",");//使用“,”分隔
String[] a2 = str.split(" ");//使用“ ”分隔
String[] a3 = str.split("\\|");//使用“|”分隔
String[] a4 = str.split("\\d");//使用正则表达式分割,本行用数字分割
String[] a5 = str.split(",| |\\||\\d");//同时使用“,”、“空格”、“|”、数字分割,用“|”连接所有分隔符
System.out.println("str的原值:"+str);//显示str原值
System.out.println("使用\",\"分割:");//输出内容
for(String b:a1) {//使用for-each循环展示结果
System.out.print("["+b+"]");//输出,分割后的结果
}
System.out.println();//换行
System.out.println("使用空格分割:");//输出内容
for(String b:a2) {//使用for-each循环展示结果
System.out.print("["+b+"]");//输出,分割后的结果
}
System.out.println();//换行
System.out.println("使用\"|\"分割:");
for(String b:a3) {//使用for-each循环展示结果
System.out.print("["+b+"]");//输出,分割后的结果
}
System.out.println();//换行
System.out.println("使用数字分割:");
for(String b:a4) {//使用for-each循环展示结果
System.out.print("["+b+"]");//输出,分割后的结果
}
System.out.println();//换行
System.out.println("同时使用所有分隔符:");//使用for-each循环展示数字分割结果
for(String b:a5) {//使用for-each循环展示结果
System.out.print("["+b+"]");//输出,分割后的结果
}
System.out.println();//换行
}
}
运行结果如下:
package javaProject001;//包名
public class StringSplit2 {//创建类
public static void main(String[] args) {//主方法
String str = "a1b2,c,d e f|gh";//创建字符串对象
String[] a1 = str.split(",");//使用“,”分隔
String[] a2 = str.split(" ");//使用“ ”分隔
String[] a3 = str.split("\\|");//使用“|”分隔
String[] a4 = str.split("\\d");//使用正则表达式分割,本行用数字分割
String[] a5 = str.split(",| |\\||\\d");//同时使用“,”、“空格”、“|”、数字分割,用“|”连接所有分隔符
System.out.println("str的原值:"+str);//显示str原值
System.out.println("使用\",\"分割:");//输出内容
for(String b:a1) {//使用for-each循环展示结果
System.out.print("["+b+"]");//输出,分割后的结果
}
System.out.println();//换行
System.out.println("使用空格分割:");//输出内容
for(String b:a2) {//使用for-each循环展示结果
System.out.print("["+b+"]");//输出,分割后的结果
}
System.out.println();//换行
System.out.println("使用\"|\"分割:");
for(String b:a3) {//使用for-each循环展示结果
System.out.print("["+b+"]");//输出,分割后的结果
}
System.out.println();//换行
System.out.println("使用数字分割:");
for(String b:a4) {//使用for-each循环展示结果
System.out.print("["+b+"]");//输出,分割后的结果
}
System.out.println();//换行
System.out.println("同时使用所有分隔符:");//使用for-each循环展示数字分割结果
for(String b:a5) {//使用for-each循环展示结果
System.out.print("["+b+"]");//输出,分割后的结果
}
System.out.println();//换行
}
}
运行结果如下:
5.4.4 大小写转换
1. toLowerCase()
该方法将String转换为小写,如果字符串中没有应被转换的字符,则将原字符串返回;否则将返回一个新的字符串,将原字符串中每个可进行小写转换的字符都转换成等价的小写字符,字符串长度与原字符串长度相同。
该方法将String转换为小写,如果字符串中没有应被转换的字符,则将原字符串返回;否则将返回一个新的字符串,将原字符串中每个可进行小写转换的字符都转换成等价的小写字符,字符串长度与原字符串长度相同。
例:将字符串“abc DEF”分别用大写、小写两种格式输出。
package javaProject001;//包名
public class StringTransform {//创建类
public static void main(String[] args) {//主方法
String str = "abc DEF";//创建字符串对象
System.out.println(str.toLowerCase());//按照小写格式输出
System.out.println(str.toUpperCase());//按照大写格式输出
}
}
运行结果如下:
package javaProject001;//包名
public class StringTransform {//创建类
public static void main(String[] args) {//主方法
String str = "abc DEF";//创建字符串对象
System.out.println(str.toLowerCase());//按照小写格式输出
System.out.println(str.toUpperCase());//按照大写格式输出
}
}
运行结果如下:
语法如下:
str.toLowerCase();//该方法的使用方式
其中 str代表任意字符串。
str.toLowerCase();//该方法的使用方式
其中 str代表任意字符串。
2. toUpperCase()
该方法将String转换为大写,如果字符串中没有应被转换的字符,则将原字符串返回;否则将返回一个新的字符串,将原字符串中每个可进行大写转换的字符都转换成等价的大写字符,字符串长度与原字符串长度相同。
该方法将String转换为大写,如果字符串中没有应被转换的字符,则将原字符串返回;否则将返回一个新的字符串,将原字符串中每个可进行大写转换的字符都转换成等价的大写字符,字符串长度与原字符串长度相同。
语法如下:
str.toUpperCase();//该方法的使用方式
其中 str代表任意字符串。
str.toUpperCase();//该方法的使用方式
其中 str代表任意字符串。
5.4.5 去除空白内容
trim()方法可以返回字符串的副本,忽略首尾处空白。语法如下:
str.trim();//该方法的使用方式
其中str代表任意字符串。
str.trim();//该方法的使用方式
其中str代表任意字符串。
例:使用trim()方法去掉字符串两边的空白内容。
package javaProject001;//包名
public class StringTrim {//创建类
public static void main(String[] args) {//主方法
String str = " abc ";//创建字符串对象
String shortStr = str.trim();//使用trim()方法 处
System.out.println("str的原值是:["+str+"]");//输出str的原值
System.out.println("去掉首尾空白的值:["+ shortStr +"]");//输出去除空白后的值
}
}
运行结果如下:
package javaProject001;//包名
public class StringTrim {//创建类
public static void main(String[] args) {//主方法
String str = " abc ";//创建字符串对象
String shortStr = str.trim();//使用trim()方法 处
System.out.println("str的原值是:["+str+"]");//输出str的原值
System.out.println("去掉首尾空白的值:["+ shortStr +"]");//输出去除空白后的值
}
}
运行结果如下:
5.4.6 比较字符串是否相等
对字符串对象进行比较不能简单的使用比较运算符“==”,因为比较运算符比较的是两个字符串的内存地址是否相同,因为即使两个字符串的文本值相同,两个对象的内存地址也可能不同,所以使用比较运算符会返回false.
例:使用比较运算符计较两个字符串。
package javaProject001;//包名
public class StringCompare {//创建类
public static void main(String[] args) {//主方法
String a,b;//引入字符串常量
a = "I am a student";//给a赋值
b = "I am a student";//给b赋值
System.out.println("直接引入字符串常量的比较结果:"+ (a==b));//直接引入字符串常量的比较
a = new String("I am a student");//使用new创建对象
b = new String("I am a student");//使用new创建对象
System.out.println("使用new创建对象的比较结果:"+ (a==b));//使用new创建对象的比较
}
}
运行结果如下:
package javaProject001;//包名
public class StringCompare {//创建类
public static void main(String[] args) {//主方法
String a,b;//引入字符串常量
a = "I am a student";//给a赋值
b = "I am a student";//给b赋值
System.out.println("直接引入字符串常量的比较结果:"+ (a==b));//直接引入字符串常量的比较
a = new String("I am a student");//使用new创建对象
b = new String("I am a student");//使用new创建对象
System.out.println("使用new创建对象的比较结果:"+ (a==b));//使用new创建对象的比较
}
}
运行结果如下:
5.4.7 格式化字符串
(1) format(String format,Object...args)
语法如下:
str.format(String format,Object ...args)//该方法的使用方式
解释说明:
format:格式化字符串。
args :格式字符串中由格式说明符引用的参数。如果还有格式说明符以外的参数,则忽略这些额外的参数。此参数的数目是可变的,可为0。
该方法使用指定的格式字符串和参数返回一个格式化字符串,格式化后的新字符串使用本地默认的语言环境。
语法如下:
str.format(String format,Object ...args)//该方法的使用方式
解释说明:
format:格式化字符串。
args :格式字符串中由格式说明符引用的参数。如果还有格式说明符以外的参数,则忽略这些额外的参数。此参数的数目是可变的,可为0。
(2)format(Local 1,String format,Object...args)
1:格式化过程中要应用的语言环境。如果1为null,则不进行本地化。
format:格式化字符串。。
args:格式化字符串中有格式说明符引用的参数。如果还有格式说明符以外的参数,则忽略这些额外的参数。此参数的数目是可变的,可为0。
format:格式化字符串。。
args:格式化字符串中有格式说明符引用的参数。如果还有格式说明符以外的参数,则忽略这些额外的参数。此参数的数目是可变的,可为0。
常规类型格式化
常规类型格式化可应用于他人和类型参数,可以通过下表的转换符来实现。
常规类型格式化可应用于他人和类型参数,可以通过下表的转换符来实现。
5.5 可变字符串
5.5.1 StringBuffer类的常用方法
StringBuffer sbf=new StringBuffer();//创建StringBuffer对象
StringBuffer sbf=new StringBuffer("abc");//创建对象并传入值
StringBuffer sbf=new StringBuffer(32);//创建对象并传入值
StringBuffer sbf=new StringBuffer();//创建StringBuffer对象
StringBuffer sbf=new StringBuffer("abc");//创建对象并传入值
StringBuffer sbf=new StringBuffer(32);//创建对象并传入值
2.append()方法
将参数转换成字符串,将所有字符串中的字符追加到此序列中。
str.append(obj);//该方法的使用方法
解释说明:
sbf:任意StringBuffer对象
obj:任意数据类型的对象,使append()方法都转变成字符串的表示形式。
public static void main(String[] args) {
StringBuffer sbf=new StringBuffer("门前大桥下,");//创建StringBuffer对象
sbf.append("游过一群鸭,");//追加字符串常量
StringBuffer tmp=new StringBuffer("快来快来数一数,");//追加StringBuffer对象
sbf.append(tmp);//追加字符串常量
int x=24678;//定义一个整型常量
sbf.append(x);//追加字符串常量
System.out.println(sbf.toString());//输出
}
将参数转换成字符串,将所有字符串中的字符追加到此序列中。
str.append(obj);//该方法的使用方法
解释说明:
sbf:任意StringBuffer对象
obj:任意数据类型的对象,使append()方法都转变成字符串的表示形式。
public static void main(String[] args) {
StringBuffer sbf=new StringBuffer("门前大桥下,");//创建StringBuffer对象
sbf.append("游过一群鸭,");//追加字符串常量
StringBuffer tmp=new StringBuffer("快来快来数一数,");//追加StringBuffer对象
sbf.append(tmp);//追加字符串常量
int x=24678;//定义一个整型常量
sbf.append(x);//追加字符串常量
System.out.println(sbf.toString());//输出
}
3.setCharAt(int index,char ch)方法
将给定索引处的字符修改成ch.
sbf.setCharAt(index,ch);//该方法的使用方法
解释说明:
sbf:任意StringBuffer对象
index:被替换字符的索引
替换后的字符
public static void main(String[] args) {
StringBuffer sbf=new StringBuffer("0123456");//创建StringBuffer对象
System.out.println("sbf的原值是:"+sbf);//输出信息
sbf.setCharAt(3, 'A');//将索引为3的字符改成‘A’
System.out.println("修改后的值是:"+sbf);//输出信息
}
将给定索引处的字符修改成ch.
sbf.setCharAt(index,ch);//该方法的使用方法
解释说明:
sbf:任意StringBuffer对象
index:被替换字符的索引
替换后的字符
public static void main(String[] args) {
StringBuffer sbf=new StringBuffer("0123456");//创建StringBuffer对象
System.out.println("sbf的原值是:"+sbf);//输出信息
sbf.setCharAt(3, 'A');//将索引为3的字符改成‘A’
System.out.println("修改后的值是:"+sbf);//输出信息
}
4.insert(int offset,String str)方法
将字符串插入此字符序列中
sbf.insert(offset,str);//该方法的使用方法
解释说明:
sbf:任意StringBuffer对象
offset:插入的索引
str:插入的字符串
public class test35 {
public static void main(String[] args) {
StringBuffer sbf=new StringBuffer("0123456");//创建StringBuffer对象
System.out.println("sbf的原值为:"+sbf);//输出信息
sbf=sbf.insert(5, "F");//在索引为5的位置插入“F”,将返回值赋给sbf自己
System.out.println("修改之后的值为:"+sbf);//输出信息
}
}
将字符串插入此字符序列中
sbf.insert(offset,str);//该方法的使用方法
解释说明:
sbf:任意StringBuffer对象
offset:插入的索引
str:插入的字符串
public class test35 {
public static void main(String[] args) {
StringBuffer sbf=new StringBuffer("0123456");//创建StringBuffer对象
System.out.println("sbf的原值为:"+sbf);//输出信息
sbf=sbf.insert(5, "F");//在索引为5的位置插入“F”,将返回值赋给sbf自己
System.out.println("修改之后的值为:"+sbf);//输出信息
}
}
5.reverse()方法
sbf.reverse();//该方法的使用方法
例:
public static void main(String[] args) {
StringBuffer sbf=new StringBuffer("同一个世界,同一个梦想");//创建一个StringBuffer对象
System.out.println("sbf的原值为:"+sbf);//输出信息
sbf=sbf.reverse();//将字符序列sbf反转
System.out.println("修改之后的值为:"+sbf);//输出信息
}
sbf.reverse();//该方法的使用方法
例:
public static void main(String[] args) {
StringBuffer sbf=new StringBuffer("同一个世界,同一个梦想");//创建一个StringBuffer对象
System.out.println("sbf的原值为:"+sbf);//输出信息
sbf=sbf.reverse();//将字符序列sbf反转
System.out.println("修改之后的值为:"+sbf);//输出信息
}
6.delete(int start,int end)方法
sbf.delete(start,end);
sbf:任意StringBuffer对象
start:起始索引
end:结束索引
例:
public static void main(String[] args) {
StringBuffer sbf=new StringBuffer("天行健,君子以自强不息");//创建StringBuffer对象
System.out.println("sbf的原值为:"+sbf);//输出信息
sbf=sbf.delete(4, 7);//删除从索引4开始至索引7之前的内容
System.out.println("删除之后的值为:"+sbf);//输出信息
}
sbf.delete(start,end);
sbf:任意StringBuffer对象
start:起始索引
end:结束索引
例:
public static void main(String[] args) {
StringBuffer sbf=new StringBuffer("天行健,君子以自强不息");//创建StringBuffer对象
System.out.println("sbf的原值为:"+sbf);//输出信息
sbf=sbf.delete(4, 7);//删除从索引4开始至索引7之前的内容
System.out.println("删除之后的值为:"+sbf);//输出信息
}
5.5.2 StringBuilder类的使用方法
public static void main(String[] args) {
StringBuffer sbd=new StringBuffer();//创建一个StringBuffer对象
System.out.println("sbd的原值为空");//输出信息
sbd.append("我是StringBuffer类");//追加字符串
System.out.println("sbd追加字符串:"+sbd);//输出信息
int length=sbd.length();//获取sbd字符串的长度
System.out.println("sbd的长度为:"+length);//输出信息
sbd=sbd.insert(length-1, "123456");//插入字符串
System.out.println("插入字符串:"+sbd);//输出
sbd=sbd.delete(sbd.length()-1,sbd.length());//删除字符串
System.out.println("删除最后一个字:"+sbd);//输出
sbd=sbd.reverse();//反序输出
System.out.println("反序输出:"+sbd);//输出
}
StringBuffer sbd=new StringBuffer();//创建一个StringBuffer对象
System.out.println("sbd的原值为空");//输出信息
sbd.append("我是StringBuffer类");//追加字符串
System.out.println("sbd追加字符串:"+sbd);//输出信息
int length=sbd.length();//获取sbd字符串的长度
System.out.println("sbd的长度为:"+length);//输出信息
sbd=sbd.insert(length-1, "123456");//插入字符串
System.out.println("插入字符串:"+sbd);//输出
sbd=sbd.delete(sbd.length()-1,sbd.length());//删除字符串
System.out.println("删除最后一个字:"+sbd);//输出
sbd=sbd.reverse();//反序输出
System.out.println("反序输出:"+sbd);//输出
}
5.5.3 StringBuffer、StringBuilder、String 之间的关系
类名 对象类型 执行效率 线程安全性
String 指向另外的空间 常量 慢 不安全
StringBuffer 指向在原来的基础上添加 变量 中 有锁 安全
Stringbuilder 在原来的基础上添加 变量 快 无 锁 不安全
类名 对象类型 执行效率 线程安全性
String 指向另外的空间 常量 慢 不安全
StringBuffer 指向在原来的基础上添加 变量 中 有锁 安全
Stringbuilder 在原来的基础上添加 变量 快 无 锁 不安全
第六章 面向对象编程基础
面向对象概述
对象
在面向对象中,类和对象是最基本、最重要的组成单元。类实际上是表示一个客观世界某类群体的一些基本特征抽象。对象就是表示一个个具体的东西。所以说类是对象的抽象,对象是类的具体。
类
类是实体对象的概念模型,因此通常是笼统的、不具体的。关于类和对象,初学者在理解上是存在一定难度的。
类是 Java 中的一种重要的引用数据类型,也是组成 Java 程序的基本要素,因为所有的 Java 程序都是基于类的
类是 Java 中的一种重要的引用数据类型,也是组成 Java 程序的基本要素,因为所有的 Java 程序都是基于类的
面向对象程序设计的特点
类是实体对象的概念模型,因此通常是笼统的、不具体的。关于类和对象,初学者在理解上是存在一定难度的。
类是 Java 中的一种重要的引用数据类型,也是组成 Java 程序的基本要素,因为所有的 Java 程序都是基于类的
类是 Java 中的一种重要的引用数据类型,也是组成 Java 程序的基本要素,因为所有的 Java 程序都是基于类的
类与对象
成员变量
在java中对象的属性称为成员变量
数据类型 变量名称 [=值];
数据类型 变量名称 [=值];
成员方法
在java语言中,成员方法对于类对象的行为,它主要用来定义类可执行的操作,它是包含一系列语句的代码块。
成员方法的定义
[权限修饰符] [返回值类型] 方法名 ([参数类型 参数名]) [throws 异常类型]{
...//方法体
return 返回值;
}
成员方法的定义
[权限修饰符] [返回值类型] 方法名 ([参数类型 参数名]) [throws 异常类型]{
...//方法体
return 返回值;
}
构造方法
在类中除了成员方法之外,还存在一种特殊类型的方法,那就是构造方法。构造方法是一个与类同名的方法,对象的创建就是通过构造方法完成的。
构造方法的特点如下:
(1)构造方法没有返回类型,也不能定义为void。
(2)构造方法的名称要与本类的名称相同。
(3)构造方法的主要作用是完成对象的初始化工作,它能把定义对象的参数传给对象成员。
构造方法的特点如下:
(1)构造方法没有返回类型,也不能定义为void。
(2)构造方法的名称要与本类的名称相同。
(3)构造方法的主要作用是完成对象的初始化工作,它能把定义对象的参数传给对象成员。
局部变量
局部变量
如果在成员方法内定义一个变量,那么这个变量被称为局部变量。
局部变量在方法被执行时创建,在方法执行结束时销毁。局部变量在使用时必须进行赋值操作或则被初始化,否则会出现编译错误。
public String getName(){//定义一个getName()方法
int id=0;//局部变量
setName("java");//调用类中其他方法
return id+this.name;//设置方法返回值
如果在成员方法内定义一个变量,那么这个变量被称为局部变量。
局部变量在方法被执行时创建,在方法执行结束时销毁。局部变量在使用时必须进行赋值操作或则被初始化,否则会出现编译错误。
public String getName(){//定义一个getName()方法
int id=0;//局部变量
setName("java");//调用类中其他方法
return id+this.name;//设置方法返回值
说明:类成员变量和成员方法可以统称为类成员。如果一个方法中含有与成员变量同名的局部变量,则方法中对这个变量的访问以局部变量进行。
局部变量的有效范围
局部变量的有效范围从该变量的声明开始到该变量的结束为止。
在相互不嵌套的作用域中可以同时声明两个名称和类型相同的局部变量。但是相互嵌套不能。
局部变量的有效范围
局部变量的有效范围从该变量的声明开始到该变量的结束为止。
在相互不嵌套的作用域中可以同时声明两个名称和类型相同的局部变量。但是相互嵌套不能。
局部变量的有效范围
局部变量的有效范围从该变量的声明开始到该变量的结束为止。
在相互不嵌套的作用域中可以同时声明两个名称和类型相同的局部变量。但是相互嵌套不能。
在相互不嵌套的作用域中可以同时声明两个名称和类型相同的局部变量。但是相互嵌套不能。
对象的创建
在java语言中通过new操作符来创建对象。前文在讲解构造方法时介绍过。
语法如下:
Test test=new Test();
Test test=new Test("a");
Test:类名。
解释说明:
test:创建Test类对象
new:创建对象操作符。
a:构造方法的参数。
test对象被创建出来时,就是一个对象的引用,这个引用在内存中为对象分配了存储空间,
语法如下:
Test test=new Test();
Test test=new Test("a");
Test:类名。
解释说明:
test:创建Test类对象
new:创建对象操作符。
a:构造方法的参数。
test对象被创建出来时,就是一个对象的引用,这个引用在内存中为对象分配了存储空间,
访问对象的属性和行为
用户在使用new操作符创建一个对象后,可以使用“对象.类成员”来获取对象的属性和行为。前面提到,对象的属性和行为在类中通过类成员变量和成员方法的形式来表示,所以当对象获取类成员时,也相应地获取对象的属性和行为。
对象的销毁
每个对象都有生命的周期,当对象的生命周期结束时,分配给该对象的内存地址会被回收。在其它语言中需要手动回收废弃的对象,但在Java拥有一套完整的垃圾回收机制,用户不必担心废弃的对象占用内存,垃圾回收站将回收无用的但占用内存的资源。
何种对象会被Java虚拟机视为垃圾。
(1)对象引用超出其作用范围,这个对象将被视为垃圾
(2)将对象赋值为null。
finalize()方法可进行垃圾回收但不一定会发生
System.gc()方法强制启动垃圾回收器。
何种对象会被Java虚拟机视为垃圾。
(1)对象引用超出其作用范围,这个对象将被视为垃圾
(2)将对象赋值为null。
finalize()方法可进行垃圾回收但不一定会发生
System.gc()方法强制启动垃圾回收器。
this 的关键字
static 关键字
static关键字
由static修饰的变量、常量和方法被称作静态变量、静态常量 、静态方法,也被称为类的静态成员。静态成员是属于类所有的。区别于个别对象。
由static修饰的变量、常量和方法被称作静态变量、静态常量 、静态方法,也被称为类的静态成员。静态成员是属于类所有的。区别于个别对象。
静态变量:把共享的变量用static 修饰,该变量就是静态变量。
类名.静态类成员
类名.静态类成员
说明:当类首次被加载时,静态变量就被分配到内存中,直到程序结束才会释放。
静态常量
final static 数据类型 变量名=值;
final static 数据类型 变量名=值;
注意:给静态常量赋值时所有的字母都应该大写。
静态方法
类名.静态方法();
类名.静态方法();
静态代码块
在类中除成员方法之外,用static修饰代码块可以称之为静态代码块。定义一块静态代码块,可以完成类的初始化操作,在类声明时就会运行.
在类中除成员方法之外,用static修饰代码块可以称之为静态代码块。定义一块静态代码块,可以完成类的初始化操作,在类声明时就会运行.
说明:
(1)静态代码块由始至终只运行一次
(2)非静态代码块,每创建对象时候,会在构造方法之前运行。所以读取成员变量时,只能获取到默认值null。
(1)静态代码块由始至终只运行一次
(2)非静态代码块,每创建对象时候,会在构造方法之前运行。所以读取成员变量时,只能获取到默认值null。
类的主方法
public static void main(String[]args){
//方法体
}
说明:
(1)主方法是静态的,所以如要直接在主方法中调用其他方法,则该方法必须是静态的。
(2)主方法没有返回值。
(3)主方法的形参为数组。其中args[0]~args[n]分别代表程序的第一个参数到第n+1个参数,可以使用args.length获取参数的个数。
public static void main(String[]args){
//方法体
}
说明:
(1)主方法是静态的,所以如要直接在主方法中调用其他方法,则该方法必须是静态的。
(2)主方法没有返回值。
(3)主方法的形参为数组。其中args[0]~args[n]分别代表程序的第一个参数到第n+1个参数,可以使用args.length获取参数的个数。
第七章 面向对象核心技术
类的封装
封装将类的某些信息隐藏在类内部,不允许外部程序直接访问,只能通过该类提供的方法来实现对隐藏信息的操作和访问。例如:一台计算机内部极其复杂,有主板、CPU、硬盘和内存, 而一般用户不需要了解它的内部细节,不需要知道主板的型号、CPU 主频、硬盘和内存的大小,于是计算机制造商将用机箱把计算机封装起来,对外提供了一些接口,如鼠标、键盘和显示器等,这样当用户使用计算机就非常方便。
封装的特点:
只能通过规定的方法访问数据。
隐藏类的实例细节,方便修改和实现。
实现封装的具体步骤如下:
修改属性的可见性来限制对属性的访问,一般设为 private。
为每个属性创建一对赋值(setter)方法和取值(getter)方法,一般设为 public,用于属性的读写。
在赋值和取值方法中,加入属性控制语句(对属性值的合法性进行判断)。
封装将类的某些信息隐藏在类内部,不允许外部程序直接访问,只能通过该类提供的方法来实现对隐藏信息的操作和访问。例如:一台计算机内部极其复杂,有主板、CPU、硬盘和内存, 而一般用户不需要了解它的内部细节,不需要知道主板的型号、CPU 主频、硬盘和内存的大小,于是计算机制造商将用机箱把计算机封装起来,对外提供了一些接口,如鼠标、键盘和显示器等,这样当用户使用计算机就非常方便。
封装的特点:
只能通过规定的方法访问数据。
隐藏类的实例细节,方便修改和实现。
实现封装的具体步骤如下:
修改属性的可见性来限制对属性的访问,一般设为 private。
为每个属性创建一对赋值(setter)方法和取值(getter)方法,一般设为 public,用于属性的读写。
在赋值和取值方法中,加入属性控制语句(对属性值的合法性进行判断)。
类的继承
继承在面向对象开发思想中是一个非常重要的概念,它使整个程序具有一定的弹性,在程序中复用已经定义完善的类不仅可以减少软件开发周期,还可以提高软件的可维护性和可扩展性。
继承其基本思想是基于某父类的扩展,制定出一个新的子类,子类可以继承父类原有的属性和方法,也可以增加原来父类所不具备的属性和方法,或者直接重写父类中的某些方法。
继承其基本思想是基于某父类的扩展,制定出一个新的子类,子类可以继承父类原有的属性和方法,也可以增加原来父类所不具备的属性和方法,或者直接重写父类中的某些方法。
1.extends关键字
在java中,让一个类继承另一个类,用extends关键字
child extends parents//子类继承父类
注意:java中的类只支持单继承,即一个子类只能继承一个父类,类似下面的代码是错误的:
child extends parents1,parent2{
//错误的继承语法
}
注意:java中的类只支持单继承,即一个子类只能继承一个父类,类似下面的代码是错误的:
在java中,让一个类继承另一个类,用extends关键字
child extends parents//子类继承父类
注意:java中的类只支持单继承,即一个子类只能继承一个父类,类似下面的代码是错误的:
child extends parents1,parent2{
//错误的继承语法
}
注意:java中的类只支持单继承,即一个子类只能继承一个父类,类似下面的代码是错误的:
方法的重写
继承并不只是扩展父类的功能,还可以重写父类的成员方法。重写(还可以称为覆盖)就是在子类中将父类的成员方法的名称保留。重新编写成员方法的实现内容,更改成员方法的存储权限,或是修改成员方法的返回值类型 (重写父类成员方法的返回值是基于J2SE 5.0版本以上的编译器提供的新功能)。
在继承中还有一种特殊的重写方式,子类与父类的成员方法返回值、方法名称、参数类型及个数完全相同,唯一不同的是方法实现内容,这种特殊重写方式被称为重构。
注意:当重写父类的方法时,修改方法的修饰权限只能从小的范围到大的范围改变,例如,父类中的doSomething()方法的修饰权限为protected,继承后子类中的方法doSomething()的修饰权限只能修改为public,不能修改为private。
继承并不只是扩展父类的功能,还可以重写父类的成员方法。重写(还可以称为覆盖)就是在子类中将父类的成员方法的名称保留。重新编写成员方法的实现内容,更改成员方法的存储权限,或是修改成员方法的返回值类型 (重写父类成员方法的返回值是基于J2SE 5.0版本以上的编译器提供的新功能)。
在继承中还有一种特殊的重写方式,子类与父类的成员方法返回值、方法名称、参数类型及个数完全相同,唯一不同的是方法实现内容,这种特殊重写方式被称为重构。
注意:当重写父类的方法时,修改方法的修饰权限只能从小的范围到大的范围改变,例如,父类中的doSomething()方法的修饰权限为protected,继承后子类中的方法doSomething()的修饰权限只能修改为public,不能修改为private。
super关键字
super关键字可以调用父类的方法和属性,它的使用方法和this关键字相似。但this关键字代表本类的对象,super关键字带调用的是父类的方法
super.property;//调用父类的属性
super.method();//调用父类的方法
super关键字可以调用父类的方法和属性,它的使用方法和this关键字相似。但this关键字代表本类的对象,super关键字带调用的是父类的方法
super.property;//调用父类的属性
super.method();//调用父类的方法
Object类——所有类的父类
在java中,所有的类都直接或间接继承了java.lang.Object类。Object类是所有类的父类,是java类层中的最高层类。
注意:Object类中的getClass()、notify()、notifyAll()、wait()等方法不能被重写,因为这些方法被定义为final类型。
1.getClass()方法
getClass()方法是Object类定义的方法,它会返回对象执行时的Class实例,然后使用此实例调用getName ()方法可以取得类的名称。
getClass().getName();//调用getClass()里的getName()方法
可以将getClass()方法与toString()方法联合使用。
2.toString()方法
toString()方法的功能是将一个对象返回为字符串形式,它会返回一个String实例。在实际的应用中通常重写toString()方法。
public class ObjectInstance {创建类
public String toString(){//重写toString()方法
return "在"+getClass().getName()+"类中重写toString()方法";//返回值
}
public static void main(String[] args) {//主方法
System.out.println(new ObjectInstance());//调用方法并输出,打印本类对象
}
}
运行结果如下:
3.equals()方法
比较两个对象的实际内容。
class V{//自定义类V
}
public class OverWriteEquals {//创建一个方法
public static void main(String[] args) {//主方法
String s1="123";//实例化两个对象,内容相同
String s2="123";//实例化对象
System.out.println(s1.equals(s2));//使用equals()方法
V v1=new V();//实例化两个V类对象
V v2=new V();//实例化对象
System.out.println(v1.equals(v2));//使用equals()方法
}
}
运行结果如下:
在java中,所有的类都直接或间接继承了java.lang.Object类。Object类是所有类的父类,是java类层中的最高层类。
注意:Object类中的getClass()、notify()、notifyAll()、wait()等方法不能被重写,因为这些方法被定义为final类型。
1.getClass()方法
getClass()方法是Object类定义的方法,它会返回对象执行时的Class实例,然后使用此实例调用getName ()方法可以取得类的名称。
getClass().getName();//调用getClass()里的getName()方法
可以将getClass()方法与toString()方法联合使用。
2.toString()方法
toString()方法的功能是将一个对象返回为字符串形式,它会返回一个String实例。在实际的应用中通常重写toString()方法。
public class ObjectInstance {创建类
public String toString(){//重写toString()方法
return "在"+getClass().getName()+"类中重写toString()方法";//返回值
}
public static void main(String[] args) {//主方法
System.out.println(new ObjectInstance());//调用方法并输出,打印本类对象
}
}
运行结果如下:
3.equals()方法
比较两个对象的实际内容。
class V{//自定义类V
}
public class OverWriteEquals {//创建一个方法
public static void main(String[] args) {//主方法
String s1="123";//实例化两个对象,内容相同
String s2="123";//实例化对象
System.out.println(s1.equals(s2));//使用equals()方法
V v1=new V();//实例化两个V类对象
V v2=new V();//实例化对象
System.out.println(v1.equals(v2));//使用equals()方法
}
}
运行结果如下:
类的多态
类的多态性指“一种定义,多种实现”,类的多态性可以从两方面 体现:方法的重载,类的上下转型。
方法的重载:重载(不需要继承):返回参数不同、传入参数不同、 方法名相同
方法的重载:重载(不需要继承):返回参数不同、传入参数不同、 方法名相同
注意:虽然在方法的重载中可以使两个方法的返回类型不同,但只有返回类型不同不足以区分两个方法的重载,还需要通过参数的个数以及参数的类型来设置。
抽象类与接口
抽象类与抽象方法
使用抽象类和抽象方法时,需要遵守以下原则:
1、在抽象类中,可以包含抽象方法,也可以不包含抽方法,但是包含了抽象方法的类必须被定义为抽象类。
2、抽象类不能直接实例化,即使抽象类中没声明抽象方法,也不能实例化。
3、抽象类被继承后,子类需要实现其中所有的抽象方法。
4、如果继承抽象类的子类也被声明为抽象类,则可以不用实现父类中所有的抽象方法。
1、在抽象类中,可以包含抽象方法,也可以不包含抽方法,但是包含了抽象方法的类必须被定义为抽象类。
2、抽象类不能直接实例化,即使抽象类中没声明抽象方法,也不能实例化。
3、抽象类被继承后,子类需要实现其中所有的抽象方法。
4、如果继承抽象类的子类也被声明为抽象类,则可以不用实现父类中所有的抽象方法。
接口的声明及实现
接口是抽象类的延申,可以将它看作是纯粹的抽象类,接口中的所有方法都没有方法体。即全部都是抽象方法。抽象类是从多个类中抽象出来的模板,如果将这种抽象进行的更彻底,则可以提炼出一种更加特殊的“抽象类”——接口(Interface)。接口是 Java 中最重要的概念之一,它可以被理解为一种特殊的类,不同的是接口的成员没有执行体,是由全局常量和公共的抽象方法所组成。
定义接口:
public 表示接口的修饰符,当没有修饰符时,则使用默认的修饰符,此时该接口的访问权限仅局限于所属的包;
interface_name 表示接口的名称。接口名应与类名采用相同的命名规则,即如果仅从语法角度来看,接口名只要是合法的标识符即可。如果要遵守 Java 可读性规范,则接口名应由多个有意义的单词连缀而成,每个单词首字母大写,单词与单词之间无需任何分隔符。
extends 表示接口的继承关系;
interface1_name 表示要继承的接口名称;
constant_name 表示变量名称,一般是 static 和 final 型的;
returnType 表示方法的返回值类型;
parameter_list 表示参数列表,在接口中的方法是没有方法体的。
[修饰符]interface 接口名[extends 父接口名列表]{
[public] [static] [final]常量;
[public] [abstract] 方法;
}
一个类实现一个接口可以使用implements关键字
public class Parallelogram extends Quadrangle implements drawTest{
....//
}
说明:在接口中定义的任何变量都自动是static和final的,因此,在接口中定义变量时,必须进行初始化,而且,实现接口的子类不能对接口的变量重新赋值。
接口对于其声明、变量和方法都做了许多限制,这些限制作为接口的特征归纳如下:
具有 public 访问控制符的接口,允许任何类使用;没有指定 public 的接口,其访问将局限于所属的包。
方法的声明不需要其他修饰符,在接口中声明的方法,将隐式地声明为公有的(public)和抽象的(abstract)。
在 Java 接口中声明的变量其实都是常量,接口中的变量声明,将隐式地声明为 public、static 和 final,即常量,所以接口中定义的变量必须初始化。
接口没有构造方法,不能被实例化。
定义接口:
public 表示接口的修饰符,当没有修饰符时,则使用默认的修饰符,此时该接口的访问权限仅局限于所属的包;
interface_name 表示接口的名称。接口名应与类名采用相同的命名规则,即如果仅从语法角度来看,接口名只要是合法的标识符即可。如果要遵守 Java 可读性规范,则接口名应由多个有意义的单词连缀而成,每个单词首字母大写,单词与单词之间无需任何分隔符。
extends 表示接口的继承关系;
interface1_name 表示要继承的接口名称;
constant_name 表示变量名称,一般是 static 和 final 型的;
returnType 表示方法的返回值类型;
parameter_list 表示参数列表,在接口中的方法是没有方法体的。
[修饰符]interface 接口名[extends 父接口名列表]{
[public] [static] [final]常量;
[public] [abstract] 方法;
}
一个类实现一个接口可以使用implements关键字
public class Parallelogram extends Quadrangle implements drawTest{
....//
}
说明:在接口中定义的任何变量都自动是static和final的,因此,在接口中定义变量时,必须进行初始化,而且,实现接口的子类不能对接口的变量重新赋值。
接口对于其声明、变量和方法都做了许多限制,这些限制作为接口的特征归纳如下:
具有 public 访问控制符的接口,允许任何类使用;没有指定 public 的接口,其访问将局限于所属的包。
方法的声明不需要其他修饰符,在接口中声明的方法,将隐式地声明为公有的(public)和抽象的(abstract)。
在 Java 接口中声明的变量其实都是常量,接口中的变量声明,将隐式地声明为 public、static 和 final,即常量,所以接口中定义的变量必须初始化。
接口没有构造方法,不能被实例化。
多重继承
多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承。有些时候我们会认为如果系统中需要使用多重继承往往都是糟糕的设计,这个时候我们往往需要思考的不是怎么使用多重继承,而是您的设计是否存在问题.但有时候我们确实是需要实现多重继承,而且现实生活中也真正地存在这样的情况,比如遗传:我们即继承了父亲的行为和特征也继承了母亲的行为和特征。可幸的是Java是非常和善和理解我们的,它提供了两种方式让我们曲折来实现多重继承:接口和内部类。
区分抽象类与接口
抽象类与接口是java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力。他们两者之间对抽象概念的支持有很大的相似,甚至可以互换,但是也有区别。 尽管抽象类和接口之间存在较大的相同点,甚至有时候还可以互换,但这样并不能弥补他们之间的差异之处。下面将从语法层次和设计层次两个方面对抽象类和接口进行阐述。
控制访问
访问控制符
在 Java 语言中提供了多个作用域修饰符,其中常用的有 public、private、protected、final、abstract、static、transient 和 volatile,这些修饰符有类修饰符、变量修饰符和方法修饰符。
通过使用访问控制修饰符来限制对对象私有属性的访问,可以获得 3 个重要的好处。
防止对封装数据的未授权访问。
有助于保证数据完整性。
当类的私有实现细节必须改变时,可以限制发生在整个应用程序中的“连锁反应”。
访问控制符是一组限定类、属性或方法是否可以被程序里的其他部分访问和调用的修饰符。类的访问控制符只能是空或者 public,方法和属性的访问控制符有 4 个,分别是 public、 private、protected 和 friendly,其中 friendly 是一种没有定义专门的访问控制符的默认情况。
1. private
用 private 修饰的类成员,只能被该类自身的方法访问和修改,而不能被任何其他类(包括该类的子类)访问和引用。因此,private 修饰符具有最高的保护级别。例如,设 PhoneCard 是电话卡类,电话卡都有密码,因此该类有一个密码域,可以把该类的密码域声明为私有成员。
2. friendly(默认)
如果一个类没有访问控制符,说明它具有默认的访问控制特性。这种默认的访问控制权规定,该类只能被同一个包中的类访问和引用,而不能被其他包中的类使用,即使其他包中有该类的子类。这种访问特性又称为包访问性(package private)。
同样,类内的成员如果没有访问控制符,也说明它们具有包访问性,或称为友元(friend)。定义在同一个文件夹中的所有类属于一个包,所以前面的程序要把用户自定义的类放在同一个文件夹中(Java 项目默认的包),以便不加修饰符也能运行。
3. protected
用保护访问控制符 protected 修饰的类成员可以被三种类所访问:该类自身、与它在同一个包中的其他类以及在其他包中的该类的子类。使用 protected 修饰符的主要作用,是允许其他包中它的子类来访问父类的特定属性和方法,否则可以使用默认访问控制符。
4. public
当一个类被声明为 public 时,它就具有了被其他包中的类访问的可能性,只要包中的其他类在程序中使用 import 语句引入 public 类,就可以访问和引用这个类。
说明:
类中被设定为 public 的方法是这个类对外的接口部,避免了程序的其他部分直接去操作类内的数据,实际就是数据封装思想的体现。每个 Java 程序的主类都必须是 public 类,也是基于相同的原因
在 Java 语言中提供了多个作用域修饰符,其中常用的有 public、private、protected、final、abstract、static、transient 和 volatile,这些修饰符有类修饰符、变量修饰符和方法修饰符。
通过使用访问控制修饰符来限制对对象私有属性的访问,可以获得 3 个重要的好处。
防止对封装数据的未授权访问。
有助于保证数据完整性。
当类的私有实现细节必须改变时,可以限制发生在整个应用程序中的“连锁反应”。
访问控制符是一组限定类、属性或方法是否可以被程序里的其他部分访问和调用的修饰符。类的访问控制符只能是空或者 public,方法和属性的访问控制符有 4 个,分别是 public、 private、protected 和 friendly,其中 friendly 是一种没有定义专门的访问控制符的默认情况。
1. private
用 private 修饰的类成员,只能被该类自身的方法访问和修改,而不能被任何其他类(包括该类的子类)访问和引用。因此,private 修饰符具有最高的保护级别。例如,设 PhoneCard 是电话卡类,电话卡都有密码,因此该类有一个密码域,可以把该类的密码域声明为私有成员。
2. friendly(默认)
如果一个类没有访问控制符,说明它具有默认的访问控制特性。这种默认的访问控制权规定,该类只能被同一个包中的类访问和引用,而不能被其他包中的类使用,即使其他包中有该类的子类。这种访问特性又称为包访问性(package private)。
同样,类内的成员如果没有访问控制符,也说明它们具有包访问性,或称为友元(friend)。定义在同一个文件夹中的所有类属于一个包,所以前面的程序要把用户自定义的类放在同一个文件夹中(Java 项目默认的包),以便不加修饰符也能运行。
3. protected
用保护访问控制符 protected 修饰的类成员可以被三种类所访问:该类自身、与它在同一个包中的其他类以及在其他包中的该类的子类。使用 protected 修饰符的主要作用,是允许其他包中它的子类来访问父类的特定属性和方法,否则可以使用默认访问控制符。
4. public
当一个类被声明为 public 时,它就具有了被其他包中的类访问的可能性,只要包中的其他类在程序中使用 import 语句引入 public 类,就可以访问和引用这个类。
说明:
类中被设定为 public 的方法是这个类对外的接口部,避免了程序的其他部分直接去操作类内的数据,实际就是数据封装思想的体现。每个 Java 程序的主类都必须是 public 类,也是基于相同的原因
内部类
final关键字
final 在 Java 中的意思是最终,也可以称为完结器,表示对象是最终形态的,不可改变的意思。final 应用于类、方法和变量时意义是不同的,但本质是一样的,都表示不可改变,类似 C# 里的 sealed 关键字。
使用 final 关键字声明类、变量和方法需要注意以下几点:
final 用在变量的前面表示变量的值不可以改变,此时该变量可以被称为常量。
final 用在方法的前面表示方法不可以被重写(子类中如果创建了一个与父类中相同名称、相同返回值类型、相同参数列表的方法,只是方法体中的实现不同,以实现不同于父类的功能,这种方式被称为方法重写,又称为方法覆盖。这里了解即可,教程后面我们会详细讲解)。
final 用在类的前面表示该类不能有子类,即该类不可以被继承。
final 修饰变量
final 修饰的变量即成为常量,只能赋值一次,但是 final 所修饰局部变量和成员变量有所不同。
final 修饰的局部变量必须使用之前被赋值一次才能使用。
final 修饰的成员变量在声明时没有赋值的叫“空白 final 变量”。空白 final 变量必须在构造方法或静态代码块中初始化。
注意:final 修饰的变量不能被赋值这种说法是错误的,严格的说法是,final 修饰的变量不可被改变,一旦获得了初始值,该 final 变量的值就不能被重新赋值。
final 在 Java 中的意思是最终,也可以称为完结器,表示对象是最终形态的,不可改变的意思。final 应用于类、方法和变量时意义是不同的,但本质是一样的,都表示不可改变,类似 C# 里的 sealed 关键字。
使用 final 关键字声明类、变量和方法需要注意以下几点:
final 用在变量的前面表示变量的值不可以改变,此时该变量可以被称为常量。
final 用在方法的前面表示方法不可以被重写(子类中如果创建了一个与父类中相同名称、相同返回值类型、相同参数列表的方法,只是方法体中的实现不同,以实现不同于父类的功能,这种方式被称为方法重写,又称为方法覆盖。这里了解即可,教程后面我们会详细讲解)。
final 用在类的前面表示该类不能有子类,即该类不可以被继承。
final 修饰变量
final 修饰的变量即成为常量,只能赋值一次,但是 final 所修饰局部变量和成员变量有所不同。
final 修饰的局部变量必须使用之前被赋值一次才能使用。
final 修饰的成员变量在声明时没有赋值的叫“空白 final 变量”。空白 final 变量必须在构造方法或静态代码块中初始化。
注意:final 修饰的变量不能被赋值这种说法是错误的,严格的说法是,final 修饰的变量不可被改变,一旦获得了初始值,该 final 变量的值就不能被重新赋值。
第八章 异常处理
异常概述
异常分类
系统错误
Error类及其子类通常用来描述Java运行系统中的内部错误,该类定义了常规环境下不希望由程序捕获的异常,比如:OutOfMemoryError、TreadDeath等,这些错误发生时,Java虚拟机(JVM)一般选择线程终止。
异常
子主题
捕捉处理异常
try...catch 代码块
finally 代码块
在方法中抛出异常
throws 关键字抛出异常
throw 关键字抛出异常
自定义异常
异常的使用原则
Java异常强制用户去考虑程序的强健性和安全性。异常处理不应该用来控制程序的正常其主要作用是捕获程序在运行时发生的异常并进行相应的处理。编写代码处理某个方法可能异常时,可遵循以下原则。
(1)不要过度使用异常。虽然通过异常可以增强程序的健壮性,但如果使用过多不必要的异常处理,可能会影响程序的执行效率。
(2)不要使用过于庞大的try... catch块。在一个try块中放置大量的代码,这种写法看上去“很”,但是由于try块中的代码过于庞大,业务过于复杂,会造成try块中出现异常的可能性大大W,从而导致分析异常原因的难度也大大增加。
(3)避免使用catch(Exception e)。因为如果所有异常都采用相同的处理方式,将导致无法对不异常分情况处理;另外,这种捕获方式可能将程序中的全部错误、异常捕获到,这时如果出现一让“关键”异常,可能会被“悄悄地”忽略掉。
(4)不要忽略捕捉到的异常,遇到异常一定要及时处理。
(5)如果父类抛出多个异常,则覆盖方法必须抛出相同的异常或其异常的子类,不能抛出异常。
(1)不要过度使用异常。虽然通过异常可以增强程序的健壮性,但如果使用过多不必要的异常处理,可能会影响程序的执行效率。
(2)不要使用过于庞大的try... catch块。在一个try块中放置大量的代码,这种写法看上去“很”,但是由于try块中的代码过于庞大,业务过于复杂,会造成try块中出现异常的可能性大大W,从而导致分析异常原因的难度也大大增加。
(3)避免使用catch(Exception e)。因为如果所有异常都采用相同的处理方式,将导致无法对不异常分情况处理;另外,这种捕获方式可能将程序中的全部错误、异常捕获到,这时如果出现一让“关键”异常,可能会被“悄悄地”忽略掉。
(4)不要忽略捕捉到的异常,遇到异常一定要及时处理。
(5)如果父类抛出多个异常,则覆盖方法必须抛出相同的异常或其异常的子类,不能抛出异常。
第九章 Java常用类
包装类
Integer 类
java.lang包中的Integer类、Byte类、Short类和Long类,分别将基本数据类型int、byte、short和long封装成一个类,由于这些类都是Number的子类,区别就是封装不同的数据类型,其包含的方法基本相同,所以本节以Integer类为例介绍整数包装类。
Integer类在对象中包装了一个基本数据类型int的值,该类的对象包含一个int类型的字段,此外,该类提供了许多方法,能在int类型和String类型之间互相转换,同时还提供了其他一些处理的方法和常量。
1.构造方法
该方法以一个int型变量作为参数来获取Integer对象。
Integer number=new Integer(7);//创建一个对象
2.Integer(String str)
该方法以一个String型变量作为参数来获取Integer对象
注意:如果要使用字符串变量创建Integer对象,字符串变量的值一定要是数值型,如"123",否则将会抛出NumberFormatException异常
java.lang包中的Integer类、Byte类、Short类和Long类,分别将基本数据类型int、byte、short和long封装成一个类,由于这些类都是Number的子类,区别就是封装不同的数据类型,其包含的方法基本相同,所以本节以Integer类为例介绍整数包装类。
Integer类在对象中包装了一个基本数据类型int的值,该类的对象包含一个int类型的字段,此外,该类提供了许多方法,能在int类型和String类型之间互相转换,同时还提供了其他一些处理的方法和常量。
1.构造方法
该方法以一个int型变量作为参数来获取Integer对象。
Integer number=new Integer(7);//创建一个对象
2.Integer(String str)
该方法以一个String型变量作为参数来获取Integer对象
注意:如果要使用字符串变量创建Integer对象,字符串变量的值一定要是数值型,如"123",否则将会抛出NumberFormatException异常
Double 类
Double类和Float类是对double、float基本类型的封装,它们都是Number类的子类,都是对小数进行操作,所以常用方法基本相同,
Double类在对象中包装一个基本类型为double的值,每个Double类的对象都包含一个double类型的字段。此外,该类还提供多个方法,可以将double转换为String,将String转换为double,也提供了其他一些处理double时有用的常量和方法。
1.构造方法
Double类提供了以下两种构造方法来获得Double类对象。
(1) Double(double value)
基于double参数创建Double类对象。
例如,以double型变量作为参数创建Double对象,代码如下:
Double number=new Double(3.14);
(2) Double(String str)
该方法以一个String型变量作为参数来获取Double对象。
例如,以String型变量作为参数创建Double对象,代码如下:
Double number=new Double("3.14");
Double类在对象中包装一个基本类型为double的值,每个Double类的对象都包含一个double类型的字段。此外,该类还提供多个方法,可以将double转换为String,将String转换为double,也提供了其他一些处理double时有用的常量和方法。
1.构造方法
Double类提供了以下两种构造方法来获得Double类对象。
(1) Double(double value)
基于double参数创建Double类对象。
例如,以double型变量作为参数创建Double对象,代码如下:
Double number=new Double(3.14);
(2) Double(String str)
该方法以一个String型变量作为参数来获取Double对象。
例如,以String型变量作为参数创建Double对象,代码如下:
Double number=new Double("3.14");
BOOlean类
Boolean类将基本类型为boolean的值包装在一个对象中。一个Boolean类型的对象只包含一个典型为boolan的字段。此外,此类还为boolean和String的相互转换提供了许多方法,并提供了处the boolean时非常有用的其他一些常量和方法。
1.构造方法
Boolean类提供了以下两种构造方法来获得Boolean类对象。
(1) Boolean(boolean value)
该方法创建一个表示value参数的Boolean对象。
例如,创建一个表示value参数的Boolean对象,代码如下:
Eoolean b=new Boolean(true);
(2) Boolean(String str)
该方法以String变量作为参数创建Boolean对象。如果String参数不为null且在忽略大小写时等于true,则分配一个表示true值的Boolean对象,否则获得一个false值的Boolean对象。
例如,以String变量作为参数,创建Boolean对象。代码如下:
Boolean bool=new Boolean("ok");
1.构造方法
Boolean类提供了以下两种构造方法来获得Boolean类对象。
(1) Boolean(boolean value)
该方法创建一个表示value参数的Boolean对象。
例如,创建一个表示value参数的Boolean对象,代码如下:
Eoolean b=new Boolean(true);
(2) Boolean(String str)
该方法以String变量作为参数创建Boolean对象。如果String参数不为null且在忽略大小写时等于true,则分配一个表示true值的Boolean对象,否则获得一个false值的Boolean对象。
例如,以String变量作为参数,创建Boolean对象。代码如下:
Boolean bool=new Boolean("ok");
Character 类
3.常量
Character类提供了大量表示特定字符的常量,例如:(1)CONNECTOR_ PUNCTUATION :返回byte型值,表示Unicode规范中的常规类别“Pc”。
(2) UNASSIGNED :返回byte型值,表示Unicode规范中的常规别“Cn”。
(3)TITLECASE_LETTER:返回byte型值,表示Unicode规范中常规类别“Lt”。
说明:
Character类提供的常量有很多,详细列表可查看Java API文档。
Character类提供了大量表示特定字符的常量,例如:(1)CONNECTOR_ PUNCTUATION :返回byte型值,表示Unicode规范中的常规类别“Pc”。
(2) UNASSIGNED :返回byte型值,表示Unicode规范中的常规别“Cn”。
(3)TITLECASE_LETTER:返回byte型值,表示Unicode规范中常规类别“Lt”。
说明:
Character类提供的常量有很多,详细列表可查看Java API文档。
Number 类
Math类
Math 类概述
Math类表示数学类,它位于java. lang包中,由系统默认调用,该类中提供了众多数学函数方法,主要包括三角函数方法,指数函数方法,取整函数方法,取最大值、最小值以及绝对值函数方法,这些方法都被定义为static形式,因此在程序中可以直接通过类名进行调用。使用形式如下:Math.数学方法
在Math类中除了函数方法之外还存在一些常用的数学常量,如PI、E等,这些数学常量作为Math类的成员变量出现,调用起来也很简单。可以使用如下形式调用:
Math.PI//表示圆周率PI的值
Math.E//表示自然对数底数e的值
例如,下面代码用来分别输出PI和E的值。代码如下:
System. out. println("圆周率π的值为:"+Math.PI);
System. out.printIn("自然对数底数e的值为:"+Math.E);
上面代码的输出结果为:
圆周率π的值为:3. 141592653589793
自然对数底数e的值为:2. 718281828459045
在Math类中除了函数方法之外还存在一些常用的数学常量,如PI、E等,这些数学常量作为Math类的成员变量出现,调用起来也很简单。可以使用如下形式调用:
Math.PI//表示圆周率PI的值
Math.E//表示自然对数底数e的值
例如,下面代码用来分别输出PI和E的值。代码如下:
System. out. println("圆周率π的值为:"+Math.PI);
System. out.printIn("自然对数底数e的值为:"+Math.E);
上面代码的输出结果为:
圆周率π的值为:3. 141592653589793
自然对数底数e的值为:2. 718281828459045
运用数学运算方法
Math类中的常用数学运算方法较多,大致可以将其分为4大类别,分别为三角函数方法,指数函数方法,取整函数方法以及取最大值、最小值和绝对值函数方法
Math类中的常用数学运算方法较多,大致可以将其分为4大类别,分别为三角函数方法,指数函数方法,取整函数方法以及取最大值、最小值和绝对值函数方法
随机数
Math.random() 方法
在Math类中存在一个random(方法,用于生成随机数字,该方法默认生成大于等于0.0小于10的double型随机数,即0<=Math.random0<1.0,虽然Math. random(方法只可以生成0~1之间的double型数字,但只要在Math. random(i语句上稍加处理,就可以使用这个方法生成任意范围的随机数,如图9.11所示。
(int)(Math. Random()*n)返回大于等于0小于n的随机数
m+(int)(Math. Random()*n)
返回大于等于m小于m+n(不包括m+n)的随机数
在Math类中存在一个random(方法,用于生成随机数字,该方法默认生成大于等于0.0小于10的double型随机数,即0<=Math.random0<1.0,虽然Math. random(方法只可以生成0~1之间的double型数字,但只要在Math. random(i语句上稍加处理,就可以使用这个方法生成任意范围的随机数,如图9.11所示。
(int)(Math. Random()*n)返回大于等于0小于n的随机数
m+(int)(Math. Random()*n)
返回大于等于m小于m+n(不包括m+n)的随机数
注意:
Math. random向方法返回的值实际上是伪随机数,它通过复杂的运算而得到一系列的数,该方法是通过当事判断作为随机数生成器的参数,所以每次执行程序都会产生不同的随机数。
Math. random向方法返回的值实际上是伪随机数,它通过复杂的运算而得到一系列的数,该方法是通过当事判断作为随机数生成器的参数,所以每次执行程序都会产生不同的随机数。
Random 类
除了Math类中的random(方法可以获取随机数之外,Java中还提供了一种可以获取随机数的方式,那就是java. util. Random类,该类表示一个随机数生成器,可以通过实例化一个Random对象创建一个随机数生成器。语法如下:
Random r=new Random();
其中,r是指Random对象。
以这种方式实例化对象时,Java编译器以系统当前时间作为随机数生成器的种子,因为每时每刻的时间不可能相同,所以生成的随机数将不同,但是如果运行速度太快,也会生成两次运行结果相同的随机数。
同时也可以在实例化Random类对象时,设置随机数生成器的种子。语法如下:
Random r=new Random(seedValue);
r:Random类对象。
seedValue:随机数生成器的种子。在Random类中提供了获取各种数据类型随机数的方法,其常用方法及说明如表9.11所示。
除了Math类中的random(方法可以获取随机数之外,Java中还提供了一种可以获取随机数的方式,那就是java. util. Random类,该类表示一个随机数生成器,可以通过实例化一个Random对象创建一个随机数生成器。语法如下:
Random r=new Random();
其中,r是指Random对象。
以这种方式实例化对象时,Java编译器以系统当前时间作为随机数生成器的种子,因为每时每刻的时间不可能相同,所以生成的随机数将不同,但是如果运行速度太快,也会生成两次运行结果相同的随机数。
同时也可以在实例化Random类对象时,设置随机数生成器的种子。语法如下:
Random r=new Random(seedValue);
r:Random类对象。
seedValue:随机数生成器的种子。在Random类中提供了获取各种数据类型随机数的方法,其常用方法及说明如表9.11所示。
日期时间类
Date类
Calender 类
Calendar提供了一个类方法getInstance,以获得此类型的一个通用的对象。Calender的getInstance方法返回一个Calendar对象,其日历字段已由当前日期和时间初始化。
Calendar rightNow=Calendar.getInstance();
Calendar提供了一个类方法getInstance,以获得此类型的一个通用的对象。Calender的getInstance方法返回一个Calendar对象,其日历字段已由当前日期和时间初始化。
Calendar rightNow=Calendar.getInstance();
第十章 集合类
集合类概述
Collection 接口
注意:以上方法完全来自于 Java API 文档,读者可自行参考 API 文档来查阅这些方法的详细信息。读者无需硬性记忆这些方法,可以和实际生活结合记忆。集合类就像容器,现实生活中容器的功能,就是添加对象、删除对象、清空容器和判断容器是否为空等,集合类为这些功能都提供了对应的方法。
list 集合
list 接口
list 接口的实现类
Iterator 迭代器
Set集合
Set接口
HashSet 具有以下特点:
不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化。
HashSet 不是同步的,如果多个线程同时访问或修改一个 HashSet,则必须通过代码来保证其同步。
集合元素值可以是 null。
当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,然后根据该 hashCode 值决定该对象在 HashSet 中的存储位置。如果有两个元素通过 equals() 方法比较返回的结果为 true,但它们的 hashCode 不相等,HashSet 将会把它们存储在不同的位置,依然可以添加成功。
也就是说,两个对象的 hashCode 值相等且通过 equals() 方法比较返回结果为 true,则 HashSet 集合认为两个元素相等。
在 HashSet 类中实现了 Collection 接口中的所有方法。HashSet 类的常用构造方法重载形式如下。
HashSet():构造一个新的空的 Set 集合。
HashSet(Collection<? extends E>c):构造一个包含指定 Collection 集合元素的新 Set 集合。其中,“< >”中的 extends 表示 HashSet 的父类,即指明该 Set 集合中存放的集合元素类型。c 表示其中的元素将被存放在此 Set 集合中。
不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化。
HashSet 不是同步的,如果多个线程同时访问或修改一个 HashSet,则必须通过代码来保证其同步。
集合元素值可以是 null。
当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,然后根据该 hashCode 值决定该对象在 HashSet 中的存储位置。如果有两个元素通过 equals() 方法比较返回的结果为 true,但它们的 hashCode 不相等,HashSet 将会把它们存储在不同的位置,依然可以添加成功。
也就是说,两个对象的 hashCode 值相等且通过 equals() 方法比较返回结果为 true,则 HashSet 集合认为两个元素相等。
在 HashSet 类中实现了 Collection 接口中的所有方法。HashSet 类的常用构造方法重载形式如下。
HashSet():构造一个新的空的 Set 集合。
HashSet(Collection<? extends E>c):构造一个包含指定 Collection 集合元素的新 Set 集合。其中,“< >”中的 extends 表示 HashSet 的父类,即指明该 Set 集合中存放的集合元素类型。c 表示其中的元素将被存放在此 Set 集合中。
Set 接口的实现类
注意:在使用自然排序时只能向 TreeSet 集合中添加相同数据类型的对象,否则会抛出 ClassCastException 异常。如果向 TreeSet 集合中添加了一个 Double 类型的对象,则后面只能添加 Double 对象,不能再添加其他类型的对象,例如 String 对象等。
Map集合
Map 接口
Map 接口的实现类
集合的使用场合
Map 集合的遍历与 List 和 Set 集合不同。Map 有两组值,因此遍历时可以只遍历值的集合,也可以只遍历键的集合,也可以同时遍历。Map 以及实现 Map 的接口类(如 HashMap、TreeMap、LinkedHashMap、Hashtable 等)都可以用以下几种方式遍历。
第十一章 枚举与泛型
枚举
使用枚举类型设置常量
以往设置常量,通常将常量放置在接口中,这样在程序中就可以直接使用,并且该常量不能被修改,因为在接口中定义常量时,该常量的修饰符为final与static.
public interface Constants{
public static final int Constants_A=1;//定义一个泛型变量并赋初值
public static final int Conostants_B=12;
}
在JDK1.5版本中新增枚举类型后就逐渐取代了这种常量定义方式,因为通过使用枚举类型,可以赋予程序在编译时进行检查的功能。语法如下:
public enum Constants{
Constants_A,//泛型常量
Constants_B,
Constants_c
}
其中,enum是定义枚举类型的关键字。当需要在程序中使用该常量时,可以使用Constants.Constant_A来表示。
public interface Constants{
public static final int Constants_A=1;//定义一个泛型变量并赋初值
public static final int Conostants_B=12;
}
在JDK1.5版本中新增枚举类型后就逐渐取代了这种常量定义方式,因为通过使用枚举类型,可以赋予程序在编译时进行检查的功能。语法如下:
public enum Constants{
Constants_A,//泛型常量
Constants_B,
Constants_c
}
其中,enum是定义枚举类型的关键字。当需要在程序中使用该常量时,可以使用Constants.Constant_A来表示。
深入了解枚举类型
使用枚举类型的优势
枚举类型声明提供了一种用户友好的变量定义方法,枚举了某种数据类型所有可能出现的值。总结枚举类型,它具有以下特点:
(1)类型安全。
(2)紧凑有效的数据定义。
(3)可以和程序其他部分完美交互。
(4)运行效率高。
(1)类型安全。
(2)紧凑有效的数据定义。
(3)可以和程序其他部分完美交互。
(4)运行效率高。
泛型
回顾向上向下转型
泛型的常规用法
泛型的高级用法
1.通过类型参数T的继承限制泛型类型
默认可以使用任何类型来实例化一个泛型类对象,但Java中也对泛型类实例的类型作了限制,这主要通过对类型参数T实现继承来体现。
class 类名称 <T extends anyClass>
anyClass:接口或者类
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class Limitclass<T extends List> {//限制泛型的类型
public static void main (string[] args) {//可以实例化已经实现List接口的类
Limitclass<ArrayList> 11 = new LimitClass<ArrayList>();
Limitclass<LinkedList>12 = new Limitclass<LinkedList>();
//这句是错误的,因为HashMap没有实List()接口
//LimitClass<HashMap> 13=new Limitclass<HashMap>();
上面代码中,将泛型作了限制,设置泛型类型必须实现List接口。例如,ArrayList和 LinkedList 都实现了List接口,而HashMap没有实现List接口,所以在这里不能实例化 HashMap类型的泛型对象。
当没有使用extends关键字限制泛型类型时,默认 Object类下的所有子类都可以实例化泛型类对象。如图11.11所示的两个语句是等价的
1.通过类型参数T的继承限制泛型类型
默认可以使用任何类型来实例化一个泛型类对象,但Java中也对泛型类实例的类型作了限制,这主要通过对类型参数T实现继承来体现。
class 类名称 <T extends anyClass>
anyClass:接口或者类
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class Limitclass<T extends List> {//限制泛型的类型
public static void main (string[] args) {//可以实例化已经实现List接口的类
Limitclass<ArrayList> 11 = new LimitClass<ArrayList>();
Limitclass<LinkedList>12 = new Limitclass<LinkedList>();
//这句是错误的,因为HashMap没有实List()接口
//LimitClass<HashMap> 13=new Limitclass<HashMap>();
上面代码中,将泛型作了限制,设置泛型类型必须实现List接口。例如,ArrayList和 LinkedList 都实现了List接口,而HashMap没有实现List接口,所以在这里不能实例化 HashMap类型的泛型对象。
当没有使用extends关键字限制泛型类型时,默认 Object类下的所有子类都可以实例化泛型类对象。如图11.11所示的两个语句是等价的
2.通过类型通配符的继承限制泛型类型
在泛型机制中,提供了类型通配符,其主要作用是在创建一个泛型类对象时,限制这个泛型类的类型,或者限制这个泛型类型必须继承某个接口或某个类(或其子类)。要声明这样一个对象可以使用“?”通配符,同时使用extends 关键字来对泛型加以限制。
说明:
通过对类型参数T实现继承限制泛型类型时,在声明时就进行了限制,而通过对类型通配符实现继承限制泛型类型时,则在实例化时才进行限制。
使用泛型类型通配符的语法如下:
泛型类名称<?extends List> a=null;
其中,<? extends List>表示类型未知,当需要使用该泛型对象时,可以单独实例化。例如,在项目中创建一个类文件,在该类中限制泛型类型。
A<?extends List> a=null;
a=new A<ArrayList> ();
a=new A<LinkedList>();
如果实例化没有实现List 接口的泛型对象,编译器将会报错。例如,实例化HashMap对象时,编译器将会报错,因为 HashMap类没有实现List 接口。
除了可以实例化一个限制泛型类型的实例之外,还可以将该实例放置在方法的参数中。例如,在项目中创建一个类文件,在该类的方法参数中使用匹配字符串。
public void doSomething(A<? extends List> a){
}
在上述代码中,定义方式有效地限制了传入doSomething()方法的参数类型。
如果使用A<?>这种形式实例化泛型类对象,则默认表示可以将A指定为实例化Object 及以下的子类类型。读者可能对这种编码类型有些疑惑,下面的代码将直观地介绍A<?>泛型机制。
在泛型机制中,提供了类型通配符,其主要作用是在创建一个泛型类对象时,限制这个泛型类的类型,或者限制这个泛型类型必须继承某个接口或某个类(或其子类)。要声明这样一个对象可以使用“?”通配符,同时使用extends 关键字来对泛型加以限制。
说明:
通过对类型参数T实现继承限制泛型类型时,在声明时就进行了限制,而通过对类型通配符实现继承限制泛型类型时,则在实例化时才进行限制。
使用泛型类型通配符的语法如下:
泛型类名称<?extends List> a=null;
其中,<? extends List>表示类型未知,当需要使用该泛型对象时,可以单独实例化。例如,在项目中创建一个类文件,在该类中限制泛型类型。
A<?extends List> a=null;
a=new A<ArrayList> ();
a=new A<LinkedList>();
如果实例化没有实现List 接口的泛型对象,编译器将会报错。例如,实例化HashMap对象时,编译器将会报错,因为 HashMap类没有实现List 接口。
除了可以实例化一个限制泛型类型的实例之外,还可以将该实例放置在方法的参数中。例如,在项目中创建一个类文件,在该类的方法参数中使用匹配字符串。
public void doSomething(A<? extends List> a){
}
在上述代码中,定义方式有效地限制了传入doSomething()方法的参数类型。
如果使用A<?>这种形式实例化泛型类对象,则默认表示可以将A指定为实例化Object 及以下的子类类型。读者可能对这种编码类型有些疑惑,下面的代码将直观地介绍A<?>泛型机制。
泛型总结
使用泛型需遵循以下原则。
(1 )泛型的类型参数只能是类类型,不可以是简单类型,如A<int>这种泛型定义就是错误的,
(2)泛型的类型个数可以是多个.
(3 )可以使用extends关键字限制泛型的类型。
( 4)可以使用通配符限制泛型的类型。
使用泛型需遵循以下原则。
(1 )泛型的类型参数只能是类类型,不可以是简单类型,如A<int>这种泛型定义就是错误的,
(2)泛型的类型个数可以是多个.
(3 )可以使用extends关键字限制泛型的类型。
( 4)可以使用通配符限制泛型的类型。
收藏
0 条评论
下一页