我是靠谱客的博主 平常水蜜桃,这篇文章主要介绍【无标题】Java基础Java面向对象——OOP补充,现在分享给大家,希望可以做个参考。

变量的作用域:
全局变量:
定义方法(函数)和代码块之外的变量
局部变量:
定义在方法或者代码之间的变量
静变量
数据类型:
整型、长整形、短整型 、单精度浮点型、 双、布尔、 字节、 字符型、

数据类型转换
Boolean类型不参与转换
char和short可以相互转换(互相强转)
小类型转换成大类型(自动转换)
强制类型转换:
当大类型数据转换成小类型需要强制转换(类型强转)
语法:小类型 变量名 =(需要转换的类型)大类型

引用 数据类型不能与基本数据类型相互转换;两种数据类型要彼此兼容,否则不能互相转换。
引用数据类型转换需是继承关系,

任何数据类型与字符串做+运算都会变成字符串。
Java算术运算符
1、一元运算:
-、++、–、(++在前,先自增再赋值)
2、二元运算符:
加、减、乘、除、取余、
3、逻辑或不论后面是真是假都会往后走。
Java关系运算符
1、基本类型的变量、值不能与引用类型的变量、值使用进行作比较;
2、
3、
栈 通常用来存放方法
equals(obj)方法和
的区别:
equals方法比较的是两个对象的内容是否相等
==比较的是两个 对象在内存中存放的地址是否为同一个;
位移运算符
只有<<(向左位移) >>(向右位移) 。无<<<或者>>>等符号
next()与nextLine()方法的区别;
1.当遇到空格或者回车的时候,next()停止读取
2.当遇到回车的时候nextLine()方法停止读取,读取整行数据
一、int类型的直接量
在程序中直接给出的整型数值,可分为二进制、十进制、八进制和十六进制4种,其中二进制需要以0B或Ob开头,八进制需要以
0开头,十六进制需要以0x或OX开头。例如123、012(对应十进制的10)、0x12(对应十进制的18)等。
二、long 类型的直接量
在整型数值后添加 | 或 L后就变成了long 类型的直接量。例如3L、0x12L(对应十进制的18L),
三、float 类型的直接量
在一个浮点数后添加f 或 F 就变成了 float 类型的直接量,这个浮点数可以是标准小数形式,也可以是科学计数法形式。例如
5.34F、3.14E5f。
四、double 类型的直接量
直接给出一个标准小数形式或者科学计数法形式的浮点数就是 double 类型的直接量。例如5.34、3.14E5。
五、boolean 类型的直接量
这个类型的直接量只有true 和 false。
char类型的直接量
char 类型的直接量有三种形式,分别是用单引号括起来的字符、转义字符和 Unicode 值表示的字符。例如’a’,n’和u0061’。


Java课堂笔记

Java常量
常量是指在程序的整个运行过程中值保持不变的量。
常量值
常量值又称为字面常量,它是通过数据直接表示的,因此有很多种数据类型,像整型和字符串型等。
整型常量值
整型常量值主要有如下3种形式。
十进制数形式:如54、-67、 0。
八进制数形式: Java 中的八进制常数的表示以0开头,如0125表示十进制数85, -013 表示十进制数-11。
十六进制数形式: Java中的十六进制常数的表示以0x或0X开头,如0x100表示十进制数256, -0x16 表示十进制数-22。
整型(int) 常量默认在内存中占32位。
实型常量值
Java的实型常量值主要有如下两种形式。
十进制数形式:由数字和小数点组成,且必须有小数点,如12.34、-98.0。
科学记数法形式:如1.75e5或32&E3,中e或E之前必须有数字,且e或E之后的数字必须为整数。
Java实型常量默认在内存中占64位,是具有双精度型(double) 的值。
单精度型数值一般要在该常数后面加 F或f,如69.7f, 表示-个float型实数,它在内存中占32位。
布尔型常量值
Java的布尔型常量只有两个值,即false (假)和true (真)。
Java变量的作用域
变量的作用域规定了变量所能使用的范围,只有在作用域范围内才能被使用。根据变量的声明地点不同,变量的作用域也不同
变量又分为成员变量与局部变量
成员变量分为
(1)全局变量:无static修饰访问对象名变量名
(2)静态变量:用static修饰,访问类名变量名
局部变量分为
(1)方法参数变量:在整个方法内有下效
(2)方法局部变量:从定义这个变量开始到方法结束这一段时间内有效
(3)代码块局部变量:从定义这个变量开始到代码结束这一段时间内有效
局部变量在使用前必须被程序员主动初始化值
声明变量
首字符必须是字母、下划线、美元符号、人民币符号
标识符由数字大写字母小写字母下划线美元符号人民币符号以及所有在十六进制Oxco前的ASCLL码组成,不能吧关键字保留字作为标识符
定义常量
常量不同于常量值,它可以在程序中用符号来代替常量值使用,因此在使用前必须先定义。常量与变量类似也需要初始化,即在声明 常量的同时要赋予一个初始值。常量一旦初始化就不可以被修改。
final dataType variab1eName = value
其中,final 是定义常量的关键字,dataType 指明常量的数据类型,variableName 是变量的名称, value 是初始值。final关键字表示最终的,它可以修改很多元素,修饰变量就变成了常量。例如,以下语句使用final关键字声明常量。
Java中的数据类型:
1、基本数据类型(八种)
byte(字节型)、short(短整型)、int(整形)、long(长整型)、float(单精度浮点型)、double(双精度浮点型)char(字符型)、boolean(布尔型)
字节型:byte by = 127;
// System.out.println((byte) (by + 1));
短整型:short sh = 56;
整形: int num = 78946;
长整型,注意: 需要早长整型末尾添加L或者l:long number = 56L;
单精度浮点型, 注意: 需要早长整型末尾添加F或者f;float fl = 3.14F
System.out.println(fl1);
双精度浮点型,java中小数默认是double类型;double db = 3.14159;
字符型, 字符型的值使用单引号引起来,当值为整形时不需要单引号
char ch1 = 3;
char ch2 = ‘a’;
char ch3 = 97;
System.out.println(ch1);
System.out.println(ch3);
布尔值类型,注意:Java中布尔值类型只有true和false两个值
boolean bool1 = true;
boolean bool2 = false;
2、引用数据类型
除了基本数据类型,其他全部是引用数类型,如:String、数组等
Java逻辑运算符
&& 短路与:a && b (a和b同时为真时为真)

|| 短路或:a && b (a和b有一个为真时为真)

& 逻辑与:同&&
| 逻辑或:同||
! 逻辑非:!a (a为真时,值为假;a为假时,值为真)

短路与、短路或和逻辑与、逻辑或的区别:
a && b :如果 a 为 false,则不计算 b(因为不论 b 为何值,结果都为 false)

a || b :如果 a 为 true,则不计算 b(因为不论 b 为何值,结果都为 true)

a & b : a无论是true或false,b都会进行计算

a | b : a无论是true或false,b都会进行计算
创建扫描器对象
Scanner scan = new Scanner(System.in);
System.out.println(“请输入您的名字:”);
name = scan.next();
next()与nextLine()方法的区别:
1、当遇到空格或者回车的时候 next()方法停止读取
2、当遇到回车的时候 nextLine()方法停止读取,读取整行数据

1.二位数组用数据类型 [][] = new 数据类型[][];
例如: int[][] arr = new int[2][3];
2.遍历二位数组;
可以用两个for-each,例如for(int i:arr[])for(int j:arr);遍历二维数组;
3.访问二维数组的语法:arr[x][y] = 1;就是给第x + 1行第y + 1列的值赋成1;
4.二维数组的存储,大概是arr[x][y]中,x存的是二维数组的索引,也就是数组的地址,x存在栈,y存在堆区;static修饰的存在方法区;在类中,static修饰可以直接用类名访问,用对象访问会报警告;
5.System.arraycopy,src:原数组;srcPos: 原数组起始位置(从这个位置开始复制);dest:目标数组;destPos:目标数组粘贴的起始位置;length: 复制的个数
6.方法的重载是方法名相同,参数列表不同,返回值不做要求;
7.Arrays.copyOf(arr[],7);即arr【】为目标数组,7为新复制的数组长度;
8.数组的扩容与缩容量,使用int aee1[] = Arrays.copyOf(arr,5);
其中arr为原来的数组,5位新数组的大小;增容的操作也类同;这里并没有销毁原来的数组,准确的应该算复制;
9.Arrays.sort能对数组进行排序,返回值为int,返回数据为目标值的下标,二分查找的使用的前提是数组必须排好序;
10,使用equals能比较两个数组是否相等;两个参数分别是一个数组和另一个数组,如果相同返回true,如果不同返回false;

if语句
if双分枝结构:为条件表达语句,当语句为ture时执行语句,当语句为false,执行else语句。
嵌套switch语句
if语句与switch语句都表示条件语句,可以使用效率与实用性两方面加以区分。
从效率上看
对同一个变量的不同值作为条件判断时,当判断条件较多时可以使用switch语句
从实用性上看
当判断条件不多时使用if语句更加方便

while循环与do…while循环的区别:
1、while是先判断后执行,do…while循环是先执行然后再判断
2、do…while循环至少执行一次
while循环与do…while的特点:都是循环执行某一语句,循环次数素不固定
while循环:
语法:
while (循环条件) {
循环体}
案例:计算1+到100的和
1+2+3+4+5+6+7+…+100
int num = 1;
int sum = 0;
while (num <= 100) {
sum += num;
num ++;
}
System.out.println(sum);

