Java知识点总结
2021-05-17 18:53:21 145 举报
AI智能生成
Java是一种广泛使用的面向对象编程语言,具有跨平台、安全性高、易于维护等特点。其核心知识点包括数据类型、运算符、流程控制、数组、字符串处理、类和对象、继承和多态、接口和抽象类、异常处理等。此外,Java还提供了丰富的标准库,如集合框架、输入输出流、网络编程等。Java的语法规范严谨,对代码格式有严格要求,有助于编写高质量的代码。掌握Java编程,可以为开发各类应用提供基础,如桌面应用、移动应用、Web应用等。
作者其他创作
大纲/内容
Java基础
数据类型
数据类型的转换
强制转换
int自动转long
int自动转float
int自动转double
float自动转double
long自动转float
long自动转double
自动转换
特例
基本数据类型
byte
short
int
十进制数在内存中以补码形式存在
long
Date时间的数据类型底层是long类型
char
char c = '\\u1234';
char c = 2 + '2';,那么c=4
float
double
boolean
引用数据类型
类
接口
数组
流程控制语句
分支语句
if-else
switch-case
支持可以自动转int的类型
支持String类型
JDK1.7版本及以后支持
支持枚举
循环语句
for
while
do-while
foreach
底层就是迭代器
循环关键字
break
continue
return
标识符
标识符定义
类名
变量名
方法名
等等统称
标识符规则
不能数字开头
不能含空格
不可有特殊符号
标识符组成
数字
字母
下划线
$
运算符
算数运算符
比较运算符
逻辑运算符
三目运算符
拓展运算符
赋值运算符
位运算符
<<
>>
&
|
~
^
>>>
声明与初始化
特点
长度不可变
存放类型一定
操作
复制
扩容
剪切
遍历
相关问题
排序
查找
求值
变量
成员变量
定义在类全局
有默认值
数字默认为0
引用类型默认为null
布尔默认false
系统不会给final修饰的成员变量初始化
局部变量
仅在该代码块可用
无默认值
系统不会对局部变量初始化
构造方法
返回值
不用写返回值类型
返回值为该类的对象
不写返回值不是没有返回值
参数列表
无参
有参
重载
方法名相同
参数列表不同
new调用该方法创建对象
构造方法必须调用父类构造方法
方法
参数的传递
值传递(call by value)
址传递(call by reference)
方法重载
确定方法的三要素
调用者
形参列表
形参个数可变的方法
方法三要素
返回值类型
方法所属性
类方法
属于该类本身
不经过对象
普通方法
属于该类对象
方法默认主调者
静态方法默认由类直接调用
普通方法由该类对象默认调用
抽象方法
默认由public abstract修饰
不可被调用
抽象
抽象类
包含元素
可以包含普通方法和抽象方法
初始化块
内部类
用abstract关键字修饰类
抽象类不可被实例化
抽象类不可被private和protected修饰
抽象类可以继承抽象类
抽象类可以实现接口
主要作为多各类的模板
abstract
static和abstract不能同时修饰方法
final和abstract不能同时修饰方法
接口定义
接口是比抽象类更抽象的类
定义多个类应该遵守的规范
不可被实例化
不能被final和protected修饰修饰
一个类可以实现多个接口
接口可以多继承接口
接口中元素
接口不包含构造方法
接口中只能定义静态常量,不可定义普通成员变量
接口中不能声明引用
Java7
成员变量只能是静态常量
Java8新特性
可以在接口中定义默认方法
可以在接口中定义静态方法
Java9新特性
可以在接口中写私有方法
可以在接口中写私有静态方法
static
只能修饰属性、方法和初始化块
static修饰的在类加载时就初始化了
static修饰的可以直接用类名调用
不能使用this
final
可以修饰普通类、方法和属性
用final修饰的变量不可被二次赋值
用final修饰的类不可被继承
final修饰的方法不可被重写
重写final修饰的方法会发生编译错误
final修饰的成员变量必须指定初始值
由final修饰的类变量
final修饰的实例变量
修饰局部变量
final修饰引用变量
该变量不可被二次赋值
该变量引用指向的对象的内部可以发生改变
宏变量
被final修饰
只有在定义该变量时指定其初始值才有宏变量的效果
顺序
前面定义的块先执行
后面定义的块后执行
先执行静态后执行普通
可包含
调用其它对象的方法
控制语句
静态初始化块
只能被static修饰
类加载时执行
普通初始化块
创建对象时执行
枚举
枚举的本质是用enum修饰的final类
抽象与非抽象
非抽象枚举类默认由final修饰但不能显示使用final修饰该类
枚举类可以实现多个接口
枚举值
构造器
与普通类的区别
构造器只能用private修饰
默认继承java.lang.Enum抽象类
默认使用final修饰不能被继承
枚举不可以显示继承任何类
Enum提供的方法
values()
该方法为静态方法
toString()
实例方法
返回枚举常量名称
String name()
返回枚举实例名称
与toString方法功能相同
异常
异常的定义及概念
异常是用来处理可能因很多原因出现的以外状况的
异常的五个关键字
try
这个块中写可能发生异常类代码
与catch搭配使用
catch()
这个块中写发生异常后的处理方法
传一个异常类型的参数
finally
在try-catch最后
一般在这个块中关闭在try块中打开的资源
不要在此块中使用return、throw关键字,一旦使用,try块和catch块中的rerturn和throw将失效
throws
后面跟异常类
throw
Java非正常情况有两种
错误(Error)
此错误无法处理,发生的可能性小,所以不需要处理机制
发生场景
系统崩溃
内存溢出
动态连接失败
异常(Exception)
可处理异常
异常的分类
编译时异常
Checked异常
运行时异常
Runtime异常
该异常在编译时无需处理
Throwable
Error
AWTError
IOError
LinkageError
ThreadDeath
Exception
RuntimeException
NullPointerException
IndexOutOfBoundsExceptipn
StringIndexOutOfBoundsException
ArraysIndexOfBoundsException
ClassCastException
IllegalArgumentException
ArithmeticException
NumberFormatException
IOException
SQLException
处理异常的方式
try-catch-finally
异常处理可以嵌套,但会降低执行效率不建议使用
try块catch块遇到return、throw都会结束,然后直接奔向finally
Java7新增多异常捕获
捕获多异常时,异常变量有final隐式修饰
只能在方法签名中使用
throw自行抛出异常
直接抛出一个异常的实例,可以当作独立语句使用
在catch块中结合throw使用
所有异常类的通用方法
getMessage()
System.out.print(e.getMessage())
printStackTrace()
打印异常错误和位置以及异常跟踪栈信息
getStackTrace()
返回跟踪异常栈信息
自定义异常
IO
路径
反斜线\\
在双引号中为\\\\
绝对路径
优点:在任何项目中使用绝对路径绝没问题
缺点:没有系统移植性
相对路径
File
File可以创建删除重命名文件和目录(目录就是文件夹)
File不可以访问文件本身的内容
常用方法
exists()判断文件或目录是否存在
isFile()判断File对象对应的是否是文件而不是目录
isDirectory()判断对象是否是目录而不是文件
createFile()
delete()删除对象对应的文件或空路径,如果想要产出一个文件夹下所有东西,包括这个文件夹下的目录文件与子目录及其文件,可以使用递归,如左侧代码
mkdir()创建目录,但需要有父目录
mkdirs()创建目录不需要父目录存在
getName()以字符串形式返回文件或目录名
list()
listFile()
过滤器
FileFilter
方法accept(File pathname)
accept的参数市listFile方法传递过来的
在accept方法中,进行判断,如果满足自己要求,则将true返回给listFile方法,此时listFile将此时拿到的全路径保存到File数组中
若拿到的路径不满足自己的要求,则返回给listFile方法false,此时不保存该路径
listFile(FileFilter接口实现类)
遍历多级目录需要使用递归
流的分类
按方向
输入流
只能从中读取数据而不能写
输出流
只能向其写数据而不能读
按功能
字节流
操作的数据单元是8位的字节
主要由InputStream和OutPutStream作为基类
字符流
操作的数据单元是16位的字符
主要有Reader和Writer作为基类
字符流可以将字符串作为物理节点
对象流
按角色
节点流
低级流
程序直接与数据源连接
处理流(也称包装流)
高级流
IO的四十多个类的抽象基类
所有输入流基类
InputStream
int read()
读取一个字节数据,返回这个字节数据的十进制整数值
int read(byte[] b)
读取一组字节数据并放入byte类型的数组中
返回读取的字节数
读取一组字节数据放入byte数组中
从off开始
读取len个字节放入数组
FileInputStream->InputStream
Reader
读取一个字符数据返回这个字符的int值
int read(char[] c)
读取一组字符并放入char类型的数组中
返回读取的字符数
读取一组字符放入char类型的数组中
读取len个字符
返回读取的字字符数
FileReader->InputStreamReader->Reader
流的关闭
void close()
保证流的物理资源被收回
保证缓冲当中的数据flush到数据节点即输出目标中
所有输出流基类
OutputStream
write(int c)
将指定的字节输出到流中
void write(byte[] b)
将指定字节数组输出到指定流
将指定字节数组输出到流
输出len个字节
FileOutputStream继承自OutputStream
Writer
将指定的字符输出到流中
将指定字符数组输出到指定流
将指定字符数组输出到流
void write(String s)
将字符串输出到指定流
将制定字符串输出到指定流
从字符串的off开始输出
输出len个字符
FileWriter->OutputStreamWriter->Writer
处理流
常见处理流
打印流
次流不负责数据源,只负责数据目的
为其他流添加功能
永远不会抛出IOException,但会抛出别的异常
两个打印流的方法是一致的
PrintStream
PrintWriter
转换流
InputStreamReader
参数传字节输入流
将字节输入流转换为字符输入流
该类父类为Reader
OutputStreamWriter
参数为字节输出流
将字节输出流转换为字符输出流
该父类为Writer
BufferedReader
字符输入流
功能更强大
主要优点
提供readLine()方法每次读一行
继承自Reader
BufferedWriter
字符输出流
带缓冲
newLine()写入一个换行符
继承自Writer
序列化
序列化的目的
序列化的意义
使得对象可以脱离程序的运行而独立存在
什么是序列化
对象的序列化指将一个Java对象写入IO流
对象的反序列化是从IO流中恢复Java对象
如何实现可序列化
实现Serializable接口
实现该接口不需要实现任何方法
实现Externalizable接口
对象流实现序列化
首先该对象的类实现可序列化接口
静态不是对象的一部分所以不参与序列化
序列化步骤
2.调用该处理流的writeObject()方法输出可序列化对象
反序列化
对象引用序列化
特殊序列化机制
1.所有保存到磁盘的对象都有一个序列化编号
注意
自定义序列化
递归序列化
transient
只能修饰实例变量
作用是让序列化忽略该实例变量
该变量称为瞬态实例变量
特殊签名的方法
writeObject(ObjectOutputStream out) throws IOException
序列化注意事项
反序列化对象时必须有序列化对象的class文件
当通过文件、网络来读取序列化对象时,必须按照实际写入顺序读取
序列号冲突问题
在编辑器将java文件编译成class文件的同时,如果这个类可序列化,则给这个类计算序列号,第一次序列化该类对象时,按照该序列号为准,当序列化以后改变了类的内容,则编辑器重新编译且生成新序列号,此时再反序列化则会出现序列号冲突,反序列化异常
给该可序列化类定义序列号:格式要求static final long serialVersionUID = 222L
NIO
线程
线程的本质
线程本质上是进程中一段并发操作的代码,所以线程需要操作系统投入CPU资源来运行和调度
线程和进程
进程
一个程序进入内存运行时,就变为一个进程
进程是操作系统进行资源分配和调度的一个独立单位
进程的三个特征
独立性
是系统中独立存在的
拥有自己私有的地址空间
拥有自己独立的资源
动态性
进程拥有自己的生命周期和各种状态
并发性
多个进程可以在单个处理器上并发执行,各个进程之间不会相互影响
并发性与并行性
并发性是同一时刻一条指令在单个处理器上执行,由于处理器快速轮换,就好像多条指令同时执行
并行性是同一时刻多条指令在多个处理器上同时执行
当一个程序运行时,内部包含多个顺序执行流,每个顺序执行流就是一个线程
线程是进程的基本单位
每个进程包含一个或多个线程
同一个进程内的线程独立运行但资源共享
线程的创建方式
继承Thread类
1.定义Thread的子类并重写run()方法,该方法就是线程执行体
2.创建Thread子类的实例,该实例就是线程对象
3.用该实例调用start()方法就启动了一个线程
实现Runnable接口
1.定义Runnable接口的实现类,并重写run()方法,该方法就是线程执行体
2.创建实现类的实例,并以此实例作为Thread的target来创建Thread对象
3.用Thread对象调用start()方法启动线程
使用Callable和Future创建
Callabe接口
call()方法
Callable接口提供了call()方法作为线程执行体,该方法可以有返回值
该方法可以声明抛出异常
该接口不是继承自Runnabl接口,所以不可作为Thread的target
Callable有泛型限制,且泛型与call方法的返回值类型一致,Callable是函数式接口,可以用lambda表达式表示
Future接口
提供一个FutureTask实现类,该类实现了Future、Runnable接口,可以作为Thread的target
让FutureTask与Callable关联,来代表Callable接口中call()方法的返回值,并作为Thread的target
提供的方法
cancel()
get()
isDone()
isCancelled()
创建线程步骤
1.创建Callable接口的实现类并实现call()方法,该方法作为线程执行体
2.使用FutureTask类来包装Callable对象,该FutureTask对象封装了call()方法的返回值
3.使用FutureTask对象作为Thread对象的target创建并启动线程
4.调用FutureTask对象的get()方法来获得返回值
线程的状态
新建状态
new一个线程类
只由JVM给其分配内存空间,初始化其成员变量
就绪状态
当一个新建线程调用start()方法,该线程由新建状态变为就绪状态
运行状态
当就绪状态的新线程获得cpu,该线程变为运行状态
阻塞状态
当运行状态的线程遇到IO请求或者调用sleep()方法,线程变为阻塞状态
线程在等待某个通知(notify)
死亡状态
线程执行体执行完成正常结束变为死亡状态
线程调用stop()方法,线程变为死亡状态
线程的控制
join线程
join()
后台线程
setDaemon(true)可以将前台线程设置为后台线程
isDaemon()判断线程是否为后台线程
当前台线程全部死亡,后台线程也会直接死亡
线程睡眠
sleep(int 毫秒)
改变线程优先级
setPriority(int priority)
getPriority()
线程同步
线程安全问题
同步代码块
把对共享资源的操作的代码放在同步代码块中,使其任何时刻只能有一个线程访问该代码块
语法格式
synchronized(obj){....}
volatile关键字
只能修饰成员变量
可以称之为轻量级synchronized
两大性
可见性
有序性
指程序中上下两条无关的代码执行不会被指令重排序
同步方法
用synchronized关键字修饰方法
原子性
同步锁lock
创建锁对象
悲观锁
对应现实生活中悲观的人,即什么事都想的比较坏。在进行数据访问的时候,总是想着一定会有人来争抢资源,所以悲观锁是在用之前就上锁。数据库中的行锁,表锁等,读锁、写锁等都属于悲观锁,另外synchronized锁和Lock锁都是悲观锁机制
适用场景
悲观锁适用于多写的应用场景,多写的场景发生线程冲突的情况较多,适合适用之前就加锁
乐观锁
对应于现实生活中乐观的人,即把什么事都想得比较好,在进行数据访问的时候,总是认为没有人访问,所以乐观锁是在使用数据的时候不会上锁,而是在最后更新的时候通过版本号机制或CAS算法判断有没有其他线程更新,再决定是否驳回操作
乐观锁适用于多读应用程序,在这种多读情景下,线程发生冲突较少,适合使用前不加锁
版本号机制
数据库每张表都有一个版本号,每次更新版本号都会加1,在读数据库的时候,也会读取该表的版本号,当对表中数据做更新的时候,会检查此刻的版本号跟起初读的版本号是否一致,如果不一致,将驳回本次更新操作
CAS算法
无锁算法,所以又叫非阻塞同步
线程通信
Object类提供了三个控制线程的方法,该方法由线程同步监视器调用
wait()
notify()
notifyAll()
Condition接口下的方法控制线程通信
Condition cond = lock.newCondition()
获取Codition的实例
API
await()
singal()
singalAll()
线程其他相关类
ThreadLocal
set(T value)
设置线程副本的值
获取线程变量副本的值
remove()
删除此线程局部变量中当前线程的值
入口
main方法
命名规范
驼峰命名
首字母小写
项目名
全小写
包名
域名倒置
常量
全大写
用下划线连接
首字母大写
类和对象
类的定义
一般用public修饰
一个类只能有一个公共类
基本的类包含属性和方法
对象的创建
new关键字
创建对象时根据构造器对对象成员变量进行初始化
对象的引用
对象赋给引用变量
引用变量存对象的地址
this
构造器中this指向正在初始化的对象
在静态方法中不可使用this
必须写在构造器第一行
类中元素
特征
匿名内部类适用于创建仅需使用一次的类
分类
成员内部类
将一个类定义在另一个类的类中
不可包含静态属性和方法
局部内部类
局部内部类存在于方法中。和成员内部类的区别:局部内部类的访问权限仅限于方法或作用域内
局部内部类只能访问外部类的final变量
不能由权限修饰符和static修饰
匿名内部类
没有构造方法
只能访问外部类的final变量
静态内部类
由static修饰的内部类
不可访问外部类的非静态变量和方法
静态内部类不可包含非静态成员
不同点
权限修饰符
private
protected
默认
public
非静态内部类不能拥有静态成员
内部类实例的创建
外部类.内部类 对象名 = new 外部类.内部类();
外部类.内部类 对象名 = 外部类对象名.new 内部类();
面向对象三大特征
封装
本质
类和类之间的关系
泛化关系
继承
实现
依赖关系
关联关系
聚合关系
弱聚合
通常把弱聚合称为聚合
强聚合
通常把强聚合称为组合
extends关键字
子类可获得父类静态方法
子类可获得父类静态属性
java中只可单继承
继承抽象类必须重写抽象类中的所有抽象方法
重写
重写父类方法将覆盖父类方法
子类对象不可调用被覆盖方法
子类中可以调用被覆盖方法
实例方法用关键字super调用
类方法用类名调用
@Override
注解
只能标注方法
重写规则
重写权限修饰符不能变小
重写必须方法名一致参数列表一致,返回值类型可不同
不能重写私有方法
super
用于限定该对象调用他从父类继承到的东西
调用父类构造器
父类设计规则
尽量隐藏父类内部数据
不让子类随意访问、修改父类方法
成员变量都用private修饰
不被访问的方法可以用private修饰
不想被重写但让子类访问的方法可以用public final修饰
希望某方法被子类访问和重写但不希望其他类自由访问可以用protect修饰
尽量不在构造器中使用将被重写的方法
继承和组合的使用
继承的两个类之间是\"是\"的关系
组合两个类之间是\"有\"的关系
类只能单继承类,但接口可以多继承接口,类可以多实现接口
多态
编译时类型
运行时类型
多态存在的必要条件
存在继承关系
存在重写
存在父类引用指向子类对象
向下转型
父类向子类转需要强转
强转后释放子类的拓展属性和方法
向上转型
子类可以自动转换 为父类
转换成父类以后将隐藏子类的拓展属性和方法
设计模式
高内聚低耦合
各个设计模式图解
链接地址
创建型设计模式
工厂模式三兄弟
反例设计
缺点
违背单一职责原则
违背开闭原则
高耦合
重复代码较多
简单工厂模式
设计思想
再提供一个工厂类并提供用于创建所需要的各个对象的方法
客户端只需要调用工厂类的方法并传入相应参数便可以得到想要的对象
简单工厂模式的定义
简化
优点
实现了对象的创建与使用分离
工厂类职责过于繁重
工厂类负责创建的对象较少
工厂模式
工厂模式的定义
角色
Product(抽象产品)
ConcreteProduct(具体产品)
Factory(抽象工厂)
ConcreteFactory(具体工厂)
客户端无需知道具体对象的创建细节
基于工厂角色和产品角色的多态性设计是工厂模式的关键
完全符合开闭原则
抽象工厂类通过其子类来指定创建哪个对象
抽象工厂模式
抽象工厂的定义
提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类
包含角色
AbstractFactory(抽象工厂)
它声明了一组用于创建一族产品的方法,每一个方法对应一 种产品。
ConcreteFactory(具体工厂)
它实现了在抽象工厂中声明的创建产品的方法,生成一组具 体产品这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。
AbstractProduct(抽象产品)
它为每种产品声明接口,在抽象产品中声明了产品所具有的 业务方法。
ConcreteProduct(具体产品)
它定义具体工厂生产的具体产品对象,实现抽象产品接口中 声明的业务方法。
开闭原则倾斜
增加产品族完全符合开闭原则
产品族指的是一组产品例如海尔公司的冰箱空调洗衣机
增加产品等级结构
增加新的产品族很方便,无须修改已有系统,符合“开闭原则”。
当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产 品族中的对象。
增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码, 这显然会带来较大的不便,违背了“开闭原则”。
单例模式
目的
单例模式出现动机
定义
确保一个类只有一个实例
自行实例化并向整个系统提供这个实例
设计方式
将该类构造器设为私有
在该类中定义并保存该类的唯一实例
Singleton(单例)
饿汉式单例
在定义静态变量的时候实例化该类
这样不会出现并发问题
懒汉式单例
但在多线程环境中还是会出现多个实例的情况
原型模式
先创建一个原型对象,再通过复制创建出更多同类型的对象
Prototype(抽象原型类)
ConcretePrototype(具体原型类)
Client(客户类)
在客户端类中创建原型类对象然后调用原型类对象的克隆方法创建出新的相同对象
可以自定义抽象原型类并声明克隆方法然后再自己实现该方法
clone方法满足
对任何对象x,都有x.clone() != x
对任何对象x,都有x.clone().getClass() == x.getClass(),即克隆对象与原型对象的类型一 样
如果对象x的equals()方法定义恰当,那么x.clone().equals(x)应该成立。
建造者模式
结构型模式
适配器模式
桥接模式
组合模式
装饰者模式
外观模式
代理模式
亨元模式
行为型模式
命令模式
迭代器模式
中介者模式
访问者模式
观察者模式
策略模式
状态模式
解释器模式
备忘录模式
模板方法模式
职责链模式
整个项目可用
包内可用
包外子类可用
包内
本类
java常用包及类
lang
String
Math
System
arraycopy
Thread
util
工具类
Arrays
copyOf
toString
binarySearch()
List
Set
net
网络编程有关
io
输入输出流
text
格式化相关类
sql
JDBC相关类
swing
图形用户界面
awt
字符串
String常用方法
indexOf
返回int下标
传字符或字符串
查找第一次出现的字符的位置
split
返回字符串
传入字符串
按指定字符分割字符串
codePointAt
返回整型
传整型下标
将指定位置字符转换成Unicode码
valueOf
传入八种数据类型+Object
将传入的转换为字符串
getByte
返回byte[]
不传参
按默认编码集将指定字符串转换成字节码
charAt
返回char
传int下标
按照下标取字符
startWith
返回boolean
判断该字符串是否以指定字符串开始
endWith
判断是否以指定字符串结束
substring
返回string
截取字符串
equals
传字符串
判断字符串是否相等
equalsIgnoreCase
忽略大小写比较字符串
isEmpty
判断字符串是否为空字符串
lastIndexOf
返回int
传String引用变量
判断字符串最后一次出现指定子字符串的下标
contains
传CharSequence(String的父类)
判断字符串是否包含指定字符串
concat
返回String
传String
将两个字符串连接
length
返回字符串长度
trim
删除字符串两端空格
compareTo
比较两个字符串在字典中的位置
为什么设计成final的
常量池需要
虚拟机对字符串是有优化的,有字符串常量池
如果字符串可以改来改去,那字符串常量将没有意义
缓存hash值
安全性
Java对Stirng的特殊支持
+、+=用于字符串拼接
加号操作一定出现新的String对象
“asa”可以直接创建一个字符串对象
jvm对String拼接的优化
String底层是有final修饰的char数组
可变字符串
StringBuilder
底层是没有final修饰的char数组
利用数组复制实现可变字符串
字符串截取
该方法是StringBuilder父类的方法
该方法与String的substring方法类似
append
传8种数据类型
返回StringBuilder
字符串拼接
delete
初始容量为16个字符
StringBulider类型可以直接输出
StringBuffer
跟StringBuilder本质一样
主要区别是StringBuilder多了线程安全
包装类
Integer
返回值Integer
将传入的转换成Integer类型
parseInt
返回值int
将特定字符串转换为int
Byte
Short
Long
Float
Double
Boolean
Charact
不可变类
用final和private修饰类的成员变量
提供有参构造方法给成员变量初始化
只提供getter方法
必要时提供hashCode和equals
java.lang.String和八个包装类均为不可变类
泛型
集合
Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。 Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。 ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等。
Collections
java.util包下的提供了大量操作集合的方法的工具类
排序操作
查找替换操作
Collection
ArrayList
底层是Object类型的可变的数组
利用数组的拷贝来进行对容器内数据的操作
有序
有下标
元素允许重复
add()
add(E)
addAll()
addAll(Collection<> c)批量插入
set()
set(E)
get(int)
remove(int index)
Vector
与ArrayList一样
Stack子类
栈
后进先出
push入栈
pop出栈
peek查看栈顶元素
empty判断是否为空
size元素个数
固定长度的list
调用Arrays的asList方法可将一个数组或指定个数的对象转为List
他是Arrays类中的内部类ArrayList的实例
只能遍历访问该集合元素,不可增删该
LinkedList
底层是数据结构中的双向链表
利用节点的前后指向将一个个节点连接起来组成链
在插入时效率较高,元素多的时候查找效率低
linkLast(E e)
linkFirst(E e)
add(E)默认在链表最后查入
clear()
Collection接口方法
add(Object)
addAll(Collection)
contains(Obj)
containsAll(Collection)
iterator
remove(Obj)
removeAll(Collection)
size()
toArray()
Collection和Collections
Collections是一个操作Set、List、Map等集合的工具类
HashSet
按Hash算法来存储集合中的元素,查找插入超级快
无序
不支持排序
不是同步的,线程安全有问题
集合的元素可以为null
HashSet两个元素相等的标准是通过equals返回true并且哈希值相等
LinkedHashSet子类
也是根据哈希值存放
内部多了一个LinkedLish列表用来记录元素插入顺序
性能略低
子主题
当存入可变对象时,如果修改集合对象的内部成员变量,有可能使该对象与集合中其他对象相等,从而导致集合无法准确操作元素
SortedSet
TreeSet
直接父类是SortedSet(继承Set接口)
元素有序
支持排序
元素不可重复
不可有null元素
first()
取第一个元素
last()
取最后一个元素
lower()
取指定元素的前一个元素
higher()
取指定元素的后一个元素
截取自TreeSet的方法
headSet(Object)
返回小于指定元素的子集
tailSet(Object)
返回大于指定元素的子集
返回在传入参数之间的子集
如果向集合插入可变对象,并且后面程序修改了该对象实例变量,这会导致其顺序发生改变,但集合不会重新调整顺序,甚至会出现重复元素
自然排序
TreeSet会调用集合元素的compareTo(Object)方法比较元素大小进行升序排列
Comparable是一个接口,提供了比较大小的标准
如果试图把一个对象添加到TreeSet时必须实现Comparable接口并实现比较的方法
定制排序
在创建TreeSet对象时传入一个Comparator对象,可以写匿名内部类,也可以用Lambda表达式代替
Queue
序列
先进先出FIFO
队列不允许随机访问队列中的元素
Deque接口
ArrayDeque实现类
底层基于Array
双端队列
允许从队列两端操作队列
addFirst(Object e)
addLast(Object e)
getLast()
getFirst
removeLast
removeFirst()
add(Object e)
向队尾添加元素
offer(Object e)
element()
获取队列头部元素但不删除
peek()
poll()
获取并删除队列头部元素
就这么说吧,对于集合的三种遍历方式删除:1.普通for循环:可以删除注意每次删除之后索引要--2.Iterator遍历:可以删除不过要使用Iterator类中的remove方法,如果用List中的remove方法会报错3.增强for循环foreach:不能删除强制用List中的remove方法会报错
普通for循环
foreach循环(底层还是迭代器)
迭代器
hasNext()判断是否还有数据
next()返回元素
Map集合
HashMap
键值对
key可以存null
value可以重复
HashMap中是用链地址法来解决哈希冲突的
forEach
get(key)
keySet()返回所有key存入set集合
SortedMap接口
TreeMap实现类
不可存null
查找较慢
采用红黑树排序
按照元素的实际大小
HashTable
线程安全
子类
Properties
不可写泛型
键值都是String
可以和IO结合使用,实现永久存储
getProperty(k)
stringPropertyNames()
类似于Map集合中的keySet方法
特有方法
读到集合
load(InputStream in)
load(Reader r)
写到properties文件
store(OutputStream)
store(Write)
Properties pro = new Properties();FileInputStream in = new FileInputStream(\"c://a.properties\");//调用集合方法load并传入流对象,就可以将文件内容放入集合pro.load(in);//此时键值对已存入集合in.close;
Properties pro = new Properties();FileWriter fw = new FileWriter(\"c://a.properties\
java.util.concurrent
ConcurrentHashMap
底层原理
锁分段技术
首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。
Iterator和ListIterator的区别?
网络编程
网络通信协议
TCP/IP协议
应用最为广泛的协议
包括TCP和IP协议
IP地址
计算机在网络中的唯一标识
端口号
程序在电脑中的唯一标识,范围在0~65535,0~1024由计算机软件占用
InetAddress
static InetAddress getByName() 通过主机名获取IP地址
static InetAddress getLocalHost() 获取本机IP地址
String getHostName() 获取主机名
String getHostAddress() 获取主机IP地址对象
传输协议
UDP
无连接通信协议
发送端和接收端不会建立逻辑连接:当一台计算机向另一台计算机发送数据的时候不会去管接收端是否存在就会发送数据,而接收端接收完数据也不会给发送端反馈
资源消耗小、通信效率高
容易造成数据丢失
有传输大小限制,数据限制在64k以内
新闻联播
视频会议
微信聊天、发短信
TCP
面向连接通信协议
三次握手
客户端向服务器端发送连接请求,等待服务器确认
服务器向客户端回送一个响应,通知客户端收到了连接请求
客户端再次向服务器端发送确认信息,确认连接
资源消耗相对较大,通信效率较低
传输大小理论没有限制
比较安全,不会造成数据丢失
适用
资源下载
文件传输
UDP通信
DatagramPacket
数据报包,用于封装数据
DatagramSocket
用于发送和接收数据包的
发送步骤
创建DatagramPacket对象,封装数据,接收端IP和端口
创建DatagramSocket对象
new DatagramSoket()
调用DatagramSocket对象的send方法,发送数据包
关闭资源
接收步骤
创建DatagramSocket对象,绑定端口号,要求和发送数据的端口号一致
new DatagramSocket(int port)
创建字节数组用来接收数据
创建数据包DatagramPacket对象
调用DatagramSocket对象的,receive方法
receive(DatagramPacket dp) 接收数据,数据放在数据包中
拆包
发送的IP地址
接收到的字节个数
发送方的端口号(无意义)
TCP通信
面向连接,服务器先开机,客户端连服务器
ServerSocket
用于服务器端
使用构造方法接收客户端连接请求,传端口号,与客户端一致
new ServerSocket(int port)
使用ServerSocket对象的accept方法获取客户端Socket对象
server.accept()
调用客户端Socket对象获取字节输入流,读入客户端发来的数据
socket.getInputStream()
调用客户端Socket对象获取字节输出流,向客户端写数据
socket.getOutputStream()
Socket
用于客户端
客户端使用构造方法与服务器进行连接,如果连接失败则抛异常
用客户端Socket对象获取输出流,向客户端写数据
用客户端Socket对象获取输入流,读服务器发来的数据
socket.InputStream()
多线程上传图片思想:服务器没接收到一个客户端Socket,就给它开启一个线程,并将Socket对象传过去
0 条评论
回复 删除
下一页