JavaSE知识内容
2020-07-18 16:49:10 84 举报
AI智能生成
JavaSE思维导图
作者其他创作
大纲/内容
Java 8
Lambda表达式
允许把函数作为一个方法的参数(函数作为参数传递到方法中)
<函数式接口> <变量名> = (参数1,参数2,...) -> //方法体
}
}
注意事项:
形参列表的数据类型会自动推断
如果形参列表为空,只需保留()
如果形参只有1个,()可以省略,只要参数名字
如果执行语句只有一句,且无返回值,{}可以省略
若有返回值,想省略{},return 也省略.保证执行语句只有1句
Lambda表达式不会生成单独的内部类文件
Lambda访问局部变量时,局部变量要修饰为final,如果没修饰,会自动添加final修饰
函数式接口
如果一个接口只有一个抽象方法,则该接口称为函数式接口
为了确保接口达到函数式接口的要求,可以添加@FunctionalInterface注解。明确要求该接口只能有一个抽象方法
内置四个核心函数式接口
Consumer<T> 消费性接口
void accept(T t);
Supplier<T> 供给型接口
T get();
Function<T,R> 函数型接口
R apply(T t);
Predicate<T> 断言型接口
boolean test(T t);
方法引用
方法引用是Lambda表达式的一种简写形式,如果Lambda表达式方法体中是调用一个特定的已存在的方法,可以使用方法引用代替
::操作符
对象::实例方法
类::静态方法
类::实例方法
类::new
注意:调用的方法参数列表、返回值类型,要与函数型接口中的方法参数列表、返回值类型一致
Stream API
处理数组、集合的抽象概念
流(与I/O不同)
可以执行复杂的查找、过滤、映射
创建
中间操作
终止操作
串行
stream();
并行
parallelStream();
数组
概念:一组连续的存储空间,存储多个相同数据类型的值。
数据类型[] 数组名 = new 数据类型[长度]; // int [] a = new int[5];
数组的组成概述
访问元素时,需要通过“下标”(从0开始,依次+1,自动生成)
访问的语法:数组名[下标]; //存:a[0] = 10; 取:a[0]
下标的范围:0 ~ 数组的长度-1
数组的复制
手工循环完成逐一的赋值
System.arraycopy(原数组,起始位置,新数组,起始位置,长度)
java.util.Arrays.copyOf(原数组,新长度)
基本类型变量与引用类型变量的区别
基本数据类型中,存储的是“值”
引用数据类型中,存储的是“地址”
排序
冒泡
相邻的两个值比较大小,互换位置
选择
固定值与其他值比较大小,互换位置
JDK
java.util.Arrays.sort(数组名);
二维数组
一维数组中的一维数组,数组中的元素,还是数组
创建语法:数据类型[][] 数组名 = new 数据类型[高维下标][低维下标]
访问元素的方式:数组名[高维下标][低维下标]
高维数组中保存了低维数组的地址,访问 数组[0] 等价于访问低维数组的地址
循环结构
概念:通过某个条件,重复的执行一段逻辑代码
循环结构
while
首次即有入口条件,先判断、再执行,适用于循环次数明确的情况
do while
首次没有入口条件,先执行、再判断,适用于循环次数不明确的情况
for
首次即有入口条件,先判断、再执行,适用于循环次数明确的情况
流程控制语句
break
中止、跳出:switch分支结构、循环结构
continue
结束本次、进入下一次循环
嵌套循环的概念
在一个完整的循环结构中,嵌套另一个循环结构
外层控制循环次数,内层控制单次循环操作
选择结构与分支结构
概念:根据已知条件进行落尽判断,满意条件后执行相应的操作
选择结构
基本if选择结构
if else 选择结构
多重if选择结构
相互排斥,有一个选项为true,其他选择不再执行,适用于区间判断
嵌套if选择结构
可以在一个选择结构当中,嵌套另一个选择结构,语法正确、格式正确的情况下,可以任意组合
分支结构
switch
可判断的byte、short、int、char、String(JDK7+)
switch中的多个case取值不可以相同
switch有自动向下贯穿的特性,如需要在某个选项执行后中止,需要追加break关键字
局部变量
概念:声明在函数内部的变量,必须先赋值再使用
作用范围:从定义行开始到所在的代码块结束
注意:多个变量在重合的作用范围内,不可出现重名
三大特性
封装
概念:尽可能隐藏对象的内部实现细节,控制对象的修改及访问的权限
由private修饰为私有的属性 + 提供set/get公共的访问方法
封装之后,不可直接访问属性,仅可通过get/set公共访问进行访问,可以在方法内部对数据进行过滤
继承
程序中的继承,是类与类之间特征和行为的一种赠与或获得
构成继承关系的要求:两个类之间必须满足"is a"的关系
选择父类:功能越精细、重合点越多,越接近直接父类
父类的抽象:在一组相同或类似的类中,抽取出共性的特征和行为,定义在父类中,实现重用
定义子类时:class 子类 extends 父类
产生继承关系后,子类可以使用父类中的属性和方法,也可以定义子类独有的属性和方法
Java为单继承,一个类只能有一个直接父类,但可以多级继承,属性和方法逐级叠加
不可继承:父类构造方法、父类中由private修饰的成员、父子类不在同一个包时由default修饰的成员
访问修饰符:private、default、protected、public
方法的覆盖:父类提供的方法无法满足子类需求、可在子类中定义相同的方法进行覆盖
覆盖的要求:方法名、参数表、返回值都与父类完全相同,仅访问修饰符可以与父类相同或更宽
方法覆盖后,执行时,优先执行子类覆盖后的版本
super关键字
使用" super. "的形式在子类中访问父类的属性和方法(解决属性遮蔽、方法覆盖调用)
使用" super() "、" super(实参) "在子类构造方法的首行,调用父类的构造方法,如果没有显示书写,则默认调用父类无参构造super()
同一个子类的构造方法中,super()、this()不可同时存在
构建子类对象时,先构建父类对象
多态
概念:父类引用指向子类对象,从而产生多种形态
父类引用仅可调用父类中所声明的属性和方法,不可调用子类独有的属性和方法
实际运行过程中,依旧遵循覆盖原则,如果子类覆盖了父类中的方法,则执行子类中覆盖后的方法,否则执行父类中的方法
多态应用场景一:使用父类作为方法形参实现多态,使方法参数的类型更为宽泛
多态应用场景二:使用父类作为方法返回值实现多态,使方法可以返回不同的子类对象
面向对象
什么是程序
程序简单来说就是为了模拟现实世界,解决现实问题而使用计算机语言的编写的指令集合
对象:一切客观存在的事物都是对象,万物皆对象。对象一定具有自己的特征和行为
类的抽取:在一组相同或类似的对象中,抽取出共性的特征和行为,保留所关注的部分。
类:定义了对象应具有的特征和行为,类是对象的模板。
对象:拥有多个特征和行为的实体,对象是类的实例。
接口
概念:接口是一种能力和约定
经验:Java单继承,当父类的方法种类无法满足子类需求时,可实现接口来扩充子类的能力
接口支持多实现,可为类扩充多种能力
规范:任何类在实现接口时,必须覆盖接口中所有的抽象方法,否则此类还是抽象类
实现接口中的抽象方法时,访问修饰符必须是public
接口应用同父类引用一样,可以声明为应用,指向实现类对象,仅可调用接口中所声明的方法,无法调用实现类独有方法
接口引用指向实现类对象时,需要调用实现类独有方法,可强转回实现类本身类型,进行调用
网络编程
网络
由点和线构成的,标识诸多对象间的相互联系
计算机网络
为实现资源共享和信息传递,通过通信线路连接起来的若干主机(Host)
互联网:点与点相连
万维网:端与端相连
物联网:物与物相连
网络编程:让计算机与计算机之间建立连接、进行通信
网络模型:OSI开放式系统互联
第一层:物理层(双绞线、光导纤维)
第二层:链路层(MAC)
第三层:网络层(IP地址)
第四层:传输层(TCP、UDP)
第五层:会话层(断点续传)
第六层:表示层(对数据转换以及加密)
第七层:应用层(HTTP、FTP、SMTP)
TCP/IP模型
一组用于实现网络互联的通信协议,分为了四层
第一层:网络接口层(以太网、ADSL
第二层:网络层(分配地址、传送数据,IP协议)
第三层:传输层(文本数据,协议是TCP、UDP协议)
第四层:应用层(负责传送最终形态的数据,协议为HTTP、FTp)
TCP/UDP
TCP:传输控制协议 是一种面向连接、可靠的、基于字节流的传输层通信协议。
数据大小无限制。
建立连接的过程需要三次握手
断开连接的过程需要四次挥手
UDP:用户数据报协议 是一种无连接的传输层协议,提供面向事务的简单、不可靠信息传送服务
每个包的大小是64KB
每个包的大小是64KB
IP
互联网协议/网际协议地址
分配给互联网设备的唯一数字标签(标识)
IPV4
4字节32位整数,分成4段8位的二进制数 255.255.255.255
IPV6
16字节128位整数,分成8段十六进制整数 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
回环地址
127.0.0.1 localhost
Port端口
在通信实体上进行网络通讯的程序的唯一标识
0~65535
Mysql:3306
Oracle:1521
Tomcat:8080
Web服务器:80
FTP服务器:21
InetAddress
标识互联网协议(IP)地址对象。封装了与该IP地址对象相关的所有信息,并提供常用方法
无法直接创建对象,构造方法私有化。需要通过getXXX方法来获得
基于TCP的网络编程
Socket
是网络中的一个通信节点
分为客户端Socket和服务端ServerSocket
通信要求:IP地址+端口号
语言基础
变量
计算机内存中的一块存储空间,是存储数量的基本单位
组成部分
数据类型
变量名
值
声明方式
先声明,再赋值
数据类型 变量名
变量名 = 值
变量名 = 值
声明并赋值
多个 同类型变量的声明与赋值
数据类型
基本数据类型
整数
byte
1个字节
-2^7~2^7-1
short
2个字节
-2^15~2^15-1
int
4个字节
-2^31~2^31-1
long
8个字节
-2^63~2^63-1
小数
float
double
布尔
boolean
字符
char
转义字符 \
\'
\"
\\
\t
\n
引用数据类型
字符串
String
数组
对象
数据类型转换
自动类型转换
两种类型相互兼容,目标类型大于源类型
强制类型转换
两种类型相互兼容,目标类型小于源类型
转换规则
整数长度足够,数据完整
整数长度不够,数据截断
小数强转整数,数据截断
字符整数互转,数据完整
保证正整数转换成字符,可以正常显示
boolean不可与其他类型转换
运算符
算数运算符
+ - * / % ++ --
赋值运算符
= += -= *= /= %=
关系运算符
> < >= <= == !=
逻辑运算符
&& || !
三元运算符
布尔表达式? 结果1 : 结果2
概述与环境搭建
初始Java
Java的由来
Java之父的介绍
詹姆斯·高斯林(高司令)
Java语言的特点
面向对象(使用计算机模拟现实世界,解决现实问题,贴近人类思维)
简单(相对C,C++, 不易造成内存溢出,较少代码量,代码可读性强)
跨平台(操作系统,服务器,数据库)
Java的运行机制
编译执行
将源文件编译成机器码,一次编译,多次执行
执行效率高,不可跨平台
解释执行
将源文件被一行一行解释,一行一行执行。不同的操作系统具备不同的解释器
执行效率低,可以跨平台
先编译,再解释
将源文件编译成字节码文件(平台中立文件.class),再将字节码文件进行解释执行
Java的设计理念:Write Once Run Anywhere
Java的环境搭建
名词的了解
JVM(Java Virtual Machine)虚拟机:使用软件在不同的操作系统中,模拟相同的环境
JRE(Java Runtime Environment)运行环境:包含JVM和解释器,完整的Java运行环境
JDK(Java Development Kit)开发环境:包含JRE + 类库 + 开发工具包(编译器和调试工具)
DOS操作
Windows键 + R
快捷键呼出运行窗口
再输入cmd并回车打开DOS命令窗口
常用的DOS命令
更换盘符:d:
查看当前目录下的文件及文件夹: dir
进入文件夹:cd文件夹的名字
返回上一级目录:cd ..
清空屏幕:cls
删除文件:del文件名称
删除文件夹:rd文件夹名称
退出:exit
第一个应用程序
编译:javac 源文件名称 .java
运行: java 类名
注意:Java语言严格区分大小写,写错一点,就有可能会造成程序的报错
Class (类) 的介绍
同一个源文件中可以定义多个类。编译后,每个类都会产生独立的.class文件。一个类中,只能有一个主函数,每一个类都可以有自己的主函数
public 修饰的类称为公开类,要求类名必须与文件名称完全相同
一个源文件中,只能有一个公开类
Package(包)的介绍
作用:类似于文件夹,用于管理字节码文件(.class)文件
语法:package 包名;
位置:必须写在源文件的第一行
带包编译:javac -d .源文件名称 .java(自动生成目录结构)
采用域名倒置的规则
Java的语言规范
书写格式
层级之间必须缩进(Tab:一个制表位),并且一行只写一句代码
代码注释
单行注释: //
多行注释:/* */
文档注释:(生成外部文档:Javadoc -d . HelloWorld.java):/** 文档注释 **/
标识符命名问题
语法规定
可以由:字母、数字、_ 、$、¥组成,但不能以数字开头
不能与关键字,保留字重名
字下美人数骆驼
约定俗成
望文生义,见名知意
类名由一个或多个单词组成,每个单词首字母大写
函数名,变量名由一个或多个单词组成,首单词首字母小写,拼接单词首字母大写,“驼峰式”
包名全小写,只可以使用特殊字符“.”,并且不能以“.”开头或结尾
常量全大写,多个单词用下划线“_”连接
函数
概念:实现特定功能的一段代码,可反复使用。
定义的位置
定义在类的内部,与main函数并列
函数的调用
函数名();
函数调用时,优先执行函数内部代码,结束后,返回到函数调用处,继续向下执行。
返回值与返回值类型
定义返回值类型:基本数据类型、引用数据类型、void
return value; //应用在具有返回值类型的函数中,函数结束时,伴有返回值,返回到函数调用处
return; //应用在返回值类型为void的函数中,遇到return时,直接结束函数
经验:一个函数制作一件事(单一职能原则)
递归
实际再发中,递归可以解决一些具有既定规律的问题。
当需要解决的问题可以拆分成若干个小问题,大问题、小问题的解决方法相同,有特定的规律,函数自己调用自己。
设置有效的出口条件,避免无穷递归。
三个修饰符
abstract(抽象的)
什么是抽象
似是而非的,像却又不是,具备某种对象的特征,但不完整
不该被创建的对象
抽象类、抽象方法
抽象类
概念
被abstract修饰的类,称为抽象类
抽象类意为不完整的类,不够具体的类
特性
抽象类无法实例化
抽象对象无法独立存在,即不能new对象
应用
abstract修饰类,此类不能new对象
作用
可被子类继承,提供共性属性和方法
可声明为引用,强制使用多态
抽象方法
被abstract修饰的方法,被称为抽象方法
意为不完整的方法,必须包含在抽象类方法中
特性
只有方法声明,没有方法实现
产生继承关系后,子类必须覆盖父类中所有的抽象方法,否则子类也必须是抽象类
static(静态的)
了解static
静态(static)可以修饰属性和方法
被称为属性(类属性)、静态方法(类方法)
静态成员是全类所有对象共享的成员
在全类中只有一份,不因创建多个对象而产生多份
不必创建对象,可直接通过类名访问
静态的特点
静态方法允许直接访问静态成员
静态方法不能直接访问非静态成员
静态方法中不允许使用this或super关键字
静态方法可以继承,但不能重写,没有多态
静态成员、类加载
类加载
JVM首次使用某个类时,需通过CLASSPATH查找该类的.class文件
将.class文件中对类的描述信息加载到内存中,进行保存,如:包名、类名、属性、方法、构造方法
加载时机
创建对象
创建子类对象
访问静态属性
调用静态方法
Class.forName("全限定名")
静态代码块
类加载时,触发静态代码块的执行(仅一次)
执行地位
静态属性初始化之后
作用
可为静态属性赋值,或必要的初始化行为
注意
方法只有被调用才会执行
final(最终的)
概念:最后的,不可更改的
fianl修饰类、方法
final修饰类:此类不能被继承
String、Math、System均为final修饰的类,不能被继承
final修饰方法:此方法不能被覆盖
意为最终方法,不支持子类以覆盖的形式修改
final变量
final修饰变量
此变量值不能被改变(常量)
注意
所有final修饰的变量只能赋值一次,值不允许改变
了解常量
实例常量
实例常量不再提供默认值,必须手动赋予初始值
赋值时机
显示初始化、动态代码块、构造方法
注意
如果在构造方法中为实例常量赋值,必须保证所有的构造方法都能对其正确赋值
静态常量
静态常量不再提供默认值,必须手动赋予初始值
赋值时机
显示初始化、静态代码块
对象常量
final修饰基本类型
值不可变
final修饰引用类型
地址不可变
内部类与常用类
内部类
什么是内部类?
概念:在一个类的内部再定义一个完整的类
特点
编译之后可生成独立的字节码文件
内部类可直接访问外部类的私有成员,而又不破坏封装
可为外部类提供必要的内部功能组件
分类
成员内部类
在类的内部定义,与实现变量,实例方法同级别的类
外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象
Outer out= new Outer();
Inner in = out.new Inner();
不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员
当外部类,内部类存在重名属性时,会优先访问内部类属性
成员内部类不能定义静态成员
静态内部类
不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员
成员内部类不能定义静态成员
只能直接访问外部类的静态成员(实例成员需实例化外部类对象)
Outer.Inner inner = new Outer.inner();
Outer.Inner.show();
局部内部类
定义在外部类方法中,作用范围和创建对象范围仅限于当前方法
局部内部类访问外部类当前方法中的局部变量时,因为无法保证变量的声明周期与自身相同,变量必须修饰为final
限制类的使用范围
匿名内部类
没有类名的局部内部类(一切特征都与局部内部类相同)
必须继承一个父类或者一个接口
定义类,实现类,创建对象的语法合并,只能创建一个该类的对象
优点
减少代码量
缺点
可读性差
Object类
超类,所有类的直接或间接父类,位于继承树的最顶层
任何类,如果没有书写extends显示继承某个类,都默认为直接继承Object类,否则为间接继承
Object类中定义的所有方法,是所有对象都具备的方法
Object类型可以存储任何对象
作为参数,可以接受任何对象
作为返回值,可以返回任何对象
Object方法
getClass()方法
public final Class<?>getClass(){}
返回引用中存储的实际对象类型
应用:通常用于判断两个引用中实际存储的对象类型是否一致
hashCode()方法
public int hashCode(){}
返回该对象的十六进制的哈希码值
哈希算法根据对象的地址或字符串或数字计算出来的int类型的数值
哈希码并不唯一,可保证相同对象返回相同哈希码,尽量保证不同对象返回不同哈希码
toString()方法
public String toString(){}
返回该对象的字符串表示(表现形式)
可以根据程序需求覆盖该方法,如:展示对象各个属性值
equals()方法
public String toString()
默认实现为(this == obj), 比较两个对象地址是否相同
可实现覆盖,比较两个对象的内容是否相同
equals()方法覆盖步骤
比较两个引用是否指向同一个对象
判断obj是否为null
判断两个引用指向的实际对象类型是否一致
强制类型转换
依次比较各个属性值是否相同
finalize()方法
当对象被判定为垃圾对象是,由JVM自动调用此方法,用以标记垃圾对象
垃圾对象: 没有有效引用指向此对象时,为垃圾对象
垃圾回收: 由GC销毁垃圾对象,释放数据存储空间
自动回收机制:JVM的内存耗尽,一次性回收所有垃圾对象
手动回收机制:使用System.gc(); 通知JVM执行垃圾回收
包装类
什么是包装类?
概念:基本数据类型所对应的引用数据类型
Object可统一所有数据,包装类的默认值是null
转型方法
Number父类提供的,常用作自动拆箱
parseXXX() 通过String进行包装类对象的机构件
valueOf()
通过基本类型构建
通过String构建
注意:在使用字符串构建数字型包装类型对象时,要保证类型的兼容,否则产生NumberFormatException。
JDK5之后,提供自动装箱、拆箱,简化使用包装类的编程过程
自动装箱时,会调用valueOf方法,Byte、Short、Integer、Long,四种整数包装类型都提供了对应的cache缓冲区,将常用的256个数字提 前创建对象并保存在数组中,实现复用。
String类
String
字符串是常量,创建之后不可改变。
字符串字面值存储在字符串池中,可以共享。
String s = "Hello"; //产生一个对象,字符串池中存储
String s = new String("Hello"); //产生两个对象,堆、池中各存储一个
常用方法
根据下标获取字符
public char charAt(int index)
判断当前字符串中是否包含str
public boolean contains(String str)
将字符串转换成数组
public char[] toChatArray()
查找str首次出现的下标,存在,则返回该下标;不存在,则返回-1
public int indexOf(String str)
查找字符串在当前字符串中最后一次出现的下标索引
public int lastIndexOf(String str)
返回字符串的长度
public int length()
去掉字符串前后的空格
public string trim()
将小写转换为大写
public String to Uppercase()
判断字符串是否以str结尾
public boolean endWith(String str)
将旧字符串转换为新字符串
public String repalce(char oldChar, char newChar)
根据str做拆分
public String[] split(String str)
StringBuilder
可变字符串,JDK5发布,线程不安全,运行效率快
StringBuffer
可变字符串,JDK1.0发布,线程安全,运行效率慢
BigDecimal
位置
java.math包中
作用
创建方式
BigDecimal bd = new BigDecimal("1.0")
方法
BigDecimal add(BigDecimal bd)
BigDecimal subtract(BigDecimal bd)
BigDecimal multiply(BigDecimal bd)
BigDecimal divide(BigDecimal bd)
add、subtract、multiply、divide(需要确定保留的精度、除不尽时的四舍五入策略)
利用BigDecimal可以进行数值计算
除法
BigDecimal(BigDecimal bd, int scal, RoundingMode mode)
参数scal
指定精确到小数点后几位
参数mode
指定小数部分的取舍模式,通常采用四舍五入的模式
取值为BigDecimal.ROUND_HALF_UP
集合
集合的概念
概念
对象的容器,存储对象的对象,可代替数组
特点
集合是容器的工具,定义个对多个对象进行操作的常用方法
位置
java.util.*
Collection体系集合
Collection父接口:代表一组任意的对象,无序、无下标
特点
代表一组任意类型的对象,无序,无下标
方法
boolean add(Object obj) //添加一个对象
boolean addAll(Collection c) //将一个集合中的所有对象添加到此集合
void clear() //清空此集合中的所有对象
boolean contains(Object o) //检车此集合中是否包含o对象
boolean equals(Object o) //比较此集合是否与指定对象相等
boolean idEmpty() //判断此集合是否为空
boolean remove(Object o) //在此集合中移除o对象
int size() //返回此集合中的元素个数
Object[] toArray() //将此集合转换成数组
List接口与实现类
List子接口
特点
有序、有下标、元素可以重复
方法
void add(int index, Object o) //在index位置插入对象o
boolean addAll(int index,Collection c) //将一个集合中的元素添加到集合中的index位置
Object get(int index) //返回集合中指定位置的元素
List subList(int fromIndex, int toIndex) //返回fromIndex和toIndex之间的集合元素
List实现类
ArrayList(重点)
数组结构存储,查询快,增删慢。
JDK1.2发布,运行效率快,线程不安全
Vector
数组结构存储,查询快,增删慢。
JDK1.0发布,运行效率慢,线程安全
LinkedList
链表结构存储,增删快,查询慢
不同实现方法
Set接口与实现类
Set子接口
特点
无序、无下标、元素不可重复
方法
全部继承自Collection中的方法
Set实现类
HashSet(重点)
基于HashCode实现元素不重复
当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入。
LinkedHashSet
链表实现的HashSet,按照链表进行存储,即可保留元素的插入顺序
SortedSet接口
TreeSet
基于排列顺序实现元素不重复。
实现了SortedSet接口,对集合元素自动排序。
元素对象的类型必须实现Comparable接口,指定排序规则。
通过CompareTo方法确定是否为重复元素
Map接口与实现类
Map结构
数组+链表+红黑树
Map父接口
特点
存储一对数据(Key-Value),无序、无下标,键(Key)不可重复,值(Value)可以重复
方法
V put(K key, V value) //将对象存入集合中,关联键值,key重复则覆盖原值
Object get(ObJect key) //根据键获取对应的值
Set //返回所有key
Collection value() //返回包含所有值的Collection集合
Set<Map,.Entry<K, V>> //键值匹配的Set集合
Map集合的实现类
HashMap【重点】
允许用null作为Key或者是Value
JDK1.2版本,线程不安全,运行效率快
HashMap底层是链表数组
Hashtable
不允许null作为Key或者是Value
JDK1.0版本提供,线程安全,运行效率慢
Properties
要求Key和Value都是String类型
setProperty();
getProperty();
常用于配置文件的读取
SortedMap接口
TreeMap
实现了SortedMap接口(是Map子接口),保证了有序性
默认的排序是根据key值进行升序排序
默认的排序是根据key值进行升序排序
可以对Key自动排序
泛型集合与工具类
泛型集合
概念
参数化类型、类型安全的集合,强制集合元素的类型一致
特点
编译时可检查,而非运行时抛出异常
访问时,不必类型转换(拆箱)
不同泛型之间引用不能相互赋值,泛型不存在多态
Colletions工具类
概念
集合工具类,定义了除了存取以外的集合常用方法
方法
public static void reverse(List<?> list) //反转集合中元素的顺序
public static void shuffle(List<?> list) //随机重置集合元素的顺序
public static void sort(LIst list) //升序排序(元素类型必须实现了Comparable接口)
总结
集合的概念
对象的容器,存储对象的对象,定义了对多个对象进行操作的常用方法
List集合
有序、有下标、元素可以重复。(ArrayLIst,LinkedList, Vector)
Set集合
无序、无下标、元素不可重复。(HashSet, LinkedHashSet, TreeSet)
Map集合
存储一对数据,无序、无下标、键不可重复、值可重复。(HashMap、HashTable)
Collections
集合工具类,定义了除了存取以外的集合常用方法
异常
概念:程序在运行过程中出现的特殊情况
异常的分类
Throwable:可抛出的,一切错误或异常的父类,位于java.lang包中
Error:JVM、硬件、执行逻辑错误,不能手动处理
Exception:程序在运行和配置过程中产生的问题,可处理
RuntimeException:运行时异常,可处理,可不处理
CheckedException:受查异常,必须处理
异常的产生
自动抛出异常:当程序在运行时遇到不符合规范的代码或结果时,会产生异常
手动抛出异常:throw new 异常类型("实际参数");
产生异常结果:相当于遇到return一句,导致程序因异常而终止
异常的传递
按照方法的调用链反向传递,如果始终没有处理异常,最终会由JVM进行默认处理(打印堆栈跟踪信息)
受查异常:throws 异常类型 声明异常,修饰在方法参数列表后端
由于运行时异常,是可处理可不处理,所以无需声明异常
异常的处理
try{}catch(Exception e){}finally{}
try-catch-finally中 如果try中已经return了值 那么finally中对返回值的操作不会改变返回值
try-catch-finally中 如果try中已经return了值 但是在return之前发生了异常 最终的finally将改变返回值
try-catch中都存在return的情况 如果执行了catch块 那么catch的return将影响返回值
try-catch-finally中都存在return 那么将以finally中的return为最终的返回值
常见异常处理结构
try{} catch(Exception e){}
try{} catch(){}
catch(){}
try{} catch(){}
finally{}
try{} catch(){}
catch(){}
finally{}
try{} finally{}
注意:多重catch情况下,异常捕获的顺序要遵循从子(小)到父(大)的顺序,父类异常在最后
注意:异常处理的必要性
任何程序都可能存在大量的未知问题、错误;
如果不对这些问题进行正确处理,则可能导致程序的中断,造成不必要的损失
如果不对这些问题进行正确处理,则可能导致程序的中断,造成不必要的损失
自定义异常
需要继承Exception或Exception的子类,常用RuntimeException
提供必要的构造方法
无参构造方法
String message参数的构造方法
异常方法覆盖
方法名、参数列表、返回值类型必须和父类相同
子类的访问修饰符和父类相同或比父类更宽
子类中的方法,不能抛出比父类更宽泛的异常,可以抛出更多的异常。
多线程
什么是线程
了解进程
什么是进程
程序是静止的,只有真正运行起来的程序,才被称为进程
单核CPU在任何时间点上,只能运行一个进程,并遵循“宏观并行,微观串行”
线程的概念
轻量级进程(Light Weiht Process)
程序中的一个顺序控制流程,同时也是CPU的基本调度单位
比如
迅雷是一个进程,当中的多个下载任务就是多个线程
Java虚拟机是一个进程,当中默认包含主线程(Main函数),可通过代码创建多个独立线程,与Main并发执行
线程的组成
任何一个线程都具有基本的组成部分
CPU时间片
操作系统(OS)会为每个线程分配时间
运行数据
堆空间:存储线程需使用的对象,多个线程可以共享堆中的对象
栈空间:存储线程需使用的局部变量,每个线程都拥有独立的栈
线程的逻辑代码
线程的创建
extends Thread 继承Thread类,自定义类变成线程类
implements Runnable
实现Runnable接口,赋予自定义类线程任务的能力
实现Runnable接口,不影响类继承,更灵活
线程创建后,需要调用start()方法,来启动线程,由JVM调用run()方法。
直接调用run()方法并不是线程的启动
线程的常见方法
休眠
public static void sleep(long millis)
当前线程主动休眠millis毫秒(注意:1000毫秒=1秒)
放弃
public static void yield()
当前线程主动放弃时间片,回到就绪状态,竞争下一次时间片
结合
public final void join()
允许其他线程加入到当前线程中,等待加入的线程执行完毕后,此线程再去竞争时间片执行
线程的状态
线程的状态(基本)
初始状态
就绪状态
运行状态
阻塞状态
死亡状态
线程的状态(等待)
初始状态
就绪状态
运行状态
终止状态
期限等待
无限期等待
线程的状态(阻塞)
初始状态
就绪状态
运行状态
期限等待
无限期等待
阻塞状态
线程安全
当多线程并发访问临界资源时,如果破坏原子操作,可能会造成数据不一致
临界资源:共享资源(同一对象),一次仅允许一个线程使用,才能保证其正确性
原子操作:不可分割的多步操作,被视作为一个整体,其顺序和步骤不可打乱或缺省
synchronized
同步代码块
利用同步代码块对临界资源加锁
注意
每个对象都有一个互斥锁标记的线程,才能进入对该对象加锁的同步代码块
线程退出同步代码块时,会释放相应的互斥锁标记
同步方法
对对象或者方法加锁
注意
只有在调用包含同步代码块的方法,或者同步方法是,才需要对象的锁标记
如果需要使用不包含同步代码块的方法,或普通方法时,则不需要锁标记,可直接调用
线程的通信
等待
public final void wait()
public final void wait(long timeout)
必须在对obj加锁的同步代码块中,在一个线程中,调用obj.wait()时,此线程会释放其拥有的所有锁标记,
同时此线程阻塞在obj的等待队列中,释放锁,进入等待队列
同时此线程阻塞在obj的等待队列中,释放锁,进入等待队列
通知(唤醒)
notify();
在等待队列中随机唤醒一个线程
notifyAll();
唤醒等待队列中所有的线程
必须在对obj加锁的同步代码块中,从obj的Waiting中释放一个或全部线程,对自身没有任何影响
线程的同步和异步
线程的同步
同步
形容一次方法调用,同步一旦开始,调用者必须等待该方法返回,才能继续
注意:单条执行路径
线程的异步
异步
形容一次方法调用,异步一旦开始,像是一次消息传递,调用者告知之后立即返回,二者竞争时间片,同时执行
注意:多条执行路径
高级多线程
线程池
线程池概念
现有问题
线程是宝贵的内存资源,单个线程约占1M空间,过多分配易造成内存溢出
频繁的创建及销毁线程会增加虚拟机回收频率,资源开销,造成程序性能下降
线程容器,可以设定线程分配的数量上限
预先创建线程对象,存入池中,并实现重用池中的线程对象
避免频繁的创建、销毁
线程池原理
将任务提交给线程池,由线程池分配线程,运行任务,并在当前任务结束后复用线程
获取线程池
常用的线程池接口和类(所在包java.util.concurrent)
Executor: 线程池的顶级接口
ExecutorService 线程池接口
Executors 工厂类
newFixedThreadPool(int nThreads);手动固定线程池的数量
newCachedThreadPool();动态数量线程池
线程中使用的接口
Callable<V>接口
public interface Callable<V>{}
public V call() throws Exception{}
JDK5加入,与Runnbale类似,都代表了一个线程任务
call方法,具有泛型返回值,可以声明异常
Future接口
异步接收ExecutorService.submit();方法返回的结果。包含了call方法的返回值
V get();以阻塞形式等待Future中的异步处理结果(call的返回值)
Lock接口
JDK5加入,与synchronized比较,显示定义,结构更灵活
提供更多使用性方法,功能更强大,性能更优越
常用方法
void lock(); //获取锁,如锁被占用,则等待
void unlock();释放锁
boolean tryLock(); //尝试获取锁,成功返回true,失败返回false,不阻塞)
重入锁
ReentrantLock : Lock接口的实现类,与synchronized一样具有互斥功能
读写锁
ReadWriteLock
ReentrantReadWriteLock
一种支持一写多读的同步锁,读写分离,可分配读锁、写锁
多次分配读锁,多个读操作可以并发执行
互斥规则
写-写:互斥,阻塞
读-写:互斥,读阻塞写、写阻塞读
读-读:不互斥、不阻塞
在读操作远远大于写操作的环境中,可在保障线程安全的情况下,提高运行效率
线程安全的集合
Collections中的工具方法
以synchronized开头的方法
JDK1.2提供,接口统一、维护性高,但是性能没有提升,均以synchronized实现
CopyOnWriteArrayList
线程安全的ArrayList,加强版读写分离
写有锁,读无锁,读写之间不阻塞,优于读写锁
写入时,先copy一个容器副本,再添加新元素,最后替换引用
CopyOnWriteArraySet
底层是CopyOnWriteArrayList
在添加新元素时,使用addIfAbsent();添加,遍历数组
如果重复了,则抛弃掉副本(复制的数组)
ConcurrentHashMap
JDK1.7
初始容量16段(Segment),使用分段锁设计
不对整个Map加锁,而是对每个Segment加锁
当多个对象存入同一个Segment时,才需要互斥
最理想的状态为16个对象分别存入16个Segment,并行数量16个
JDK1.8
Queue 队列
FIFO
抛出异常的方法
返回特殊值的方法(推荐)
ConcurrentLinkedQueue
线程安全、可高效读写的队列,高并发下性能最好的队列
采用的是无锁、CAS比较交换算法
V:要更新的变量 E:预期值 N:新值
只用当V==E时,V=N,否则标识已被更新过,则取消当前操作
BlockingQueue 阻塞队列
put 阻塞添加
take 阻塞移除
可用于解决消费者、生产者的问题
ArrayBlockingQueue
数组结构实现,有界队列,手工固定上限
LinkedBlockingQueue
链表结构实现,无界队列(默认上限是Integer.MAX_VALUE)
I/O框架
流
概念
内存与存储设备之间传输数据的通道
比如
水借助管道传输
数据借助流传输
流的分类
按方向
输入流
将<存储设备>中的内容读入到<内存>中
输出流
将<内存>中的内容写入到<存储设备>中
按单位
字节流
以字节为单位,可以读写所有的数据
字符流
以字符为单位,只能读写文本数据
按功能
节点流
具有实际传输数据的读写功能
过滤流
在节点流的基础之上增强功能
字节流
字节流的父类(抽象类)
InputStream:字节输入流
public int read() {}
public int read(byte[ ] b) {}
public int read(byte[ ] b, int off, int len) {}
OutputStream:字节输出流
public void write() {}
public int write(byte[ ] b) {}
public itn write(byte[ ] b, int off, int len) {}
字节节点流
FileInputStream
public int read(byte[ ] b) //从流中读取多个字节,将读到的内容存入b数组,返回实际读到的字节数;如果到达文件的尾部,则返回-1
FileIOutputStream
public void write(byte[ ] b) //一次写多个字节,将b数组中的所有字节,写入输出流
字节过滤流
缓冲区
BuffereOutpuStream
BufferedInputStream
作用
提高IO效率,减少访问磁盘的次数
数据存储在缓冲区中,flush是将缓存区的内容写入文件中,也可以直接close
对象字节流
ObjectOutputStream
ObjectInputStream
作用
增强了缓冲区功能
增强了读写8种基本数据类型和字符串功能
增强了读写对象的功能
readObject() 从流中读取一个对象
writeObject(Object obj) 从流中写入一个对象
注意
使用流传输对象的过程称为序列化,反序列化
对象序列化
对象序列化的细节
必须实现Serializable接口
必须保证其所有属性均可序列化
transient修饰为临时属性,不参会序列化
读取到文件尾部的标志:java.io.EOFException
字符编码
ISO-8859-1
收录ASCII外,还包括西欧、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号
UTF-8
针对Unicode可变长度字符编码
GB2312
简体中文
GBK
简体中文、扩展
注意
当编码方式和解码方式不一致时,会出现乱码
字符流
字符流的父类(抽象类)
Reader:字符输入流
public int read() {}
public int read(char c) {}
public int read(char c, int off, int len) {}
Writer:字符输出流
public void write(int n) {}
public void write(String str) {}
public void write(char[ ] c) {}
字符节点流
FileWriter
public void write(String str) {} //一次写多个字符,将b数组的所有字符,写入输出流
FileReader
public void write(char[ ] c) {} //从流中读取多个字符,将读到内存存入C数组,返回实际读到的字符数;如果到达文件的尾部,则返回-1
字符过滤流
缓冲流
BufferedWriter
BufferedReader
特点
支持输入换行符
可一次写一行,读一行
PrintWriter
封装了print() / println() 方法,支持写入后换行
字符节点流
桥转换流
InputStreamReader
OutputStreamReader
作用
可将字节流转换为字符流
可将字节流转换为字符流
使用步骤
创建节点流
[ 创建过滤流 设置字符编码集 ]
封装过滤流
读写数据
关闭流
File类
概念
代表了物理盘符中的一个文件或文件夹
方法
creatNewFile() //创建一个新的文件 返回true/false
Mkdir() //创建一个新的目录 返回true/false
mkdirs() //创建嵌套文件夹 返回true/false
Delete() //删除文件或目录 返回true/false
Exists() //判断File对象所代表的对象是否存在 返回true/false
getName() //取得名字
getPath() //返回相对路径
getAbsolutePath() //返回绝对路径
getPatent() //获取文件/目录所在的目录
isDirectory() //是否是目录 返回true/false
isFile() //是否是文件 返回true/false
length() //获取文件的长度
listFile() //列出目录中的所有内容
renameTo() //修改文件名为
FileFilter接口
public interface FileFilter
boolean accept(File pathname)
作用
当调用File类中listFiles()方法是,支持传入FileFilter接口接口实现类,对获取文件进行过滤,满足条件的文件或文件夹才能保存下来,出现在listFile()的返回值中
反射
类的对象:基于某个类new出来的对象,也被称为实例对象
类对象
类加载的产物,封装了一个类的所有信息(类名,父类,接口,属性,方法,构造方法)
获取类对象的方法
通过类的对象,获取类对象
Person p =new Person(); Class c =p.getClass();
通过类名获取类对象
Class c = 类名.class;
通过静态方法获取类对象
Class c =Class.forName("包名,类名");
常见方法
public String getName() //获取类对象名
public Package getPackage() //获取指定包名
public Class<? super T> getSupercalass() //获取父类Class对象
public Class<?>[] getInterfaces() //获取实现的接口
public Field[] getFields() //获取属性
public Method[] getMethods() // 获取方法
public Constructor<?>[] getConstructors() //获取构造方法
public T newInstance() //获取对象
设计模式
工厂设计模式
开发中有一个非常重要的原则,“开闭原则”,对拓展开放,对修改关闭
工厂模式主要负责对象创建的问题
可通过反射进行工厂模式的设计,完成动态的对象创建
工厂模式分类
创建对象工厂
创建对象并调用方法的工厂
单例设计模式
单例(Singleton):只允许创建一个该类的对象
方式1:饿汉式(类加载时创建,天生线程安全)
方式2:懒汉式(使用时创建,线程不安全,加同步)
方式3:懒汉式(使用时创建,线程安全)
收藏
0 条评论
下一页