do.while循环
语法:
do{
循环体
} while (循环条件);
案例:计算1+到100的和
1+2+3+4+5+6+7+…+100
int num2 = 1;
int sum2 = 0;
do {
sum2 += num2;
num2 ++;
} while (num2 <= 100);
System.out.println(sum2);

for循环嵌套
如果循环嵌套层数超过了三层,那么一定是逻辑出了问题

数组定义:
用来存放相同类型的一组数据
数组下标从0开始,对数组元素进行操作是通过数组的下标(索引)
数组一旦被创建,则数组的长度不可被修改
语法:
静态创建数组
数据类型[] 数组名 = {值1,值2…}
数据类型 数组名[] = {值1,值2…}
数组元素必须是相同类型的,不允许出现混合类型。
数组的默认初始化、
int a2[] = new int[2];//默认值0,0
boolean[] b = new boolean[2];//默认值 false,false
String[] s = new String[2];//默认值null
随机数:
1、Random random = new Random();
生成指定范围内的随机数 random.nextInt(10)
2、double random = Math.random();
生成随机数的范围 0.0-1.0,但是永远到不了


动态创建数组
数据类型[] 数组名 = new 数据类型[数组长度]
数据类型 数组名[] = new 数据类型[数组长度]
// 静态创建数组,特点:创建数组的同时给数组元素赋值
int arr[] = {1, 2, 4, 8, 9};

// 动态创建数组,特点创建数组时指定数组的长度
long[] arr1 = new long[5];
// 数组元素必须是相同类型的,不允许出现混合类型。
// dArr[2] = “hello array”; 数组元素类型与数组类型不匹配,语法报错

 二维数组的动态初始化: .

数据类型数组名00 = new数据类型[m][n]数据类型00数组名= new数据类型[m][n]
数据类型0数据名0 = new数据类型[m]In]数组的复制:浅拷贝
System.arrarcoplarr,start,dist,index.length)
Arrays,copofrr,length)
4、Arrays类 具有以下常用的功能
1、给数组赋值:通过调用fill方法
2、对数组排序:通过sort方法
3、比较数组:通过equals方法比较数组中元素的值是否相等
5、数组的扩容于缩容
实质:就是创建一个新的数组,新数组避原来的数组(大,为扩容,小,为缩容)打印数组Arrays. toStingarr)方法的作用是将数组- -字符串的形式输出
给数组赋值:
通常用il方法
Arrays binarySercharr9);该方法的返回值为查找到的元素下标的值
Java面向对象- 0OP
一、什么是面向对象
面向过程与面向对象:
面向对象过程思想:
1、步骤清晰简单
2、面向过程合适处理一些较为简单的问题
面向对象思想的本质就是:以类的方式组织代码,以对象的组织(封装) 数据类是对象的抽象,对象是类的实例。
什么是类:类型/类别,代表-类个体
对象:真实存在的单个个体;
类中包含: 1、所有对象所共有的属性/特征-- -成员变量
2、所有对象所共有的行- -方法
一个类可以创建多个对象
同一类型所创建的对象,结构相同,数据类型不同。
类是对象的模板,对象是类的具体实例
面向对象的三大特征:
封装,继承,多态
类的定义:,
修饰符class 类名{成员变量类型变量名 ;
访问对象成员变量和方法,语法:
对象名.成员变量名字/方法名字,能点出什么东西全看类有扫描东西
00A :面向对象分析法
面向对象设计
一个Java文件中只能有一个public修饰的Java类,并且这个被public修饰的Java类名必须与Java文件名字-致。
创建对象的语法:
数据类型
引用类型变量
指向
new关键字对象
Student
new
造成空指针异常的原因:是因为对象为null定义类中的方法:
class类名{
修饰符返回值类型 方法名(参数列表) {
创建并且使用对象:
使用new关键字创建对象:new的运算语法为:
new类名()

Java面向对象——OOP

补充

包机制的作用:
​为了更好的组织类,Java提供了包机制,用于区分类的命名空间,包语句的语法格式为:

package
包名1.包名2.……

一般利用公司的域名倒置作为包名。

import
完整的包名.类名;

​package语句必须位于Java源文件中的第一行,否则编译不通过。
一、什么是面向对象
面向过程与面向对象:
​面向过程思想:
​ 1、 步骤清晰简单,第一步要做什么,第二步要做什么……
​ 2、 面向过程适合处理一些较为简单的问题
​ 面向对象思想:
​ 1、 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考,最后,才对某个分类下的细节进行面向过程的思索。
​ 2、 面向对象适合处理复杂的问题,适合处理需要多人协作的问题
面向过程的结构化程序设计:
​ 结构化程序设计的弊端:
​ 1、缺乏对数据的封装
​ 2、数据与方法(操作数据)的分离
什么是面向对象:
​ 面向对象的本质就是:以类的方式组织代码,以对象的组织(封装)数据。
什么是抽象的数据类型:
​ 所谓抽象数据类型可以理解为:将不同类型的数据的集合组成一个整体,用来描述一种新的事务。如:对象类型数据
什么是类?什么是对象?
​ 1、现实世界是由很多很多对象组成的
基于对象抽出了类
​ 2、对象:真实存在的单个的个体
​ 类:类型/类别,代表一类个体
​ 3、类中可以包含:
3.1、所有对象所共有的属性/特征------------成员变量
3.2、所有对象所共有的行为-----------------方法
​ 4、一个类可以创建多个对象
​ 同一类型所创建的对象,结构相同,数据不同
​ 5、类是对象的模板,对象是类的具体的实例
面向对象的三大特征:
​ 封装、继承、多态
补充:
​ OOA
​ Object-Oriented Analysis:面向对象分析法

指的是在一个系统的开发过程中进行了系统业务调查以后,按照面向对象的思想来分析问题。OOA与结构化分析有较大的区别。OOA所强调的是在系统调查资料的基础上,针对OO方法所需要的素材进行的归类花分析和整理,而不是对管理业务现状和方法的分析。
OOA(面向对象的分析)模型由5个层次(主题层、对象类层、结构层、属性层和服务层)和5个活动(标识对象类、标识结构、定义主题、定义属性和定义服务)组成。在这种方法中定义了两种对象类之间的结构,一种称为分类结构,一种称为组装结构。分类结构就是所谓的一般与特殊的关系。组装结构则反映了对象之间的整体与部分的关系。
​ OOA在定义属性的同时,要识别实例连接。实例连接是一个示例与另一个实例的映射关系。
​ OOA在定义服务的同时要识别消息连接。当一个对象需要向另一个对象发送消息时,它们之间就存在消息连接。
​ OOA中的5个层次和5个活动继续贯穿在OOD(面向对象设计)过程中。OOD模型由4各部分组成。它们分别是设计问题域部分、设计人机交互部分、设计任务管理部分、和设计数据管理部分。
一、OOA的主要原则。
​ 1)抽象:从许多食物中舍弃个别的、非本质的特征,抽取共同的、本质性的特征,就叫做抽象。愁乡石形成概念的必须手段。
​ 抽象原则有两个方面的意义:第一,尽管问题域中的事物是很复杂的,但是分析员并不需要了解和描述它们的一切,只需要分析 其中与系统目标有关的事物及其本质性特征。第二,通过舍弃个体事物在细节上的差异,抽取其共同特性而得到一批事物的抽象概 念。
​ 抽象是面向对象方法中使用最为广泛的原则。抽象原则包括过程抽象和数据抽象两个方面。
​ 过程抽象是指,任何一个完成确定功能的操作序列,其使用者都可以把它看做一个单一的实体,尽管实际上它可能是由一系列更 低级的操作完成的。

​ 数据抽象是根据施加于数据之上的操作来定义数据类型,并限定数据的值只能由这些操作来修改和观察。数据抽象是OOA的核 心原则。它强调把数据(属性)和操作(服务)结合为一个不可分的系统单位(即对象),对象的外部只需要知道它做什么,而不必 知道它如何做。
就是把对象的属
​ 2)封装:性和服务结合为一个不可分的系统单位,并尽可能隐蔽对象的内部细节。
​ 3)继承:特殊类的对象拥有的其一般类的全部属性与服务,称作特殊类对一般类的继承。(父子)
​ 在OOA中运用继承原则,就是在每个由一般类和特殊类形成的一半----特殊结构总,把一般类的对象实例和所有特殊类的对象实 例都共同具有的属性和服务,一次性的在一般类中进行显式的定义。在特殊类中不在重复的定义一般类中已定义的东西,但是在语义 上,特殊类却自动的、隐含地拥有它的一般类(以及所有更上层的一般类)中定义的全部属性和服务。继承原则的好处是:是系统模 型比较简练也比较清晰。
​ 4)分类:就是把具有相同属性和服务的对象划分为一类,用类作为这些对象的抽象描述。分类原则实际上是抽象原则运用于对象描 述时的一种表现形式。
​ 5)聚合:又称组装,其原则是:把一个复杂的事物看成若干比较简单的事物组装体,从而简化对复杂事物的描述。
​ 6)关联:是人类思考问题时经常运用的思想方法:通过一个事物联想到另外的事物。能使人发生联想的原因是事物之间确实存在着某些联系。
​ 7)消息通信:这一原则要求对象之间只能通过消息进行通信,而不允许在对象之外直接地存取对象内部的属性。通过消息进行通信是由于封装原则而引起的。在OOA中要求消息连接表示出对象之间的动态联系。
​ 8)粒度控制:一般来讲,人在面对一个复杂的问题域时,不可能在同一时刻既能纵观全局,又能洞察秋毫。因此需要控制自己的视野:考虑全局时,注意其大的组成部分,暂时不详查每一部分的具体的细节:考虑某部分的细节时则暂时撇开其余的部分。着就是粒度控制原则
​ 9)行为分析:显示世界中事物的行为是复杂的。由大量的事物所构成的问题域中各种行为旺旺相互依赖交织
二、面向对象分析产生三种模型
​ 1、对象模型:对用例模型进行分析,把系统分解成互相协作的分析类,通过类图对象图描述对象对象的属性对象间的关系,是系统的静态模型
​ 2、动态模型:**描述系统的动态行为,通过时序图/协作图/描述对象的交互,以揭示对象间如何协作来完成每个具体的用例。单个对象的状态变化/动态行为可以通过状态图来表示。
​ 3、功能模型(即用例模型à作为输入)
​ 封装:也叫作信息封装,确保组件不会以不可预期的方式改变其它组件内部状态,只有在那些提供了内部状态改变方法的组建中,才可以访问其内部状态。每类组件都提供了一个与其它组件联系的接口,并规定了其它组件进行调用的方法。
​ 多态性:组件的引用和类集会涉及到其它许多不同类型的组件,而且引用组件所产生的的结果得依据实际调用的类型。
​ 继承性:允许在现存的组件基础上创建子类组件,着统一并强调了多态性和封装性。典型的来说就是用类来对组件进行分组,而且还可以定义新类为现存的类的扩展,这样就可以将类组织成树形或网状结构,这体现了动作的通用性。
二、类与对象的创建
定义一个类:
​ 定义类的成员变量:
​ 1、类的定义包括“成员变量”的定义和“方法”的定义,其中“成员变量”用于描述对象 共同的数据结构,“方法”则是所有对象共同的行为。
​ 2、Java语言中,类的成员变量的定义可以使用如下的语法:

修饰符 class
类名 {
成员变量类型
变量名;
………
}
​
3、对象创建后,其成员变量可以按照默认的方式初始化,初始化对象成员变量时,其默认值的规则如下表所示:
| **成员变量类型**
| **默认初始值** |
| ------------------------------------------------- | -------------- |
| 数值类型(byte、short、int、long、float、double) | 0
|
| boolean类型
| false
|
| char类型
| /u0000
|
| 引用类型
| null
|
定义类的方法:
类中除了定义成员变量,还可以定义方法,用于描述对象的行为,封装对象的功能,Java语言中,可以按照如下方式定义类中的方法:
```java
class
类名 {
修饰符
返回值类型
方法名(参数列表){
方法体………
}
……………
}
**创建并且使用对象:**
​
**使用new关键字创建对象:**
​
类定义完成之后,可以使用new关键字创建对象,创建对象的过程通常称为实例化对象,new的运算语法为:
```java
new
类名();
如:new
JFrame(); //可以创建一个窗体对象
创建对象语法:
数据类型
引用类型变量
指向
new关键字
对象
Student
zs
=
new
Student();

引用类型变量:
​ 为了能够实例化对象进行访问控制,需要使用一个特殊的变量——引用。
​ 引用类型变量可以存放该类对象的地址信息,通常称为“指向该类的对象”,当一个引用类型变量指向该类的对象时,就可以通过这个变量对对象实施访问。
​ 除了8种基本数据类型之外,用类、接口、数组等声明的变量都称为引用类型变量,简称“引用”。
访问对象的成员变量,调用方法:
​ 可以通过引用访问对象的成员变量或调用方法。

创建cell类:
public class Cell {
// 定义属性
int row;
int col;
//定义方法
public void drop() {}
public void moveLeft(int len) {}
public String getCellInfo() {
return "";
}
}
创建Cell类并访问成员变量及方法
Cell
c
=
new
Cell();
c.row
=
3;
c.col
=
2;
c.drop();
c.moveLeft(2);
String
str
=
c.getCellInfo();

引用类型变量的赋值:
​ 1、引用类型变量存储的是对象的地址信息,相同类型的引用类型变量之间也可以互相赋值。
​ 2、引用类型变量之间的赋值不会创建新的对象,但有可能会使两个以上的引用指向同一个对象。例如:

Emp
e1
=
new
Emp();
Emp
e2
=
e1; // 将e1的值(对象地址信息)赋给e2,此时e1和e2指向相同对象
**null和NullPointerException:**
​	1、对于引用类型变量。可以对其赋值为null,null的含义为“空”,表示还没有指向任何对象,例如:
```java
Emp
emp
=
null; //emp为的值null,没有指向任何对象
emp
=
new
Emp(); //emp指向了一个Emp对象
​
2、当一个引用变量的值为null的时候,如果通过引用访问对象成员变量或者调用方法不符合逻辑时,会产生NullPointerException,例如:
```java
int[]
arr
=
null;
arr.length;
四、Java内存分析
1、堆、栈、方法区:
堆: new出来的对象(包括实例变量)
栈:局部变量(包括方法的参数)
方法区: .class字节码文件(包括方法、静态变量)
2、堆,栈,方法区,常量池 的位置分布图:
<img src="06-面向对象(OOP).assetsimage-20220913225751369.png" alt="image-20220913225751369" style="zoom:80%;" />
3、内存区域类型
1.寄存器:**最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制;
2. 堆:存放所有new出来的对象;
3. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(对象可能在常量池里)(字符串常量对象存放在常量池中。);
4. 静态域:存放静态成员(static定义的);
5. 常量池:存放字符串常量和基本类型常量(public static final)。有时,在嵌入式系统中,常量本身会和其他部分分割离开(由于版权等其他原因),所以在这种情况下,可以选择将其放在ROM中 ;
6. 非RAM存储:**硬盘等永久存储空间
1.内存管理:由JVM来管理的
2.1) 堆:
1.1) 存储new出来的对象(包括实例变量)
1.2) 垃圾: 没有任何引用所指向的对象
垃圾回收器(GC)**不定时到内存中清理垃圾,
回收过程是透明的(看不到的),不一定一发现垃圾就立刻回收,
调用System.gc()可以建议虚拟机尽快调度GC来回收
1.3) 内存泄漏: 不再使用的内存没有被及时的回收
建议: 对象不再使用时及时将引用设置为null
1.4) 实例变量的生命周期:
在创建对象时存储在堆中,对象被回收时一并被回收
2) 栈:
2.1) 存储正在调用的方法中的所有局部变量(包括方法的参数)
2.2) 调用方法时,会在栈中为该方法分配一块对应的栈帧,
栈帧中存储方法中的局部变量(包括参数),
方法调用结束时,栈帧被清除,局部变量一并被清除
2.3) 局部变量的生命周期:
方法被调用时存储在栈中,方法结束时与栈帧一并被清除
3) 方法区:
​
3.1) 存储.class字节码文件(包括静态变量、方法)
​
3.2) 方法只有一份,通过this来区分具体的调用对象
六、访问控制修饰符
1、public和private
​
private修饰的成员变量和方法仅仅只能在本类中访问调用。
​
public修饰的成员变量和方法可以在任何地方调用,public修饰的内容是对外提供可以被调用的功能,需要相对稳定,private修饰的内容是对类实现的封装,如果“公开”会增加维护的成本。
2、 protected和默认访问控制
​
1)用protected修饰的成员变量和方法可以被子类及同一个包中的类使用。
​
2)默认的访问控制即不书写任何访问修饰符,默认访问控制的成员变量和方法可以被同一个包中的类调用。
3、访问控制修饰类
​
1)对于类的修饰可以使用public和默认的方式,public修饰的类可以被任意一个类使用,默认方法控制的类只能被同包中的类使用。
​
2)protected和private可以用于修饰内部类
# 七、封装
​
封装,简单的说就是该露的露,该藏的藏。我们在设计程序是要追求“高内聚,低耦合”,其中,高内聚指的是类的内部数据操作细节由自己完成,不允许外部干涉。低耦合指的是仅露少量的方法给外部调用(使用get/set方法)。
​
封装(对数据的隐藏),通常来说,应禁止直接访问应该对象中数据的实际表示,而是应该通过操作接口来访问,这种称为信息隐藏。
封装的意义:
​
1、对外提供可调用的,稳定的功能。
​
2、封装容易变化的,具体的细节,外界不可访问,
这样封装的意义在于:
​
a. 降低代码出错的可能性,便于维护。
​
b. 当内部的实现细节改变时,只要保证对外的功能定义不变,其他的模块就不会因此而受到牵连。
八、继承
1、泛化的过程
2、extends关键字
​
1、通过extends关键字可以实现类的继承。
​
2、子类可以继承父类的成员变量及成员方法,同时也可以定义自己的成员变量和成员方法。
​
3、Java语言不支持多重继承,一个类只能继承一个父类,但是一个父类可以有多个子类。
例如:
<img src="06-面向对象(OOP).assetsimage-20220913231357154.png" alt="image-20220913231357154" style="zoom:80%;" />
3、继承中的构造方法
​
1、子类的构造方法中必须通过super关键字调用父类的构造方法,这样可以妥善的初始化继承自父类的成员变量。
​
2、如果子类的构造方法中没有调用父类的构造方法,Java编译器会自动的加入对父类的无参构造方法的调用(如果父类没有无参构造方法,则会有编译错误)。
4、父类的引用指向子类的对象
​
1、一个子类的对象可以向上造型为父类的类型,即,定义父类型的引用可以指向子类型的对象。
​
2、 父类的引用可以指向子类的对象,但是通过父类的引用只能访问父类所定义的成员,不能访问子类扩展的部分。
九、super关键字
**在java里面,对于super关键字通常有两种用法:**
​
1. 用在子类的构造方法里(初始化用),主要是调用父类的默认构造方法,如果父类有不止一个构造方法,可以通过super指定具体的构造函数,比如 super(paras)。
​
2. 用在子类里调用隐藏或重写的属性或行为,比如 super.onDestroy()等等。
​
对于第1种需要注意,super表示当前类的父类对象,super()调用的是父类默认的构造方法,即这样可以对父类进行初始化。如果没有对父类进行初始化,当子类调用父类的方法时,便会从逻辑上出现错误,因为没对父类初始化,父类的方法和属性便没有内存空间。
关于super 与 this 关键字的对比(区别):
​
1. super(参数):调用基类中的某一个构造函数(应该位于子类构造函数中的第一条语句)。
​
2. this(参数):调用本类中的构造函数(应该位于构造函数中的第一条语句)。
​
3. super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名 super.成员函数据名(实参)。
​
4. this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)
​
5、调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。
​
6、super()和this()类似,区别是,super()从子类中调用父类的构造方法,this()在同一类内调用其它构造方法。
​
7、super()和this()均需放在构造方法内第一行。
​
8、尽管可以用this调用一个构造器,但却不能调用两个。
​
9、this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
​
10、 this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。
​
11、 从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。
# 十、方法重写
**方法的重写(Override):**
​	1、发生在父子类中,方法名称相同,参数列表相同,方法体不同
​	2、重写方法被调用时,看对象的类型
​	3、遵循"两同两小一大"原则:------------了解
​	3.1、两同:
​	3.1.1、方法名称相同
​	3.1.2、参数列表相同
3.2、两小:
​
3.2.1、派生类方法的返回值类型小于或等于超类方法的
​
a、void时,必须相同
​
b、基本数据类型时,必须相同
​
c、引用数据类型时,小于或等于
​
3.2.2、派生类方法抛出的异常小于或等于超类方法的
​
3.3、一大:
​
3.3.1、派生类方法的访问权限大于或等于超类方法的
**重写与重载的区别:**
​
1、重写(Override):
​
1.1、发生在父子类中,方法名相同,参数列表相同,方法体不同
​
1.2、"运行期绑定",看对象的类型绑定方法
​
2、重载(Overload):
​
2.1、发生在一个类中,方法名相同,参数列表不同,方法体不同
​
2.2、"编译期绑定",看参数/引用的类型绑定方法
<p style="color: red">补充:</p>
​
编译期:.java源文件,经过编译,生成.class字节码文件
​
运行期:JVM加载.class并运行.class
​
编译错误:只是检查语法
# 十一、多态
​
多态指的是同一方法可以根据发送对象的不同而采用多种不同的行为方式。
​
一个对象的实际类型是确定的,但是可以指向对象的引用的类型有很多。
​
多态存在的条件:
​
1、 有继承关系
​
2、 子类重写父类的方法
​
3、 父类引用指向子类对象
多态的意义:
​
1、行为的多态(所有抽象方法都是多态的)
​
2、对象的多态(所有对象都是多态的)
多态的表现形式:
​
1、重写:根据对象的不同来表现多态
​
2、重载:根据参数的不同来表现多态
注:多态是方法的多态性,属性没有多态性。
* 抽象方法使用abstract关键字修饰:
*
抽象方法没有方法体,连{}也没有
*
*
抽象方法允许有方法重载
注意:如果一个类包含抽象方法,那么该类必须声明为抽象类
接口(Interface)
接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过实现(implements)接口的方式,从而来实现接口的抽象方法。
​
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
​
除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。
​
接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
接口与类相似点:
​
1)一个接口可以有多个方法。
​
2)接口文件保存在 .java 结尾的文件中,文件名使用接口名。
​
3)接口的字节码文件保存在 .class 结尾的文件中。
​
4)接口相应的字节码文件必须在与包名称相匹配的目录结构中。
接口与类的区别:
​
1)接口不能用于实例化对象。
​
2)接口没有构造方法。
​
3)接口中所有的方法必须是抽象方法。
​
4)接口不能包含成员变量,除了 static 和 final 变量。
​
5)接口不是被类继承了,而是要被类实现。
​
6)接口支持多继承(接口不能继承类,接口只能继承接口)。
接口特性:
​
1)接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
​
2)接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
​
3)接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
package com.zpark.oop.day07;
public interface
Demo05 {
//
public Demo05(); 接口中不能有构造器
// 在接口中定义的变量默认为 public final static修饰
public final static String NAME = "大锤";
// 接口中的方法必须全部是抽象方法
public abstract void a();
int b();
}
抽象类和接口的区别:
​
1. 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
​
2. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
​
3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
​
4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
内部类
​
java内部类的几种类型:成员内部类,静态内部类,方法内部类,匿名内部类。
成员内部类:成员内部类是类内部的非静态类。成员内部类不能定义静态方法和变量(final修饰的除外)。这是因为成员内部类是非静态的,类初始化的时候先初始化静态成员,如果允许成员内部类定义静态变量,那么成员内部类的静态变量初始化顺序是有歧义的。
成员内部类的使用方法:
​
1、 Inner 类定义在 Outer 类的内部,相当于 Outer 类的一个成员变量的位置,Inner 类可以使用任意访问控制符,如 public 、 protected 、 private 等
​
2、 Inner 类中定义的 test() 方法可以直接访问 Outer 类中的数据,而不受访问控制符的影响,如直接访问 Outer 类中的私有属性a
​
3、 定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去 new 一个内部类对象,即:内部类 对象名 = 外部类对象.new 内部类( );
静态内部类:
静态内部类是 static 修饰的内部类,这种内部类的特点是:
​1、 静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问。
​2、 如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;如果外部类的静态成员与
内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员。
​3、 创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名= new 内部类();
方法内部类(局部内部类):
​
方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内可以使用。
需要注意:由于方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问控制符和 static 修饰符。
枚举
​
枚举是一个被命名的整型常数的集合,用于声明一组带标识符的常数。类似这种当一个变量有几种固定可能的取值时,就可以将它定义为枚举类型。
声明枚举
​
声明枚举时必须使用 enum 关键字,然后定义枚举的名称、可访问性、基础类型和成员等。
任意两个枚举成员不能具有相同的名称,且它的常数值必须在该枚举的基础类型的范围之内,多个枚举成员之间使用逗号分隔。
提示:如果没有显式地声明基础类型的枚举,那么意味着它所对应的基础类型是 int。
枚举类
Java 中的每一个枚举都继承自 java.lang.Enum 类。当定义一个枚举类型时,每一个枚举类型成员都可以看作是 Enum 类的实例,这些枚举成员默认都被 final、public, static 修饰,当使用枚举类型成员时,直接使用枚举名称调用成员即可。所有枚举实例都可以调用 Enum 类的方法。
为枚举添加方法
​
Java 为枚举类型提供了一些内置的方法,同时枚举常量也可以有自己的方法。此时要注意必须在枚举实例的最后一个成员后添加分号,而且必须先定义枚举实例。
Java 中的 enum 还可以跟 Class 类一样覆盖基类的方法。
字符串String处理:直接定义和使用String类定义;
将字符数组转为字符串:char[] ch = new char[]{‘H’,’e’,’l’,’l’,’o’}
创建建字符串
String str = new String(ch);
分配一个新字符串,该字符串包含字符数组参数的子数组中的字符:
offset参数是子数组第一个字符的索引,count参数指定子数组的长度。
复制子数组的内容;字符数组的后续修改不会影响新创建的字符串。
char[] ch1 = new char[]{'H', 'e', 'l', 'l', 'o', ',', 'w', 'o', 'r', 'l', 'd'};
String str1 = new String(ch1, 2, 8);
System.out.println(str1);
分配一个新字符串,该字符串包含来自Unicode码点数组参数子数组的字符:
offset参数是子数组第一个编码点的索引,count参数指定子数组的长度。
子数组的内容被转换为字符;int数组的后续修改不会影响新创建的字符串。
int[] arr = new int[]{65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75};
String str2 = new String(arr, 0, 5);
System.out.println(str2);
}
将字符串转为int类型的值前提是字符内容必须是纯数字,使用包装类进行转换。
String转换为int:
Integer.parselnt(str)
Integer.valueOf(str).intValue();
Int转换为String:
String s = String.valueOf(i);
String s = Integer.toString(i);
String s = “”+i;
将int类型数据转为String类型
int num1 = 56;
String str = num1 + "";
System.out.println(str + 1);
valueOf()方法将数据的内部格式转换为可读的形式。是一种静态方法,对于所有内置的类型,在字符串被重载,以便每一种类型都能被转换成字符串。
parse()
parseXxx(String)这种形式,是指把字符串转换为数值型;
toString()可以把一个引用类型转换为String字符串类型。
concat()方法:String类的concat()方法实现了将一个字符串连接到另外一个字符串后面。语法:字符串1.concat(字符串2);
其他类型数据直接使用“+”拼接;
获取字符串长度:
使用length(),语法:字符串名.length();
1、获取字符串长度
2、将字符串转大小写
3、去除字符串两端的空白
String str = "Hello Java";
// 使用length()函数获取字符串长度
System.out.println(str.length());
// 将字符串转为大写
System.out.println(str.toUpperCase());
// 将字符串转小写
System.out.println(str.toLowerCase());
String str1 = "
hello
";
System.out.println(str1.length());
// 取出字符串两端空白
String str2 = str1.trim();
System.out.println(str2.length());
字符串截取(substring()):
* substring(int start): 从指定位置开始截取,start表示开始位置下标
* substring(int start, int end):截取指定范围内的字符串,含前不含尾
八、分割字符串(spilt())​ String 类的 split() 方法可以按指定的分割符对目标字符串进行分割,分割后的内容存放在字符串数组中。
九、字符串的替换 1、replace() 方法​ replace() 方法用于将目标字符串中的指定字符(串)替换成新的字符(串),其语法格式如下:```java字符串.replace(String oldChar, String newChar)```​ 其中,oldChar 表示被替换的字符串;newChar 表示用于替换的字符串。replace() 方法会将字符串中所有 oldChar 替换成 newChar
十、字符串比较​ 字符串比较是常见的操作,包括比较相等、比较大小、比较前缀和后缀串等。在 Java 中,比较字符串的常用方法有 3 个:equals() 方法、equalsIgnoreCase() 方法、 compareTo() 方法。## 1、equals() 方法​ equals() 方法将逐个地比较两个字符串的每个字符是否相同。如果两个字符串具有相同的字符和长度,它返回 true,否则返回 false。
十一、1、equalsIgnoreCase() 方法​ equalsIgnoreCase() 方法的作用和语法与 equals() 方法完全相同,唯一不同的是 equalsIgnoreCase() 比较时不区分大小写。当比较两个字符串时,它会认为 A-Z 和 a-z 是一样的。
2、equals()与==的比较​ 理解 equals() 方法和`==`运算符执行的是两个不同的操作是重要的。如同刚才解释的那样,equals() 方法比较字符串对象中的字符。而`==`运算符比较两个对象引用看它们是否引用相同的实例
1、4、compareTo() 方法​ 通常,仅仅知道两个字符串是否相同是不够的。对于排序应用来说,必须知道一个字符串是大于、等于还是小于另一个。一个字符串小于另一个指的是它在字典中先出现。而一个字符串大于另一个指的是它在字典中后出现。字符串(String)的 compareTo() 方法实现了这种功能。​ compareTo() 方法用于按字典顺序比较两个字符串的大小,该比较是基于字符串各个字符的 Unicode 值。
2、**提示:**如果两个字符串调用 equals() 方法返回 true,那么调用 compareTo() 方法会返回 0。
十二、字符串查找​
在给定的字符串中查找字符或字符串是比较常见的操作。字符串查找分为两种形式:一种是在字符串中获取匹配字符(串)的索引值,另一种是在字符串中获取指定索引位置的字符。## 1、根据字符查找​ String 类的 indexOf() 方法和 lastlndexOf() 方法用于在字符串中获取匹配字符(串)的索引值。
1.1、indexOf() 方法​ indexOf() 方法用于返回字符(串)在指定字符串中首次出现的索引位置,如果能找到,则返回索引值,否则返回 -1。
1.2、fromIndex 表示查找时的起始索引,如果不指定 fromIndex,则默认从指定字符串中的开始位置(即 fromIndex 默认为 0)开始查找。
1.3、lastlndexOf() 方法​ lastIndexOf() 方法用于返回字符(串)在指定字符串中最后一次出现的索引位置,如果能找到则返回索引值,否则返回 -1。
十三、StringBuffer 类是可变字符串类,创建 StringBuffer 类的对象后可以随意修改字符串的内容。每个 StringBuffer 类的对象都能够存储指定容量的字符串,如果字符串的长度超过了 StringBuffer 类对象的容量,则该对象的容量会自动扩大
十四、删除字符串​ StringBuffer 类提供了 deleteCharAt() 和 delete() 两个删除字符串的方法,下面详细介绍。**1、deleteCharAt() 方法**​ deleteCharAt() 方法用于移除序列中指定位置的字符,该方法的语法格式如下:```javaStringBuffer 对象.deleteCharAt(int index);```​ deleteCharAt() 方法的作用是删除指定位置的字符,然后将剩余的内容形成一个新的字符串
十五、StringBuilder 和 StringBuffer 功能基本相似,方法也差不多。不同的是,StringBuffer 是线程安全的,而 StringBuilder 则没有实现线程安全功能,所以性能略高。因此在通常情况下,如果需要创建一个内容可变的字符串对象,则应该优先考虑使用 StringBuilder 类。
十六、
1、静态常量​ Math 类中包含 E 和 PI 两个静态常量,正如它们名字所暗示的,它们的值分别等于 e(自然对数)和 π(圆周率)。
2、生成随机数(random()和Random类)​ 在 Java 中要生成一个指定范围之内的随机数字有两种方法:一种是调用 Math 类的 random() 方法,一种是使用 Random 类。​ Random 类提供了丰富的随机数生成方法,可以产生 boolean、int、long、float、byte 数组以及 double 类型的随机数,这是它与 random() 方法最大的不同之处。random() 方法只能产生 double 类型的 0~1 的随机数。​ Random 类位于 java.util 包中,该类常用的有如下两个构造方法。​ **Random():**该构造方法使用一个和当前系统时间对应的数字作为种子数,然后使用这个种子数构造 Random 对象。​ **Random(long seed):**使用单个 long 类型的参数创建一个新的随机数生成器。​ Random 类提供的所有方法生成的随机数字都是均匀分布的,也就是说区间内部的数字生成的概率是均等的,在表 1 中列出了 Random 类中常用的方法
3、Math 类的 random() 方法没有参数,它默认会返回大于等于 0.0、小于 1.0 的 double 类型随机数,即 0<=随机数<1.0。对 random() 方法返回的数字稍加处理,即可实现产生任意范围随机数的功能。
4、BigInteger 类型的数字范围较 Integer 类型的数字范围要大得多。BigInteger 支持任意精度的整数,也就是说在运算中 BigInteger 类型可以准确地表示任何大小的整数值。​ 除了基本的加、减、乘、除操作之外,BigInteger 类还封装了很多操作,像求绝对值、相反数、最大公约数以及判断是否为质数等。​ 要使用 BigInteger 类,首先要创建一个 BigInteger 对象。BigInteger 类提供了很多种构造方法,其中最直接的一种是参数以字符串形式代表要处理的数字。
5、igDecimal 类​ BigInteger 和 BigDecimal 都能实现大数字的运算,不同的是 BigDecimal 加入了小数的概念。一般的 float 和 double 类型数据只能用来做科学计算或工程计算,但由于在商业计算中要求数字精度比较高,所以要用到 BigDecimal 类。BigDecimal 类支持任何精度的浮点数,可以用来精确计算货币值。​ BigDecimal 常用的构造方法如下。​ 1、BigDecimal(double val):实例化时将双精度型转换为 BigDecimal 类型。​ 2、BigDecimal(String val):实例化时将字符串形式转换为 BigDecimal 类型。​ BigDecimal 类的方法可以用来做超大浮点数的运算,像加、减、乘和除等。在所有运算中,除法运算是最复杂的,因为在除不尽的情况下,末位小数的处理方式是需要考虑的。
6、Java时间日期的处理​ 在 Java 中获取当前时间,可以使用 java.util.Date 类和 java.util.Calendar 类完成。其中,Date 类主要封装了系统的日期和时间的信息,Calendar 类则会根据系统的日历来解释 Date 对象。下面详细介绍这两个类的具体使用。## 1、Date 类​ Date 类表示系统特定的时间戳,可以精确到毫秒。Date 对象表示时间的默认顺序是星期、月、日、小时、分、秒、年。#### 1.1、构造方法​ Date 类有如下两个构造方法。​ 1、Date():此种形式表示分配 Date 对象并初始化此对象,以表示分配它的时间(精确到毫秒),使用该构造方法创建的对象可 以获取本地的当前时间。​ 2、Date(long date):此种形式表示从 GMT 时间(格林尼治时间)1970 年 1 月 1 日 0 时 0 分 0 秒开始经过参数 date 指定的毫 秒数。
7、Calendar 类​ Calendar 类是一个抽象类,它为特定瞬间与 YEAR、MONTH、DAY_OF—MONTH、HOUR 等日历字段之间的转换提供了一些方法,并为操作日历字段(如获得下星期的日期) 提供了一些方法。​ 创建 Calendar 对象不能使用 new 关键字,因为 Calendar 类是一个抽象类,但是它提供了一个 getInstance() 方法来获得 Calendar类的对象。getInstance() 方法返回一个 Calendar 对象,其日历字段已由当前日期和时间初始化
十七、
1、 实现 int 和 Integer 的相互转换**​ 可以通过 Integer 类的构造方法将 int 装箱,通过 Integer 类的 intValue 方法将 Integer 拆箱。
2、 将字符串转换为数值类型**​ 在 Integer 和 Float 类中分别提供了以下两种方法:​ ① Integer 类(String 转 int 型)```javaint parseInt(String s);```​ s 为要转换的字符串。​ ② Float 类(String 转 float 型)```javafloat parseFloat(String s)```​ **注意:**使用以上两种方法时,字符串中的数据必须由数字组成,否则转换时会出现程序错误。
3、将整数转换为字符串**​ Integer 类有一个静态的 toString() 方法,可以将整数转换为字符串
4、Object类​ Object 是 Java 类库中的一个特殊类,也是所有类的父类。也就是说,Java 允许把任何类型的对象赋给 Object 类型的变量。当一个类被定义后,如果没有指定继承的父类,那么默认父类就是 Object 类。因此,以下两个类表示的含义是一样的。
5、toString() 方法​ toString() 方法返回该对象的字符串,当程序输出一个对象或者把某个对象和字符串进行连接运算时,系统会自动调用该对象的 toString() 方法返回该对象的字符串表示。​ Object 类的 toString() 方法返回“运行时类名@十六进制哈希码”格式的字符串,但很多类都重写了 Object 类的 toString() 方法,用于返回可以表述该对象信息的字符串。
6、equals() 方法​ 在前面学习字符串比较时,曾经介绍过两种比较方法,分别是`==`运算符和 equals() 方法,`==`运算符是比较两个引用变量是否指向同一个实例,equals() 方法是比较两个对象的内容是否相等,通常字符串的比较只是关心内容是否相等。
7、getClass() 方法​ getClass() 方法返回对象所属的类,是一个 Class 对象。通过 Class 对象可以获取该类的各种信息,包括类名、父类以及它所实现接口的名字等。
8、Integer类​ Integer 类在对象中包装了一个基本类型 int 的值。Integer 类对象包含一个 int 类型的字段。此外,该类提供了多个方法,能在 int 类型和 String 类型之间互相转换,还提供了处理 int 类型时非常有用的其他一些常量和方法。## 1、Integer 类的构造方法​ Integer 类中的构造方法有以下两个:​ **Integer(int value):**构造一个新分配的 Integer 对象,它表示指定的 int 值。​ **Integer(String s):**构造一个新分配的 Integer 对象,它表示 String 参数所指示的 int 值。
9、Integer 类的常量​ Integer 类包含以下 4 个常量。​ **MAX_VALUE:**值为 231-1 的常量,它表示 int 类型能够表示的最大值。​ **MIN_VALUE:**值为 -231 的常量,它表示 int 类型能够表示的最小值。​ **SIZE:**用来以二进制补码形式表示 int 值的比特位数。​ **TYPE:**表示基本类型 int 的 Class 实例。
10、Float 类的构造方法​ Float 类中的构造方法有以下 3 个。​ **Float(double value):**构造一个新分配的 Float 对象,它表示转换为 float 类型的参数。​ **Float(float value):**构造一个新分配的 Float 对象,它表示基本的 float 参数。​ **Float(String s):**构造一个新分配的 Float 对象,它表示 String 参数所指示的 float 值。
11、Float 类的常用常量​ 在 Float 类中包含了很多常量,其中较为常用的常量如下。​ **MAX_VALUE:**值为 1.4E38 的常量,它表示 float 类型能够表示的最大值。​ **MIN_VALUE:**值为 3.4E-45 的常量,它表示 float 类型能够表示的最小值。​ **MAX_EXPONENT: **有限 float 变量可能具有的最大指数。​ **MIN_EXPONENT:**标准化 float 变量可能具有的最小指数。​ **MIN_NORMAL:**保存 float 类型数值的最小标准值的常量,即 2-126。​ **NaN:**保存 float 类型的非数字值的常量。​ **SIZE:**用来以二进制补码形式表示 float 值的比特位数。​ **TYPE:**表示基本类型 float 的 Class 实例。
12、Double类​ Double 类在对象中包装了一个基本类型 double 的值。Double 类对象包含一个 double 类型的字段。此外,该类还提供了多个方法,可以将 double 类型与 String 类型相互转换,同时 还提供了处理 double 类型时比较常用的常量和方法。## 1、Double 类的构造方法​ Double 类中的构造方法有如下两个。​ **Double(double value):**构造一个新分配的 Double 对象,它表示转换为 double 类型的参数。​ **Double(String s):**构造一个新分配的 Double 对象,它表示 String 参数所指示的 double 值。
13、Number类​ Number 是一个抽象类,也是一个超类(即父类)。Number 类属于 java.lang 包,所有的包装类(如 Double、Float、Byte、Short、Integer 以及 Long)都是抽象类 Number 的子类。
14、在 validateUser() 方法中,使用 for 循环遍历用户输入的用户名、密码和年龄,对其每个字符进行验证,判断其是否符合要求。在验证的过程中,分别使用了 Character 类的 isLetter() 方法、isLetterOrDigit() 方法和 isDigit() 方法。
15、Byte 类的构造方法​ Byte 类提供了两个构造方法来创建 Byte 对象。
十周
System类
System 类位于 java.lang 包,代表当前 Java 程序的运行平台,系统级的很多属性和控制方法都放置在该类的内部。由于该类的构造方法是 private 的,所以无法创建该类的对象,也就是无法实例化该类。
System 类提供了一些类变量和类方法,允许直接通过 System 类来调用这些类变量和类方法。
System 类的成员变量
System 类有 3 个静态成员变量,分别是 PrintStream out、InputStream in 和 PrintStream err。
JDK自带记录日志类
每个初学者都很熟悉在有问题的代码中使用 System.out.println 方法在控制台打印消息,来帮助观察程序运行的操作过程。如果你使用
System.out.println 方法,一旦发现问题的根源,就要将这些语句从代码中删去。如果接下来又出现了问题,就需要再插入几个调用 System.out.println 方法的语句,如此反复,增加了工作量。日志用来记录程序的运行轨迹,方便查找关键信息,也方便快速定位解决问题。
可以使用 setLevel 方法设置级别,例如`logger.setLevel(Level.FINE);`可以将 FINE 和更高级别的都记录下来。另外,还可以使用 Level.ALL 开启所有级别的记录,或者使用 Level.OFF 关闭所有级别的记录。
注意:如果将记录级别设计为 INFO 或者更低,则需要修改日志处理器的配置。默认的日志处理器不会处理低于 INFO 级别的信息。
修改日志管理器配置
可以通过编辑配置文件来修改日志系统的各种属性。在默认情况下,配置文件存在于 jre 安装目录下“jre/lib/logging.properties”。要想使用另一个配置文件,就要将 java.util.logging.config.file 特性设置为配置文件的存储位置,并用下列命令启动应用程序
Lambda 表达式
Java 中 Lambda 表达式
1、Lambda 简介
Lambda 表达式(Lambda expression)是一个匿名函数,基于数学中的λ演算得名,也可称为闭包(Closure)。现在很多语言都支持 Lambda 表达式,如 C++、C#、Java、 Python 和 JavaScript 等。
// 可计算接口
public interface Calculable {
// 计算两个int数值
int calculateInt(int a, int b);
}
​
Calculable 接口只有一个方法 calculateInt,参数是两个 int 类型,返回值也是 int 类型。
// 实现加法计算Calculable对象
Calculable f1 = calculate('+');
// 实现减法计算Calculable对象
Calculable f2 = calculate('-');
// 调用calculateInt方法进行加法计算
System.out.println(n1 + "+" + n2 + "=" + f1.calculateInt(n1, n2));
// System.out.printf("%d + %d = %d n", n1, n2, f1.calculateInt(n1, n2));
// 调用calculateInt方法进行减法计算
System.out.println(n1 + "-" + n2 + "=" + f1.calculateInt(n1, n2));
// System.out.printf("%d - %d = %d n", n1, n2, f2.calculateInt(n1, n2));
}
常见的输出形式:
1、printf 主要继承了C语言中 printf 的一些特性,可以进行格式化输出。
2、print 就是一般的标准输出,但是不换行。
3、println 和 print 基本没什么差别,就是最后会换行。
箭头操作符:
->被称为箭头操作符或 Lambda 操作符,箭头操作符将 Lambda 表达式拆分成两部分:
- 左侧:Lambda 表达式的参数列表。
- 右侧:Lambda 表达式中所需执行的功能,用`{ }`包起来,即 Lambda 体。
2、Java Lambda 表达式的优缺点
优点:
1. 代码简洁,开发迅速
2. 方便函数式编程
3. 非常容易进行并行计算
4. Java 引入 Lambda,改善了集合操作(引入 Stream API)
缺点:
1. 代码可读性变差
2. 在非并行计算中,很多计算未必有传统的 for 性能要高
3. 不容易进行调试
3、函数式接口
Lambda 表达式实现的接口不是普通的接口,而是函数式接口。如果一个接口中,有且只有一个抽象的方法(Object 类中的方法不包括在内),那这个接口就可以被看做是函数式接口。这种接口只能有一个方法。如果接口中声明多个抽象方法,那么 Lambda 表达式会发生编译错误。
Lambda表达式的使用
1、作为参数使用Lambda表达式:Lambda 表达式一种常见的用途就是作为参数传递给方法,这需要声明参数的类型声明为函数式接口类型。
2、访问变量:Lambda 表达式可以访问所在外层作用域定义的变量,包括成员变量和局部变量。
2.1、访问成员变量:成员变量包括实例成员变量和静态成员变量。在 Lambda 表达式中可以访问这些成员变量,此时的 Lambda 表达式与普通方法一样,可以读取成员变量,也可以修改成员变量。
2.2、访问局部变量:对于成员变量的访问 Lambda 表达式与普通方法没有区别,但是访问局部变量时,变量必须是 final 类型的(不可改变)。
3、方法引用
方法引用可以理解为 Lambda 表达式的快捷写法,它比 Lambda 表达式更加的简洁,可读性更高,有很好的重用性。如果实现比较简单,复用的地方又不多,推荐使用 Lambda 表达式,否则应该使用方法引用。
Jav异常处理:
异常简介
Java 中的异常又称为例外,是一个在程序执行期间发生的事件,它中断正在执行程序的正常指令流。为了能够及时有效地处理程序中的运行错误,必须使用异常类,这可以让程序具有极好的容错性且更加健壮。
在 Java 中一个异常的产生,主要有如下三种原因:
1、Java 内部错误发生异常,Java 虚拟机产生的异常。
2、编写的程序代码中的错误所产生的异常,例如空指针异常、数组越界异常等。
3、通过 throw 语句手动生成的异常,一般用来告知该方法的调用者一些必要信息。
Java 通过面向对象的方法来处理异常。在一个方法的运行过程中,如果发生了异常,则这个方法会产生代表该异常的一个对象,并把它交给运行时的系统,运行时系统寻找相应的代码来处理这一异常。我们把生成异常对象,并把它提交给运行时系统的过程称为拋出(throw)异常。运行时系统在方法的调用栈中查找,直到找到能够处理该类型异常的对象,这一个过程称为捕获(catch)异常。
异常类型
在 Java 中所有异常类型都是内置类 java.lang.Throwable 类的子类,即 Throwable 位于异常类层次结构的顶层。Throwable 类下有两个异常分支 Exception 和 Error。
Throwable 类是所有异常和错误的超类,下面有 Error 和 Exception 两个子类分别表示错误和异常。其中异常类 Exception 又分为运行时异常和非运行时异常,这两种异常有很大的区别,也称为不检查异常(Unchecked Exception)和检查异常(Checked Exception)。
​
1、Exception 类用于用户程序可能出现的异常情况,它也是用来创建自定义异常类型类的类。
​
2、Error 定义了在通常环境下不希望被程序捕获的异常。一般指的是 JVM 错误,如堆栈溢出。
Exception 类型的异常处理。
运行时异常都是 RuntimeException 类及其子类异常,如 NullPointerException、IndexOutOfBoundsException 等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般由程序逻辑错误引起,程序应该从逻辑角度尽可能避免这类异常的发生。
非运行时异常是指 RuntimeException 以外的异常,类型上都属于 Exception 类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如 IOException、ClassNotFoundException 等以及用户自定义的 Exception 异常(一般情况下不自定义检查异常)。
二、Error和Exception的异同
Error(错误)和 Exception(异常)都是 java.lang.Throwable 类的子类,在 Java 代码中只有继承了 Throwable 类的实例才能被 throw 或者 catch。
Exception 和 Error 体现了 Java 平台设计者对不同异常情况的分类,Exception 是程序正常运行过程中可以预料到的意外情况,并且应该被开发者捕获,进行相应的处理。Error 是指正常情况下不大可能出现的情况,绝大部分的 Error 都会导致程序处于非正常、不可恢复状态。所以不需要被开发者捕获。
Error 错误是任何处理技术都无法恢复的情况,肯定会导致程序非正常终止。并且 Error 错误属于未检查类型,大多数发生在运行时。Exception 又分为可检查(checked)异常和不检查(unchecked)异常,可检查异常在源码里必须显示的进行捕获处理,这里是编译期检查的一部分。不检查异常就是所谓的运行时异常,通常是可以编码避免的逻辑错误,具体根据需要来判断是否需要捕获,并不会在编译器强制要求。
常见的 Error 和 Exception:
(1)运行时异常(RuntimeException):
​
NullPropagation:空指针异常;
​
ClassCastException:类型强制转换异常
​
IllegalArgumentException:传递非法参数异常
​
IndexOutOfBoundsException:下标越界异常
​
NumberFormatException:数字格式异常
(2)非运行时异常:
​
ClassNotFoundException:找不到指定 class 的异常
​
IOException:IO 操作异常
(3)错误(Error):
​
NoClassDefFoundError:找不到 class 定义异常
​
StackOverflowError:深递归导致栈被耗尽而抛出的异常
​
OutOfMemoryError:内存溢出异常
三、异常处理机制
Java 的异常处理通过 5 个关键字来实现:try、catch、throw、throws 和 finally。try catch 语句用于捕获并处理异常,finally 语句用于在任何情况下(除特殊情况外)都必须执行的代码,throw 语句用于拋出异常,throws 语句用于声明可能会出现的异常。
异常处理的机制如下:
​
1、在方法中用 try catch 语句捕获并处理异常,catch 语句可以有多个,用来匹配多个异常。
​
2、对于处理不了的异常或者要转型的异常,在方法的声明处通过 throws 语句拋出异常,即由上层的调用方法来处理。
tre catch语句:
try {
逻辑程序块
} catch(ExceptionType1 e) {
处理代码块1
} catch (ExceptionType2 e) {
处理代码块2
throw(e);
// 再抛出这个"异常"
} finally {
释放资源代码块}
在以上语法中,把可能引发异常的语句封装在 try 语句块中,用以捕获可能发生的异常。catch 后的( )里放匹配的异常类,指明 catch 语句可以处理的异常类型,发生异常时产生异常类的实例化对象。
如果 try 语句块中发生异常,那么一个相应的异常对象就会被拋出,然后 catch 语句就会依据所拋出异常对象的类型进行捕获,并处理。处理之后,程序会跳过 try 语句块中剩余的语句,转到 catch 语句块后面的第一条语句开始执行。
如果 try 语句块中没有异常发生,那么 try 块正常结束,后面的 catch 语句块被跳过,程序将从 catch 语句块后的第一条语句开始执行。
多重try catch语句:
在多个 catch 代码块的情况下,当一个 catch 代码块捕获到一个异常时,其它的 catch 代码块就不再进行匹配。
注意:捕获的多个异常类之间存在父子关系时,捕获异常时一般先捕获子类,再捕获父类。所以子类异常必须在父类异常的前面,否则子类捕获不到。
try catch finally语句
try catch 语句的执行过程,try 语句块和 catch 语句块有可能不被完全执行,而有些处理代码则要求必须执行。例如,程序在 try 块里打开了一些物理资源(如数据库连接、网络连接和磁盘文件等),这些物理资源都必须显式回收。 Java的垃圾回收机制不会回收任何物理资源,垃圾回收机制只回收堆内存中对象所占用的内存。 所以为了确保一定能回收 try 块中打开的物理资源,异常处理机制提供了 finally 代码块。
try {
// 可能会发生异常的语句
} catch(ExceptionType e) {
// 处理异常语句
} finally {
// 清理代码块
}
对于以上格式,无论是否发生异常(除特殊情况外),finally 语句块中的代码都会被执行。此外,finally 语句也可以和 try 语句匹配使用:
try {
// 逻辑代码块
} finally {
// 清理代码块
}
使用 try-catch-finally 语句时需注意以下几点:
1、异常处理语法结构中只有 try 块是必需的,也就是说,如果没有 try 块,则不能有后面的 catch 块和 finally 块;
2、catch 块和 finally 块都是可选的,但 catch 块和 finally 块至少出现其中之一,也可以同时出现;
3、可以有多个 catch 块,捕获父类异常的 catch 块必须位于捕获子类异常的后面;
4、不能只有 try 块,既没有 catch 块,也没有 finally 块;
5、多个 catch 块必须位于 try 块之后,finally 块必须位于所有的 catch 块之后。
6、finally 与 try 语句块匹配的语法格式,此种情况会导致异常丢失,所以不常见。
声明和抛出异常
1、throws 声明异常
当一个方法产生一个它不处理的异常时,那么就需要在该方法的头部声明这个异常,以便将该异常传递到方法的外部进行处理。使用 throws 声明的方法表示此方法不处理异常。
returnType method_name(paramList) throws Exception 1,Exception2,…{…}
returnType 表示返回值类型;method_name 表示方法名;paramList 表示参数列表;Exception 1,Exception2,… 表示异常类。
集合:集合类主要负责保存、盛装其他数据,因此集合类也被称为容器类。Java 所有的集合类都位于 java.util 包下,提供了一个表示和操作对象集合的统一构架,包含大量集合接口,以及这些接口的实现类和操作它们的算法。
集合类和数组不一样,数组元素既可以是基本类型的值,也可以是对象(实际上保存的是对象的引用变量),而集合里只能保存对象(实际上只是保存对象的引用变量)。
Collection接口
Collection 接口是 List、Set 和 Queue 接口的父接口,通常情况下不被直接使用。Collection 接口定义了一些通用的方法,通过这些方法可以实现对集合的基本操作。定义的方法既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合。
由于 Collection 是接口,不能对其实例化,所以上述代码中使用了 Collection 接口的 ArrayList 实现类来调用 Collection 的方法。add() 方法可以向 Collection 中添加一个元素,而调用 addAll() 方法可以将指定 Collection 中的所有元素添加到另一个 Collection 中。
List集合
List 是一个有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List 集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。List 集合默认按元素的添加顺序设置元素的索引,第一个添加到 List 集合中的元素的索引为 0,第二个为 1,依此类推。
​
List 实现了 Collection 接口,它主要有两个常用的实现类:ArrayList 类和 LinkedList 类。
1、ArrayList 类
ArrayList 类实现了可变数组的大小,存储在内的数据称为元素。它还提供了快速基于索引访问元素的方式,对尾部成员的增加和删除支持较好。使用 ArrayList 创建的集合,允许对集合中的元素进行快速的随机访问,不过,向 ArrayList 中插入与删除元素的速度相对较慢。
ArrayList 类的常用构造方法有如下两种重载形式:
​1、ArrayList():构造一个初始容量为 10 的空列表。
​2、ArrayList(Collection<?extends E>c):构造一个包含指定 Collection 元素的列表,这些元素是按照该 Collection 的迭代器返回它们的顺序排列的。
2、LinkedList类
LinkedList 类采用链表结构保存对象,这种结构的优点是便于向集合中插入或者删除元素。需要频繁向集合中插入和删除元素时,使用 LinkedList 类比 ArrayList 类效果高,但是 LinkedList 类随机访问元素的速度则相对较慢。这里的随机访问是指检索集合中特定索引位置的元素。
3、ArrayList 类和 LinkedList 类的区别
ArrayList 与 LinkedList 都是 List 接口的实现类,因此都实现了 List 的所有未实现的方法,只是实现的方式有所不同。
ArrayList 是基于动态数组数据结构的实现,访问元素速度优于 LinkedList。LinkedList 是基于链表数据结构的实现,占用的内存空间比较大,但在批量插入或删除数据时优于 ArrayList。
对于快速访问对象的需求,使用 ArrayList 实现执行效率上会比较好。需要频繁向集合中插入和删除元素时,使用 LinkedList 类比 ArrayList 类效果高。
不同的结构对应于不同的算法,有的考虑节省占用空间,有的考虑提高运行效率,对于程序员而言,它们就像是“熊掌”和“鱼肉”,不可兼得。高运行速度往往是以牺牲空间为代价的,而节省占用空间往往是以牺牲运行速度为代价的。
四、Set集合
Set 集合类似于一个罐子,程序可以依次把多个对象“丢进”Set 集合,而 Set 集合通常不能记住元素的添加顺序。也就是说 Set 集合中的对象不按特定的方式排序,只是简单地把对象加入集合。Set 集合中不能包含重复的对象,并且最多只允许包含一个 null 元素。
Set 实现了 Collection 接口,它主要有两个常用的实现类:HashSet 类和 TreeSet类。
1、HashSet 类
HashSet 是 Set 接口的典型实现,大多数时候使用 Set 集合时就是使用这个实现类。HashSet 是按照 Hash 算法来存储集合中的元素。因此具有很好的存取和查找性能。
HashSet 具有以下特点:
​1、不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化。
​2、HashSet 不是同步的,如果多个线程同时访问或修改一个 HashSet,则必须通过代码来保证其同步。
​3、集合元素值可以是 null。
HashSet 类的常用构造方法重载形式如下。
​1、HashSet():构造一个新的空的 Set 集合。
​2、HashSet(Collection<? extends E>c):构造一个包含指定 Collection 集合元素的新 Set 集合。其中,“< >”中的 extends 表示HashSet 的父类,即指明该 Set 集合中存放的集合元素类型。c 表示其中的元素将被存放在此 Set 集合中。
2、TreeSet 类
TreeSet 类同时实现了 Set 接口和 SortedSet 接口。SortedSet 接口是 Set 接口的子接口,可以实现对集合进行自然排序,因此使用 TreeSet 类实现的 Set 接口默认情况下是自然排序的,这里的自然排序指的是升序排序。
TreeSet 只能对实现了 Comparable 接口的类对象进行排序,因为 Comparable 接口中有一个 compareTo(Object o) 方法用于比较两个对象的大小。例如 a.compareTo(b),如果 a 和 b 相等,则该方法返回 0;如果 a 大于 b,则该方法返回大于 0 的值;如果 a 小于 b,则该方法返回小于 0 的值。
Map集合
Map 是一种键-值对(key-value)集合,Map 集合中的每一个元素都包含一个键(key)对象和一个值(value)对象。用于保存具有映射关系的数据。
Map 集合里保存着两组值,一组值用于保存 Map 里的 key,另外一组值用于保存 Map 里的 value,key 和 value 都可以是任何引用类型的数据。Map 的 key 不允许重复,value 可以重复,即同一个 Map 对象的任何两个 key 通过 equals 方法比较总是返回 false。
Map 中的 key 和 value 之间存在单向一对一关系,即通过指定的 key,总能找到唯一的、确定的 value。从 Map 中取出数据时,只要给出指定的 key,就可以取出对应的 value。
Map 接口主要有两个实现类:HashMap 类和 TreeMap 类。其中,HashMap 类按哈希算法来存取键对象,而 TreeMap 类可以对键对象进行排序。
六、遍历Map集合
Map 集合的遍历与 List 和 Set 集合不同。Map 有两组值,因此遍历时可以只遍历值的集合,也可以只遍历键的集合,也可以同时遍历。Map 以及实现 Map 的接口类(如 HashMap、TreeMap、LinkedHashMap、Hashtable 等)都可以用以下几种方式遍历。
1)在 for 循环中使用 entries 实现 Map 的遍历(最常见和最常用的)。
2)使用 for-each 循环遍历 key 或者 values,一般适用于只需要 Map 中的 key 或者 value 时使用。性能上比 entrySet 较好。
3)使用迭代器(Iterator)遍历。
4)通过键找值遍历,这种方式的效率比较低,因为本身从键取值是耗时的操作。
七、Collections类
Collections 类是 Java 提供的一个操作 Set、List 和 Map 等集合的工具类。Collections 类提供了许多操作集合的静态方法,借助这些静态方法可以实现集合元素的排序、查找替换和复制等操作。
Collections 提供了如下方法用于对 List 集合元素进行排序。
- void reverse(List list):对指定 List 集合元素进行逆向排序。
- void shuffle(List list):对 List 集合元素进行随机排序(shuffle 方法模拟了“洗牌”动作)。
- void sort(List list):根据元素的自然顺序对指定 List 集合的元素按升序进行排序。
- void sort(List list, Comparator c):根据指定 Comparator 产生的顺序对 List 集合元素进行排序。
- void swap(List list, int i, int j):将指定 List 集合中的 i 处元素和 j 处元素进行交换。
- void rotate(List list, int distance):当 distance 为正数时,将 list 集合的后 distance 个元素“整体”移到前面;当 distance 为负数时,将 list 集合的前 distance 个元素“整体”移到后面。该方法不会改变集合的长度。
八、Lambda表达式遍历Collection集合
Java 8 为 Iterable 接口新增了一个 forEach(Consumer action) 默认方法,该方法所需参数的类型是一个函数式接口,而 Iterable 接口是 Collection 接口的父接口,因此 Collection 集合也可直接调用该方法。
当程序调用 Iterable 的 forEach(Consumer action) 遍历集合元素时,程序会依次将集合元素传给 Consumer 的 accept(T t) 方法(该接口中唯一的抽象方法)。正因为 Consumer 是函数式接口,因此可以使用 Lambda 表达式来遍历集合元素。
九、Iterator(迭代器)
Iterator(迭代器)是一个接口,它的作用就是遍历容器的所有元素,也是 Java 集合框架的成员,但它与 Collection 和 Map 系列的集合不一样,Collection 和 Map 系列集合主要用于盛装其他对象,而 Iterator 则主要用于遍历(即迭代访问)Collection 集合中的元素。
Iterator 接口隐藏了各种 Collection 实现类的底层细节,向应用程序提供了遍历 Collection 集合元素的统一编程接口。Iterator 接口里定义了如下 4 个方法。
​	1、boolean hasNext():如果被迭代的集合元素还没有被遍历完,则返回 true。
​	2、Object next():返回集合里的下一个元素。
​	3、void remove():删除集合里上一次 next 方法返回的元素。
​	4、void forEachRemaining(Consumer action):这是 Java 8 为 Iterator 新增的默认方法,该方法可使用 Lambda 表达式来遍历集合元素。
注意:Iterator 必须依附于 Collection 对象,若有一个 Iterator 对象,则必然有一个与之关联的 Collection 对象。Iterator 提供了两个方法来迭代访问 Collection 集合里的元素,并可通过 remove() 方法来删除集合中上一次 next() 方法返回的集合元素。
当使用 Iterator 迭代访问 Collection 集合元素时,Collection 集合里的元素不能被改变,只有通过 Iterator 的 remove() 方法删除上一次 next() 方法返回的集合元素才可以。

最后

以上就是平常水蜜桃最近收集整理的关于【无标题】Java基础Java面向对象——OOP补充的全部内容,更多相关【无标题】Java基础Java面向对象——OOP补充内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(330)

评论列表共有 0 条评论

立即
投稿
返回
顶部