一、简介
1、概述: 是由 Sun公司于 1995 年 5 月推出的 Java 面向对象程序高级设计语言
2、平台
(1)、标准版(javaSE)
(2)、企业版(javaEE)
(3)、微型版(javaME)
3、主要特点
(1)、面向对象
(2)、跨平台
4、注意事项
(1)、严格区分大小写
(2)、括号都是成对出现,缺一不可
5、第一个Java程序
public class Hello {
public static void main(String[] args) {
System.out.println("Hello Word");
}
}
二、标识符
1、概述:对各种变量、方法、和类等命名的时使用的字符序列
2、命名规则
(1)、由26个英文字母,大小写均可,数字0 ~ 9,_或$,组成
(2)、数字不可开头
(3)、不可以使用关键字和保留字,但可以包含
(4)、严格区分大小写,并无长度限制
(5)、标识符不能包含空格
3、规范
(1)、包名:多单词组成时所有字母全小写
(2)、类名、接口名:多单词组成时,所有单词的首字母大写
(3)、变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词的首字母大写 (
4)、常量名:所有字母全部大写,多个单词时用下划线连接
三、关键字
1、概述:具有特殊意义的固定的单词,都是小写,总共时53个关键字和保留字
2、关键字
private | protected | default | public | class | abstract |
---|---|---|---|---|---|
extends | implements | interface | final | strictfp | static |
synchronized | transient | volatile | native | enum | for |
break | continue | do | while | if | else |
switch | case | instanceof | return | assert | try |
catch | finally | throw | throws | boolean | byte |
char | short | int | long | float | double |
new | super | this | void | null | true |
false | import | package | goto | const |
四、基本数据类型
(一)、整型
1、介绍
数据类型 | 名称 | 占有空间 | 字节位 | 取值范围 |
---|---|---|---|---|
btye | 字节类型 | 1 | 8 | -27 ~ 27 - 1 |
short | 短整型类型 | 2 | 16 | -215 ~ 215 -1 |
int | 整形 | 4 | 32 | -231 ~ 231 -1 |
long | 长整型类型 | 8 | 64 | -263 ~ 263 - 1 |
2、注意事项
(1)、Java各个整数类型有固定的范围和字段长度,不受具体OS的影响,以保证Java程序的可移植性
(2)、Java的整型常量默认为int类型,声明long类型常量是须在后面加" L "或" l "
(3)、Java程序中变量常声明为int类型,除非不足以表示大的整数,才可使用long
(二)、浮点类型
1、介绍
数据类型 | 名称 | 占有空间 | 字节位 | 精度 | 取值范围 |
---|---|---|---|---|---|
double | 双精度浮点型 | 4 | 32 | 7 | 1.4E-45 ~ 3.4028235e+38f |
float | 单精度浮点型 | 8 | 64 | 16 | 4.9E-324 ~ 1.7976931348623157E308 |
2、注意事项
(1)、Java各个浮点类型有固定的范围和字段长度,不受具体OS的影响,以保证Java程序的可移植性
(2)、Java的浮点型常量默认为double类型,声明float类型常量是须在后面加" F "或" f " (3)、通常情况下,浮点类型变量声明应使用double类型,因为它比float更加精确
(三)、字符类型
1、介绍
数据类型 | 名称 | 占有空间 | 字节位 | 取值范围 |
---|---|---|---|---|
char | 字符类型 | 2 | 16 | 0 ~ 65535 |
2、注意事项
(1)、字符常量是用单引号括起来的单个字符
(2)、char类型是可以参与计算的
(3)、在Java中,char的本质是一个整数,可以赋值一个整数,但是在输出时,会按照unicode码对应的字符进行输出
(四)、布尔类型
1、介绍
数据类型 | 名称 | 占有空间 | 取值范围 |
---|---|---|---|
boolean | 布尔类型 | 1 | true、false |
2、注意事项:不可以0或非0的整数来替代false和true
(五)、类型转换
1、概述:类型之间的相互转换
2、分类
(1)、自动:数字表示范围小的数据类型可以自动转换成范围大的数据类型
(2)、强制:强制显示的把一个数据类型转换为另外一种数据类型
3、注意事项
(1)、八种基本数据类型中,除了boolean类型不能转换,剩下七种类型之间都可以进行转换
(2)、如果整数型字面量没有超过byte、short、char的取值范围,可以直接将其赋值给byte、short、char类型的变量
(3)、小容量向大容量转换称为自动类型转换,容量从小到大排序为:byte<short(char)<int<long<float<double,其中short和char都占用两个字节,但是char可以表示更大的正整数
(4)、大容量转换为小容量,称为强制类型转换,编写时必须添加“强制类型转换符”,但运行时可能会出现精度损失,谨慎使用
(5)、byte、short、char类型混合运算时,先各自转换成int类型再做运算
(6)、多种数据类型混合运算时,各自先转换成容量最大的那一种再做运算
五、运算符
(一)、算术
符号 | 名称 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
% | 取模 |
X++ | 前加加;先加一,再赋值 |
++X | 后加加;先赋值,再加一 |
X-- | 前减减;先减一,再赋值 |
--X | 后减减;先赋值,再减一 |
(二)、关系
符号 | 名称 | 规则 |
---|---|---|
== | 相等 | 检查如果两个操作数的值是否相等,如果相等则条件为真 |
!= | 不等 | 检查如果两个操作数的值是否相等,如果值不相等则条件为真 |
> | 大于 | 检查左操作数的值是否大于右操作数的值,如果是那么条件为真 |
< | 小于 | 检查左操作数的值是否小于右操作数的值,如果是那么条件为真 |
>= | 大于等于 | 检查左操作数的值是否大于或等于右操作数的值,如果是那么条件为真 |
<= | 小于等于 | 检查左操作数的值是否小于或等于右操作数的值,如果是那么条件为真 |
instanceof | 是否是类的对象 | 检查该对象是否是一个特定类型 |
(三)、逻辑
符号 | 名称 | 规则 |
---|---|---|
&& | 逻辑与 | 当且仅当两个操作数都为真,条件才为真 |
|| | 逻辑或 | 如果任何两个操作数任何一个为真,条件为真 |
! | 逻辑非 | 用来反转操作数的逻辑状态。如果条件为true,则逻辑非运算符将得到false |
(四)、位
符号 | 名称 | 规则 |
---|---|---|
& | 按位与 | 如果相对应位都是1,则结果为1,否则为0 |
| | 按位或 | 如果相对应位都是 0,则结果为 0,否则为 1 |
^ | 按位异或 | 如果相对应位值相同,则结果为0,否则为1 |
~ | 取反 | 按位取反运算符翻转操作数的每一位,即0变成1,1变成0 |
<< | 左移 | 左操作数按位左移右操作数指定的位数 |
>> | 带符号右移 | 左操作数按位右移右操作数指定的位数 |
<<< | 无符号右移 | 左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充 |
(五)、三元
1、格式:(条件表达的真假)?true:false
2、规则:判断布尔表达式的值,若为true,赋问号后面的值,否则就是冒号后面的值
(六)、赋值
符号 | 名称 |
---|---|
= | 赋值 |
+= | 加等 |
-= | 减等 |
*= | 乘等 |
/= | 除等 |
%= | 取模等 |
<<= | 左移位赋值 |
>>= | 右移位赋值 |
&= | 按位与赋值 |
^= | 按位异或赋值 |
|= | 按位或赋值 |
六、流程控制
(一)、if
1、单分支
if(条件表达式){
//代码块
}
2、双分支
if(条件表达式){
// 代码块
}else{
// 代码块
}
3、多分支
if(条件表达式){
// 代码块
}else if(条件表达){
// 代码块
}
...
else{
// 代码块
}
(二)、多重选择
1、概述:判断一个变量与一系列值中某个值是否相等,每个值称为一个分支
2、语法格式
switch(表达式){
case 常量1:
执行代码块1;
break;
case 常量2:
执行代码块2;
break;
...
case 常量n:
执行代码块n;
break;
default:
执行代码块n+1;
break;
}
3、注意事项
(1)、case语句具有穿透性
(2)、条件表达式的值必须是整型、字符串或枚举类型
(三)、循环结构
1、for
for(循环变量初始化;循环条件;循环变量迭代){
执行代码块;
}
2、while
while(循环条件){
执行代码块;
循环变量迭代;
}
3、do...while
循环变量初始化;
do{
执行代码块;
循环变量迭代;
}while(循环条件);
(四)、控制语句
1、break
(1)、概述:用于终止某个语句块的执行
(2)、语法
{
...
break;
...
}
(3)、注意事项:break语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的是哪一层语句块
2、continue
(1)、概述:用于结束本次循环,继续执行下一次循环
(2)、语法
{
...
continue;
...
}
3、return
(1)、概述:表示跳出所在的方法 (2)、语法
{
...
return;
}
七、数组
(一)、简介
1、概述:可以存放多个同一类型的数据,其本质就是一个容器
2、使用方式
(1)、动态初始化:数据类型[] 数组名 = new 数据类型[数组长度];
(2)、静态初始化:数据类型[] 数组名 = new 数据类型[]{数组元素};
(3)、静态初始化简写:数据类型[] 数组名 = {数组元素};
3、注意事项
(1)、数组是由多个相同类型数据的组合,实现对这些数据的统一管理
(2)、数组中的元素可以任意类型,包括基本数据类型、引用数据类型,但是不能混用
(3)、数组在创建后,若没有赋值,则会有初始值
(4)、数组的下标都是从0开始的,且必须数组下标必须在指定范围内使用,否则就会报下标越界异常
4、遍历方式:增强for
for(数据类型 名称:集合/数组){
代码块
}
(二)、操作
1、基础自编操作
(1)、所有的数组类型都可以,且是静态方法
class Array<T> {
// 数组扩容 每次扩容,长度加一
public static<T> T[] capacityArray(T[] array) {
// 数组扩容
T[] data = transitionArrayClass(array, true);
// 复制数组的元素
copyArrayElement(array, data);
// 返回
return data;
}
// 数组扩容 每次扩容,长度加size
public static<T> T[] capacityArray(T[] array, int size) {
// 数组扩容
T[] data = transitionArrayClass(array, size);
// 复制数组的元素
copyArrayElement(array, data);
// 返回
return data;
}
// 数组反转
public static<T> void reverseArray(T[] array) {
for (int i = 0; i < array.length / 2; i++) {
T temp = array[array.length - 1 - i];
array[array.length - 1 - i] = array[i];
array[i] = temp;
}
}
// 数组拷贝
public static<T> T[] copyArray(T[] array) {
// 调用 transitionArray 方法
T[] data = transitionArrayClass(array, false);
// 复制数组的元素
copyArrayElement(array, data);
// 返回
return data;
}
// 数组遍历
public static<T> void traversalArray(T[] array) {
for (T t : array) {
System.out.print(t + " ");
}
System.out.println();
}
// 修改指定位置的元素
public static<T> void set(T[] array, T t, int index) {
array[index] = t;
}
// 获取指定位置元素
public static<T> T get(T[] array, int index) {
return array[index];
}
// 复制数组的元素
private static<T> void copyArrayElement(T[] oldArray, T[] newArray) {
for (int i = 0; i < oldArray.length; i++) {
newArray[i] = oldArray[i];
}
}
// 强制类型转换 将Object类型强制转换为T类型
private static<T> T[] transitionArrayClass(T[] array, Boolean flag) {
if (flag) {
return (T[]) new Object[array.length + 1];
}
return (T[]) new Object[array.length];
}
// 强制类型转换 将Object类型强制转换为T类型
private static<T> T[] transitionArrayClass(T[] array, int size) {
return (T[]) new Object[array.length + size];
}
}
(2)、所有的数组类型都可以,且是有参构造,传入一个数组
class Array<T> {
private final T[] array;
public Array(T[] array) {
this.array = array;
}
// 数组扩容 每次扩容,长度加一
public T[] capacityArray() {
// 数组扩容
T[] data = transitionArrayClass(array, true);
// 复制数组的元素
copyArrayElement(array, data);
// 返回
return data;
}
// 数组扩容 每次扩容,长度加size
public T[] capacityArray(int size) {
// 数组扩容
T[] data = transitionArrayClass(array, size);
// 复制数组的元素
copyArrayElement(array, data);
// 返回
return data;
}
// 数组反转
public void reverseArray() {
for (int i = 0; i < array.length / 2; i++) {
T temp = array[array.length - 1 - i];
array[array.length - 1 - i] = array[i];
array[i] = temp;
}
}
// 数组拷贝
public T[] copyArray() {
// 调用 transitionArray 方法
T[] data = transitionArrayClass(array, false);
// 复制数组的元素
copyArrayElement(array, data);
// 返回
return data;
}
// 数组遍历
public void traversalArray() {
for (T t : array) {
System.out.print(t + " ");
}
System.out.println();
}
// 修改指定位置的元素
public void set( T t, int index) {
array[index] = t;
}
// 获取指定位置元素
public T get(int index) {
return array[index];
}
// 复制数组的元素
private void copyArrayElement(T[] oldArray, T[] newArray) {
for (int i = 0; i < oldArray.length; i++) {
newArray[i] = oldArray[i];
}
}
// 强制类型转换 将Object类型强制转换为T类型
private T[] transitionArrayClass(T[] array, Boolean flag) {
if (flag) {
return (T[]) new Object[array.length + 1];
}
return (T[]) new Object[array.length];
}
// 强制类型转换 将Object类型强制转换为T类型
private T[] transitionArrayClass(T[] array, int size) {
return (T[]) new Object[array.length + size];
}
}
(三)、排序
class Array<T>{
// 冒泡排序
public int[] bubbleSort(int[] arrayName) {
for (int i = 0; i < arrayName.length - 1; i++) {
for (int j = 0; j < arrayName.length - 1 - i; j++) {
if (arrayName[j] > arrayName[j + 1]) {
int temp = arrayName[j + 1];
arrayName[j + 1] = arrayName[j];
arrayName[j] = temp;
}
}
}
return arrayName;
}
// 选择排序
public int[] choiceSort(int[] arrayName) {
for (int x = 0; x < arrayName.length - 1; x++) {
int min = x;
for (int y = x + 1; y < arrayName.length; y++) {
if (arrayName[y] < arrayName[min]) {
min = y;
}
}
int temp = arrayName[x];
arrayName[x] = arrayName[min];
arrayName[min] = temp;
}
return arrayName;
}
}
(四)、查找
class Array<T>{
// 顺序查找
public int SequentialSearch(String[] array) {
Scanner sc = new Scanner(System.in);
System.err.print("请你输入要查找的元素:");
String name = sc.next();
int index = -1;
for (int i = 0; i < array.length; i++) {
if (name.equals(array[i])) {
index = i;
break;
}
}
return index;
}
}
八、面向对象
(一)、简介
1、概述:是一种通过对象的方式,把现实世界映射到计算机模型的一种编程方法
2、对比
面向过程 | 面向对象 | |
---|---|---|
设计思路 | 自顶向下、层次化、分解 | 自底向上、对象化、综合 |
程序单元 | 函数模块 | 对象 |
设计方法 | 程序=算法+数据结构 | 程序=对象=数据+方法 |
优点 | 相互独立,代码共享,性能相对较 | 使用灵活,易维护、易复用、易扩展 |
缺点 | 修改、维护困难 | 性能相对较低 |
(二)、类
1、概述:用来描述一类具有相同特征(属性)和相同行为(方法)的对象
2、定义格式
public class 类名{
//成员变量
//成员方法
}
3、特点
(1)、类是对象的数据类型
(2)、类是具有相同属性和行为的一组对象的集合
4、类和对象的关系
(1)、类是对象的抽象
(2)、对象是类的实例化
(三)、对象
1、概述:是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位
2、特点
(1)、对象具有属性和行为
(2)、对象具有变化的状态
(3)、对象具有唯一性
(4)、对象都是某个类别的实例
(5)、 一切皆为对象
3、在内存的存在形式
(1)、栈: 一般存放基本数据类型(局部变量)
(2)、堆: 存放对象(Cat cat , 数组等)
(3)、方法区:常量池(常量,比如字符串), 类加载信息
(四)、成员方法
1、语法
访问修饰符 返回值类型 方法名称(参数列表){
方法体
}
2、优点
(1)、提高了代码的复用性
(2)、可以将实现的细节封装起来,供其他用户使用
3、注意事项
(1)、一个方法最多有一个返回值
(2)、返回值可以是任意类型
(3)、如果方法中有返回数据类型,则方法体的最后必须加上return 值,且返回值类型和return的值的类型一致或者是兼容
(4)、如果方法中没有返回值类型,也可以加上return,但是不能在后面加值
(5)、方法中可以为0个参数,也可以为多个参数,参数之间用逗号隔开
(6)、参数类型为任意类型
(7)、传入参数时,参数的类型要和方法中的参数列表的中的类型一致或者是兼容
(8)、同一类中的方法调用直接调用即可
(9)、跨类调用方法时,需要通过对象名直接调用
4、方法传参机制:在Java中,方法的参数传递是值(值/地址)传递,而不是引用传递
5、重载
(1)、概述:同一个类中,有多个同名方法存在,但形参列表不同
(2)、要求
①、方法名相同
②、参数列表不同
(3)、优点
①、减小了记名的好处
②、减小了程序员起名的好处
6、重写
(1)、概述:子类有个方法和父类的方法的名称、返回类型、参数一样
(2)、规则
①、参数列表必须完全与被重写的方法参数列表相同
②、返回的类型必须与被重写的方法的返回类型相同
③、访问权限不能比父类中被重写方法的访问权限更低
④、重写方法一定不能抛出新的检査异常或者比被重写方法声明更加宽泛的检査型异常
(3)、作用:子类可以完善父类之中不足之处,使自身的方法更加的完善
(4)、注意事项
①、重写的方法可以使用 @Override 注解来标识
②、父类的成员方法只能被它的子类重写
③、声明为 final 的方法不能被重写
④、声明为 static 的方法不能被重写,但是能够再次声明
⑤、构造方法不能被重写
⑥、子类和父类在同一个包中时,子类可以重写父类的所有方法,除了声明为 private 和 final 的方法;子类和父类不在同一个包中时,子类只能重写父类的声明为 public 和 protected 的非 final 方法
⑦、如果不能继承一个方法,则不能重写这个方法
7、可变参数
(1)、概述:同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法
(2)、语法格式
访问修饰符 返回类型 方法名(数据类型... 形参名){
执行代码块;
}
(3)、注意事项
①、可变参数的实参可以为0个或任意多个
②、可变参数的实参可以为数组
③、可变参数的本质就是数组
④、可变参数必须定义在参数列表的最后
⑤、一个形参列表只能出现一个可变参数
8、递归
(1)、概述:自己调用自己
(2)、注意事项
①、执行一个方法时,就会创建一个受保护的独立空间
②、方法的局部变量是独立的,不会相互影响
③、如果方法中使用的引用类型变量,就会共享引用类型的数据
④、递归必须向退出递归的条件逼近,否则就是无限递归
⑤、当一个方法执行完毕,或者是遇到return时,就会返回
(五)、成员变量
1、位置:定义在方法的外部,类的内部,作用为整个类
2、存储位置:堆内存
3、注意事项
(1)、不需要初始值,有默认值
(六)、局部变量
1、位置:定义在方法上或方法的内部,作用为该方法内或语句块中
2、存储位置:栈内存
3、注意事项
(1)、必须要有初始值,否则报错
(七)、构造器
1、作用:完成了对象成员的初始化工作,简化了对象初始化的代码
2、特点
(1)、方法名必须与类名相同
(2)、可以有 0 个、1 个或多个参数
(3)、没有任何返回值,包括 void
(4)、默认返回类型就是对象类型本身
(5)、只能与 new 运算符结合使用
3、注意事项
(1)、构造方法不能被 static、final、synchronized、abstract 、native修饰
(2)、不要在构造方法里使用 return 来返回当前类的对象
(3)、当自己定义了构造方法,那么Java就不会提供默认的构造方法了
(4)、一个类中可以定义不同的构造方法,即构造方法的重载
(5)、构造方法时完成对象的初始化,而不是创建对象
(6)、在创建对象时,系统自动调用该类分构造方
(八)、this
1、概述:它所在方法所属对象的引用
2、作用
(1)、在没有static关键字修饰的方法中使用
(2)、用来区分成员变量和局部变量同名
(3)、在该类的构造器中的第一行出现this,则代表了该类的构造器调用其他的构造方法
3、操作
(1)、调用类中的属性
(2)、调用类中的方法或构造方法
(九)、封装
1、概述:是将代码及其处理的数据绑定在一起的一种编程机制
2、作用
(1)、隐藏实现细节,保证数据的安全性与合理性
(2)、防止该类的代码和数据被外部类定义的代码随机访问
(十)、继承
1、概述:子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法, 使得子类具有父类相同的行为
2、特点
(1)、继承要有一定的层次结构,而且还要具备一定的可传递性
(2)、子类继承了父类的所有属性和方法,但是不包括私有属性和构造方法
(3)、子类继承父类的属性和方法同时也可以有自己的属性和方法。
(4)、Java 只支持单继承。 也就是说一个子类只能有一个父类,父类可以有多个子类
3、作用
(1)、提高代码的复用性
(2)、代码的可扩展性和维护性提高了
4、注意事项
(1)、子类继承了所有的属性和方法,但是私有属性和方法不能在子类直接访问,要通过公共的方法进行访问
(2)、子类必须调用父类的构造器,完成对父类的初始化
(3)、当创建子类对象,不管使用子类的那个构造器,都会默认调用父类的无参构造器;若父类没有无参构造器,则必须在子类的构造器中手动调用,否则编译不通过
(4)、若希望指定调用父类的哪一个构造器,则需要显示调用
(5)、super关键字必须在构造器的第一行
(6)、super()和this()都只能放在构造器的第一行,所有这两个方法不能同时存在一个构造器中
(7)、java所有类都是Object的子类
(8)、父类的构造器的调用不限于直接父类,可以一直追溯到Object类
(9)、子类最多只能继承一个父类,即java支持的是单继承
(10)、不能随便滥用继承,父类与子类之间必须满足一定关系才行(is-a)
(十一)、super
1、概述:表示当前类的父类的引用
2、特定要求:只能出现在有继承关系的子类中
3、注意事项
(1)、分工明确,父类属性由父类初始化,子类由子类进行初始化
(2)、解决了子类与父类的成员重名问题
(3)、不限于直接父类,遵守就近原则
(4)、访问父类的构造器是,必须放在当前类的构造器的第一行
4、作用
(1)、访问分类的属性,但是不能访问父类的private属性
(2)、访问父类的方法,但是不能访问父类的private方法
(3)、访问父类的构造器
(十二)、多态
1、概述:同一个行为具有多个不同表现形式或形态的能力
2、具体体现
(1)、方法多态:方法重写实现的动态多态性和方法重载实现的静态多态性
(2)、对象多态
①、一个对象的编译类型和运行类型可以不一致
②、编译类型在定义对象时,就确定了,不能改变
③、运行类型是可以变化的
④、编译类型看定义的时的等号的左边,运行类型看等号的右边
3、前提条件
(1)、类与类之间存在继承关系
(2)、发生了向上转型
4、向上转型
(1)、概述:父类引用指向子类对象为向上转型
(2)、语法:父类类型 引用名 = new 子类类型
(3)、特点
①、编译类型看左边,运行类型看右边
②、可以调用父类中所有成员,但要遵守访问权限
③、不能调用子类中特有成员
④、最终效果看子类的具体实现
5、向下转型
(1)、概述:子类对象指向父类引用为向下转型
(2)、语法:子类类型 引用名 = (子类类型)父类引用
(3)、要求:父类的引用必须指向的是当前目标类型的对象
(4)、注意事项
①、只能强制父类的引用,不能强制父类的对象
②、可以调用子类类型中所有的成员
6、动态绑定机制
(1)、当调用对象方法时,该方法会和该对象的运行类型绑定
(2)、当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用
(十三)、static
1、概述:静态的
2、作用:根据修饰的位置不同,所代表的含义不同,主要是用来修饰类、变量、方法或代码块
3、用法
(1)、变量:类变量,也叫静态变量/属性,是该类所有对象共享的变量
(2)、方法:类方法,也叫静态方法/行为,是该类所有对象共享的变量
(3)、代码块:类代码块,是该类所有对象共享的变量,用于类的初始化操作
(4)、类:嵌套内部类,是该类所有对象共享的变量
4、注意事项
(1)、静态成员不能调用非静态成员
(2)、用该修饰的成员的归属着为类,不再为对象了
(十四)、final
1、概述:最终的,不可改变的
2、作用:根据修饰的位置不同,所代表的含义不同,可以用来修饰变量,方法、以及类
3、用法
(1)、变量:一旦赋值,就不能再次更改,对于成员变量来说,我们必须在声明或构造方法中对它赋值
(2)、方法:表示该方法不能被重写
(3)、方法参数:表示在变量的生存期间它的值不能被改变
(4)、类:表示该类无法被继承,即不能拥有自己的子类
4、注意事项
(1)、final关键字可以用于成员变量、本地变量、方法以及类
(2)、final成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会报编译错误。
(3)、你不能够对final变量再次赋值
(4)、本地变量必须在声明时赋值
(5)、在匿名类中所有变量都必须是final变量
(6)、final方法不能被重写、final类不能被继承
(7)、final关键字不同于finally关键字,后者用于异常处理。
(8)、final关键字容易与finalize()方法搞混,后者是在Object类中定义的方法,是在垃圾回收之前被JVM调用的方法
(9)、接口中声明的所有变量本身是final的
(10)、final和abstract这两个关键字是反相关的,final类就不可能是abstract的
(11)、final方法在编译阶段绑定,称为静态绑定(static binding)
(12)、没有在声明时初始化final变量的称为空白final变量(blank final variable),它们必须在构造器中初始化,或者调用this()初始化。不这么做的话,编译器会报错“final变量(变量名)需要进行初始化”
(13)、将类、方法、变量声明为final能够提高性能,这样JVM就有机会进行估计,然后优化
(14)、按照Java代码惯例,final变量就是常量,而且通常常量名要大写
(十五)、代码块
1、概述:用"{}"括起来的代码称为代码块
2、用途
(1)、局部代码块:在方法中
(2)、构造代码块:依赖于构造器执行而先执行
(3)、同步代码块:用synchronized关键词修饰的代码块
(4)、静态代码块:用static关键词修饰的代码块
3、优点
(1)、相当与另一种形式的构造器,可以做初始化操作
(2)、抽取重复的代码,提高代码的复用性
4、代码块执行顺序
(1)、静态代码块
(2)、main方法
(3)、构造代码块
(4)、构造方法
(5)、局部代码块
5、继承时代码块执行顺序
(1)、父类静态代码块
(2)、子类静态代码块
(3)、父类代码块
(4)、父类构造方法
(5)、子类代码块
(6)、子类构造方法
(十六)、包
1、概述:是Java语言提供的一种区别类名字命名空间的机制
2、本质:文件夹
3、作用
(1)、区分类的查找与使用
(2)、避免相同的名字的重复
(3)、更加方便的管理类
(4)、控制控制访问范围 |
4、规则:只能包含数字、字母、下划线、小圆点,但不能以数子开头,不能关键字或保留字
5、常用包
(1)、java.lang:基本包,默认导入
(2)、java.util:工具包
(3)、java.net:网络包
(4)、java.awt:GUL包
(5)、java.sql:JDBC包
(6)、java.lang.reflect:反射包
6、注意事项
(1)、必须是程序中可执行的第一行代码
(2)、package语句只能有一句
(3)、package命名要求包含的所有字符均为小写,同时不能有特殊字符
(4)、package可以有多层,每一层有.隔开
(6)、package语句后面的分号不要掉
(7)、包的路径符合所开发的系统模块的定义
(8)、如果定义类的时候没有使用package,那么java就认为我们所定义的类位于默认包里面
(十七)、权限修饰符
1、概述:用于控制方法和属性的的访问权限
2、介绍
访问范围 | private | default(默认) | protected | public |
---|---|---|---|---|
同类 | 可访问 | 可访问 | 可访问 | 可访问 |
同包 | 不可访问 | 可访问 | 可访问 | 可访问 |
子类 | 不可访问 | 不可访问 | 可访问 | 可访问 |
不同包 | 不可访问 | 不可访问 | 不可访问 | 可访问 |
3、注意事项
(1)、修饰符可以用来修饰类中的属性、成员方法、以及类
(2)、只有默认的和public才能修饰类,并且尊循上述访问权限的特点
(十八)、内部类
1、概述:可以将一个类定义在另一个类里面或者一个方法里面
2、分类
(1)、成员内部类:定义在外部类的成员位置,并且没有static修饰
(2)、静态内部类:定义在外部类的成员位置,并且有static修饰
(3)、局部内部类:定义在外部类的位置,通常在方法上
(4)、匿名内部类:定义在外部类的局部位置
3、使用细节
(1)、成员内部类
①、可以直接访问外部类的所有成员,包括私有的
②、可以添加任意的修饰符
③、作用域为括号的全部的地方
④、外部其他类可以访问该外部类的内部类
⑤、如果外部类和内部类的成员重名时,默认遵守就近原则;如果想使用外部类的成员,可以使用this关键字去访问
(2)、静态内部类
①、可以直接访问外部类的所有静态成员,包括私有的,但是不能直接访问非静态成员
②、可以添加任意的修饰符
③、作用域为整个整体
④、外部类访问静态类,通过创建对象再去访问
⑤、外部其他类可以访问该外部类的内部类
⑥、如果外部类和内部类的成员重名时,默认遵守就近原则;如果想使用外部类的成员,可以使用外部类名加属性名去访问
(3)、局部内部类
①、局部内部类是定义在外部类的局部位置,通常在方法上
②、不能添加访问修饰符,但是可以使用final修饰符
③、作用域仅仅在定义它的方法或代码块中
④、局部内部类可以直接访问外部类的成员
⑤、外部类在方法中,可以创建Inner对象,然后直接调用方法即可
⑥、如果外部类与局部内部类的成员重名时,默认遵守就近原则,如果想访问外部类的成员,则使用外部类名.this.成员去访问
(4)、匿名内部类
①、可以直接访问外部类的所有的成员,包括私有的
②、不能添加修饰符,但是可以使用final修饰符
③、作用域仅仅在定义的方法中或代码块中
④、如果外部类和内部类的成员重名时,默认遵守就近原则;如果想使用外部类的成员,可以使用this关键字去访问
⑤、外部类在方法中,直接创建内部来对象,然后调用方法即可
⑥、外部其它类不能直接访问局部内部类
(十九)、抽象类
1、概述:如果一个类中没有包含足够的信息来描绘一个具体的对象
2、语法
(1)、类
访问修饰符 abstract 类名{
// 抽象方法
}
(2)、方法
访问修饰符 abstract 返回类型 方法名(参数列表);
3、作用:就是让子类继承重写抽象方法,实现代码的扩展
4、注意事项
(1)、抽象类不能实例化
(2)、抽象类不一定要有抽象方法
(3)、一个类中若是有一个抽象方法,那么这个类就是一个抽象类
(4)、abstract只能修饰类和方法,不能修饰属性和其它的
(5)、抽象类可以有任意成员
(6)、抽象方法没有主体
(7)、如果一个类继承了抽象类,则该类必须实现抽象类中所有的抽象方法,除非该类也声明位抽象类
(8)、抽象方法不能使用private、final、static来修饰
(二十)、接口
1、概述:是一个抽象类型,是抽象方法的集合
2、声明语法
访问修饰符 interface接口名{
// 抽象方法
}
3、实现语法
访问修饰符 class 类名 implements 接口名{
// 必须实现接口中的抽象方法
}
4、注意事项
(1)、接口不能被实例化
(2)、接口中所有的方法是public方法,接口中的抽象方法,可以不用加abstract修饰;jdk1.8之后,接口就允许有静态方法和方法体,默认使用default关键字修饰;jdk1.9之后,可以将方法设置private
(3)、一个普通类实现一个接口,则必须实现接口中所有的方法
(4)、抽象类实现接口,可以不实现接口的方法
(5)、一个类可以同时实现多个接口
(6)、接口中的属性,只能是final,而且是public static final修饰符,且必须要初始化 (7)、一个接口不能继承其它的类,但是可以继承多个别的接口
(8)、接口的修饰符是默认的public
5、对比
(1)、与类区别
①、接口不能用于实例化对象
②、接口没有构造方法
③、接口中所有的方法必须是抽象方法,Java 8 之后 接口中可以使用 default 关键字修饰的非抽象方法。
④、接口不能包含成员变量,除了 static 和 final 变量
⑤、接口不是被类继承了,而是要被类实现
⑥、接口支持多继承
(2)、与抽象类区别
①、抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行
②、抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的
③、接口中不能含有静态代码块以及静态方法,而抽象类是可以有静态代码块和静态方法
④、一个类只能继承一个抽象类,而一个类却可以实现多个接口、
九、泛型
1、概述:可以在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高了代码的重用率
2、好处
(1)、编译时,检查添加元素的类型,提高了安全性
(2)、减少了类型转换的次数,提高了效率
(3)、不再提醒编译警告
3、作用:可以在类声明时通过一个标识表示类中某中某个属性的类型,或者时某个方法的返回值的类型,或者是参数类型
4、注意事项
(1)、泛型只能是引用类型
(2)、在指定泛型之后,可以传入该类型或者其子类类型
(3)、如果没有明确写入泛型,就是默认是Object类型
5、自定义泛型
(1)、类
①、普通成员可以使用泛型
②、使用泛型的数组,不能初始化
③、静态方法重不能使用类的泛型
④、泛型类的类型,是在创建对象时确定
⑤、如果在创建对象时,没有指定类型,默认为Object
(2)、接口
①、接口中,静态成员也不能使用泛型
②、泛型接口的类型,在继承接口或者实现接口时确认
③、没有指定类型,默认为Object
(3)、方法
①、泛型方法,可以定义在普通类中,也可以定义在泛型类中
②、当泛型方法被调用时,类型会确定
③、当修饰符后没有泛型,不是泛型方法,而是使用了泛型
6、泛型继承和通配符
(1)、泛型不具备继承性
(2)、<?>:支持任意泛型类型
(3)、<? extends A>:支持A类以及A类的子类,规定了泛型的上限
(4)、<? super A>:支持A类以及A类的父类,不限于直接父类,规定了泛型的下限
十、集合
(一)、Collection
1、概述:是单列集合的顶层接口
2、常用方法
(1)、add(e):在集合末尾添加一个元素
public class CollectionTest {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<>();
collection.add("1");
collection.add("222");
System.out.println(collection);
}
(2)、remove(o):删除指定的元素
public class CollectionTest {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<>();
collection.remove("1");
System.out.println(collection);
}
}
(3)、clear():清空集合中的元素
public class CollectionTest {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<>();
collection.clear();
System.out.println(collection);
}
}
(4)、contains(o):判断集合中是否包含指定的元素
public class CollectionTest {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<>();
System.out.println(collection.contains("1"));
System.out.println(collection.contains("2"));
}
}
(5)、isEmpty():判断集合是否为空
public class CollectionTest {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<>();
System.out.println(collection.isEmpty());
}
}
(6)、size:返回集合中的元素的个数
public class CollectionTest {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<>();
System.out.println(collection.size());
}
}
(7)、addAll(c):将指定集合中的元素添加到另一个集合中去
public class CollectionTest {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<>();
Collection<String> collectionAll = new ArrayList<>();
collectionAll.addAll(collection);
System.out.println(collectionAll);
}
}
3、遍历方式
(1)、迭代器:专门为单列集合所特有的遍历方式
public class CollectionTest {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<>();
Iterator<String> iterator = collection.iterator();
while(iterator.hasNext()){ // hasNext():查询该迭代器中是否还有下一个元素
Object o = iterator.next();// next():将该元素的值取出来
System.out.println(o);
}
}
}
(2)、增强for
public class CollectionTest {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<>();
for (Object o : collectionAll) {
System.out.println(o);
}
}
}
(二)、List
1、概述:是Collection接口的子接口,可以存储有序可重复的集合
2、特点
(1)、集合中的元素允许重复
(2)、集合中的元素是有顺序的,各元素插入的顺序就是各元素的顺序
(3)、集合中的元素可以通过索引来访问或者设置
3、特有方法
(1)、add(index,o):向指定下标位置添加元素
public class ListTest {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add(2,"1.5");
System.out.println(list);
}
}
(2)、get(index):获取指定下标元素
public class ListTest {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
System.out.println(list.get(1));
}
}
(3)、set(index,o):修改指定下标元素
public class ListTest {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.set(2,"3");
System.out.println(list);
}
}
(4)、indexOf(Object o):返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1
public class ListTest {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
System.out.println(list.indexOf("2"));
}
}
4、遍历方式
(1)、迭代器
public class ListTest {
public static void main(String[] args) {
List<String> list= new ArrayList<>();
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){ // hasNext():查询该迭代器中是否还有下一个元素
Object o = iterator.next();// next():将该元素的值取出来
System.out.println(o);
}
}
}
(2)、增强for
public class CollectionTest {
public static void main(String[] args) {
List<String> list= new ArrayList<>();
for (Object o : list) {
System.out.println(o);
}
}
}
(3)、普通for
public class CollectionTest {
public static void main(String[] args) {
List<String> list= new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
Object o = list.get(i);
System.out.println(o);
}
}
}
(三)、ArrayList
1、特点:底层数据结构是数组,查询快,增删慢,线程不安全,效率高,可以存储重复元素,可以存储null值
2、扩容机制
(1)、无参:当创建ArrayList对象时,初始elementData容量为0,第一次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1.5倍
(2)、有参:当创建ArrayList对象时,初始elementData容量为指定大小,如果需要扩容则直接扩容elementData为1.5倍
3、特有方法:无
(四)、Vector
1、特点:底层数据结构是数组,查询快,增删慢,线程安全,效率低,可以存储重复元素,可以存储null值
2、扩容机制
(1)、无参:当创建Vector对象时,默认容量就是10,再次扩容时按照2倍扩容
(2)、有参:当创建Vector对象时,就直接按照2倍进行扩容
3、特有方法
(1)、先省略
(五)、LinkedList
1、特点:底层数据结构是链表,查询慢,增删快,线程不安全,效率高,可以存储重复元素
2、扩容机制
3、特有方法
(1)、先省略
(六)、Set
1、概述:是Collection接口的子接口,无序集合,不允许存放重复的元素
2、特点
(1)、无序 (添加和取出的顺序不一致) ,没有索引
(2)、不允许重复元素,所以最多包含一个null
3、特有方法
(1)、先省略
4、遍历方式
(1)、迭代器
Iterator iterator = set.iterator();
while(iterator.hasNext()){
Object o = iterator.next();
System.out.println(o);
}
(2)、增强for
for (Object o : set) {
System.out.println(o);
}
(七)、HashSet
1、特点:底层数据结构采用哈希表实现,元素无序且唯一,线程不安全,效率高,可以存储null元素
2、扩容机制
3、特有方法
(1)、先省略
(八)、LinkedHashSet
1、特点:底层数据结构采用哈希表实现,元素有序且唯一,线程不安全,效率高,可以存储null元素
2、扩容机制
3、特有方法
(1)、先省略
(九)、Map
(十)、HashMap
(十一)、HashTable
(十二)、Properties
(十三)、Collections
十一、枚举
1、概述:是一种特殊的类,就是包含一组有限的特定的对象的集合
2、实现方式
enum Season {
SPRING("春天", "温暖"), SUMMER("夏天", "炎热"), AUTUMN("秋天", "凉爽"), WINTER("冬天", "寒冷");
private String name;
private String desc;
private Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
}
3、注意事项
(1)、但我使用enum关键字来开发是,默认为继承Enum类,且是一个最终(final)类
(2)、传统的public final static Season SPRING = new Season("春天","温暖");简化成SPRING("春天","温暖"),需要知道是调用那个构造器
(3)、如果是使用无参构造器创建枚举对象,则实参列表和小括号可以省略
(4)、当有多个枚举对象时,使用,间隔,最后为;结尾
(5)、枚举对象必须放在枚举类的行首
4、常用方法
(1)、name:输出枚举对象的名字(推荐使用toString方法)
class EnumName {
public static void main(String[] args) {
String name = Season.AUTUMN.name();
System.out.println(name);
}
}
(2)、ordinal:输出的时该枚举对象的编号,从0开始
class EnumOrdinal {
public static void main(String[] args) {
int ordinal = Season.SPRING.ordinal();
System.out.println(ordinal);
}
}
(3)、values:返回的是一个包含所以的枚举对象
class EnumName {
public static void main(String[] args) {
Season[] seasons = Season.values();
for (Season season : seasons) {
System.out.println(season);
}
}
}
(4)、compareTO:比较两个枚举常量的编号,其本质就是拿前面的编号减去后面的编号
class EnumCompareTO {
public static void main(String[] args) {
int i = Season.AUTUMN.compareTo(Season.SUMMER);
System.out.println(i);
}
}
5、使用细节
(1)、使用枚举之后就不能继承其它类了
(2)、enum是是实现了枚举类了,所以可以去实现接口
十二、注解
1、概述:是提供一种为程序元素设置元数据的方法
2、作用
(1)、作为特定标记,用于告诉编译器一些信息
(2)、编译时动态处理,如动态生成代码...
(3)、运行时动态处理,作为额外信息的载体
3、内置注解
(1)、@Override :限定某个方法,是重写父类的方法,只用于方法
(2)、@Deprecated :用于表示某个程序元素(类、方法等)已过时
(3)、@SuppressWarnings :抑制编译器警告
(4)、@SafeVarargs:参数安全类型注解
(5)、@FunctionalInterface:函数式接口注解
4、元注解
(1)、@Retention
①、概述:指定注解的保存时间
②、取值说明
值 | 说明 |
---|---|
RetentionPolicy.SOURCE | 类 |
RetentionPolicy.CLASS | 字节码文件 |
RetentionPolicy.RUNTIME | 运行时 |
(2)、@Target
①、概述:指定注解的在那些位置可以使用
②、取值说明
值 | 说明 |
---|---|
ElementType.TYPE | 类、接口、枚举 |
ElementType.FIELD | 字段 |
ElementType.METHOD | 方法 |
ElementType.PARAMETER | 参数 |
ElementType.CONSTRUCTOR | 构造器 |
ElementType.LOSAL_VARIABLE | 局部变量 |
ElementType.ANNOTATION_TYPEP | 注解 |
ElementType.PACKAGE | 包 |
ElementType.TYPE_PARAMETER | 泛型参数 jdk1.8 |
ElementType.TYPE_USE | 任何元素 jdk1.8 |
(3)、@Documented :指定该注解是否在javadoc中体现
(4)、@Inherited :子类继承父类注解
5、自定义注解
(1)、格式
public @interface 注解名 {
修饰符 返回值 属性名() 默认值;
修饰符 返回值 属性名() 默认值;
}
(2)、反射获取注解中信息
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.PACKAGE, ElementType.TYPE, ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.FIELD,
ElementType.LOCAL_VARIABLE, ElementType.PARAMETER})
public @interface AnyAnnotation {
int order() default 0;
String desc() default "";
}
@AnyAnnotation(order = 1, desc = "我是类上的注释")
public class ReflectAnnotationDemo {
@AnyAnnotation(order = 2, desc = "我是成员属性")
private String name;
@AnyAnnotation(order = 3, desc = "我是构造器")
public ReflectAnnotationDemo(@AnyAnnotation(order = 4, desc = "我是构造器参数") String name) {
this.name = name;
}
@AnyAnnotation(order = 45, desc = "我是方法")
public void method(@AnyAnnotation(order = 6, desc = "我是方法参数") String msg) {
@AnyAnnotation(order = 7, desc = "我是方法内部变量") String prefix = "I am ";
System.out.println(prefix + msg);
}
public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
Class<ReflectAnnotationDemo> clazz = ReflectAnnotationDemo.class;
// 获取类上的注解
Annotation[] annotations = clazz.getAnnotations();
printAnnotation(annotations);
// 获取成员属性注解
Field name = clazz.getDeclaredField("name");
Annotation[] annotations1 = name.getAnnotations();
printAnnotation(annotations1);
//获取构造器上的注解
Constructor<ReflectAnnotationDemo> constructor = clazz.getConstructor(String.class);
AnyAnnotation[] annotationsByType = constructor.getAnnotationsByType(AnyAnnotation.class);
printAnnotation(annotationsByType);
// 获取构造器参数上的注解
Parameter[] parameters = constructor.getParameters();
for (Parameter parameter : parameters) {
Annotation[] annotations2 = parameter.getAnnotations();
printAnnotation(annotations2);
}
// 获取方法上的注解
Method method = clazz.getMethod("method", String.class);
AnyAnnotation annotation = method.getAnnotation(AnyAnnotation.class);
printAnnotation(annotation);
// 获取方法参数上的注解
Parameter[] parameters1 = method.getParameters();
for (Parameter parameter : parameters1) {
printAnnotation(parameter.getAnnotations());
}
}
public static void printAnnotation(Annotation... annotations) {
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
}
}
十三、异常
1、概述:程序在运行过程中产生的错误称为异常
2、分类
(1)、Error:Java虚拟机无法解决的严重问题
(2)、Exception:其它因编程错误或偶然的外在因素导致的一般问题,可以使用针对性的代码进行处理
3、常见异常
(1)、NullPointerException:空指针异常
(2)、ArithmeticException:数学运算异常
(3)、ArrayIndexOutOfBoundsException:数组下标越界异常
(4)、ClassCastException:类型转换异常
(5)、NumberFormatException:数字格式不正确异常
(6)、SQLException:操作数据库时,查询表可能发生异常
(7)、IOException:操作文件时,发生的异常
(8)、FileNotFoundException:当操作一个不存在的文件时,发生异常
(9)、ClassNotFoundException:加载类,而该类不存在时,异常
(10)、EOFException :操作文件,到文件未尾,发生异常
(11)、IllegalArgumentException:参数异常
4、异常处理
(1)、概述:当异常发生时,对异常的处理
(2)、方式
①、抛出:使用throws抛出异常,让调用者去处理
②、捕获:使用try-catch-finally进行捕获,然后自行处理
(3)、作用:为了能够及时有效地处理程序中的运行错误,让程序具有极好的容错性且更加健壮
5、自定义异常
(1)、概述:当程序中出现了某些错误,但该错误信息并没有再Throwable子类中描述处理,就再这个时候就可以自己设计异常类,用于描述该错误信息
(2)、作用
①、可以让系统及时识别并处理,不至于扩散,从而产生更大地影响力
②、是程序更加稳健,有更好的容错性能,系统更加安全稳定
十四、IO流
(一)、File
1、概述:是文件和目录路径名的抽象表示
2、作用:主要用于文件和目录的创建、查找和删除等操作
3、构造方法
(1)、File(String pathname) : 直接通过文件路径字符串创建
public class FileConstruct {
public static void main(String [] args) {
String pathName = "d:\\file\\file.txt";
File file = new File(pathName);
System.out.println(file);
}
}
(2)、File(String parent, String child) : 通过父和子路径字符串创建
public class FileConstruct {
public static void main(String [] args) {
String parent = "d:\\file";
String child = "file.txt";
File file = new File(parent, child);
System.out.println(file);
}
}
(3)、File(File parent, String child) : 先创建父级 file 对象,再结合子路径创建
public class FileConstruct {
public static void main(String [] args) {
File parentDir = new File("d:\\file");
String child = "file.txt";
File file = new File(parentDir, child);
System.out.println(file);
}
}
4、常用方法
(1)、获取功能方法
①、getAbsolutePath() :返回指定 File 实例的绝对路径
public class FileGet {
public static void main(String[] args) {
File file = new File("d:" + File.separator + "file.txt");
System.out.println("文件绝对路径:"+file.getAbsolutePath());
}
}
②、getPath() :将指定 File 实例的抽象路径名转换为一个路径名字符串
public class FileGet {
public static void main(String[] args) {
File file = new File("d:" + File.separator + "file.txt");
System.out.println("文件构造路径:"+file.getPath());
}
}
③、getName() :返回指定 File 实例的目录或文件名
public class FileGet {
public static void main(String[] args) {
File file = new File("d:" + File.separator + "file.txt");
System.out.println("文件名称:"+file.getName());
}
}
④、length() :返回指定 File 实例的文件长度
public class FileGet {
public static void main(String[] args) {
File file = new File("d:" + File.separator + "file.txt");
System.out.println("文件长度:"+file.length()+"字节");
}
}
(2)、判断功能的方法
①、exists() :指定 File 实例代表的文件或者目录是否存在
public class FileIs {
public static void main(String[] args) {
File file1 = new File("d:\\file\\file.txt");
File file2 = new File("d:\\file");
System.out.println("file1是否存在:"+file1.exists());
System.out.println("file2是否存在:"+file2.exists());
}
}
②、isDirectory() :指定 File 实例是不是目录
public class FileIs {
public static void main(String[] args) {
File file1 = new File("d:\\file\\file.txt");
File file2 = new File("d:\\file");
System.out.println("file1是不是目录:"+file1.isDirectory());
System.out.println("file2是不是目录:"+file2.isDirectory());
}
}
③、isFile() :指定 File 实例是不是文件
public class FileIs {
public static void main(String[] args) {
File file1 = new File("d:\\file\\file.txt");
File file2 = new File("d:\\file");
System.out.println("file1是不是文件?:"+file1.isFile());
System.out.println("file2是不是文件?:"+file2.isFile());
}
}
(3)、创建与删除方法
①、createNewFile() :指定 File 实例的文件不存在时,创建空文件
public class FileCreateDelete {
public static void main(String[] args) throws IOException {
File file = new File("file.txt");
System.out.println("是否创建:"+file.createNewFile());
}
}
②、delete() :删除指定 File 实例表示的文件或目录
public class FileCreateDelete {
public static void main(String[] args) throws IOException {
System.out.println("-----创建文件------");
File file1 = new File("file.txt");
System.out.println("-----删除文件------");
System.out.println(file1.delete());
System.out.println("-----创建目录------");
File file2 = new File("fileDir");
System.out.println("-----删除目录------");
System.out.println(file2.delete());
}
}
③、mkdir() :创建指定 File 实例表示的目录
public class FileCreateDelete {
public static void main(String[] args) throws IOException {
File file2 = new File("fileDir");
System.out.println("是否创建:"+ file2.mkdir());
}
}
④、mkdirs() :创建指定 File 实例表示的目录,以及父目录
public class FileCreateDelete {
public static void main(String[] args) throws IOException {
File file = new File("fileDir\\fileDir");
System.out.println(file.mkdirs());
}
}
(4)、目录的遍历
①、list() :返回一个 String 数组,表示指定 File 实例目录中的所有子文件或目录
public class FileList {
public static void main(String[] args) {
File dir = new File("d:\\IDEAProject");
String[] names = dir.list();
for(String name : names) {
System.out.println(name);
}
}
}
②、listFiles() :返回一个 File 数组,表示指定 File 实例目录中的所有的子文件或目录
public class FileList {
public static void main(String[] args) {
File dir = new File("d:\\IDEAProject");
File[] files = dir.listFiles();
for (File file : files) {
System.out.println(file);
}
}
}
(二)、InputStream
1、概述:是字节输入流的超类
2、常用方法
(1)、read():从输入流中读取数据的下一个字节
暂无
(2)、read(byte[] b):从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中
暂无
(3)、read(byte[] b, int off, int len): 将输入流中最多 len 个数据字节读入 byte 数组
暂无
(4)、close():关闭资源
暂无
(三)、FileInputStream
1、概述:是InputStream的实现类;称为文件字节输入流
2、作用:可以从文件系统中的某个文件中获得输入字节
3、构造方法
(1)、FileInputStream(File file):直接通过文件对象创建
暂无
(3)、FileInputStream(String name):直接通过文件路径创建
暂无
(3)、FileInputStream(FileDescriptor fdObj):通过文件描述符创建连接
暂无
4、特有方法:无
5、实例:读取文件的内容
暂无
(四)、BufferedInputStream
1、概述:是FilterInputStream的子类;称为缓存字节输入流
2、作用:是为另一个输入流添加一些功能,即缓冲输入以及支持 mark 和 reset 方法的能力
3、构造方法
(1)、BufferedInputStream(InputStream in):直接使用默认大小的缓存区大小来来创建
暂无
(2)、BufferedInputStream(InputStream in, int size):使用指定指定大小的缓存区大小来来创建
暂无
4、特有方法:实现了InputStream中的mark操作与reset操作
(1)、mark():在此输入流中标记当前的位置
暂无
(2)、reset():将此流重新定位到最后一次对此输入流调用 mark
方法时的位置
暂无
5、实例:读取文件的内容
暂无
(五)、ObjectInputStream
1、概述:是InputStream的实现类;称为对象字节输入流
2、作用:提供反序列化功能,可以将文件中的数据类型+值全部读取出来
3、构造方法
(1)、ObjectInputStream():是一个受保护的构造方法,是为了实现扩展ObjectInputStream的一种方式
暂无
(2)、ObjectInputStream(InputStream in):使用字节输入流创建对象输入流
暂无
4、特有方法:可以读取把八大基本类型包装类型、String、对象的数据
(1)、readByte():读取一个 8 位的字节
暂无
(2)、readShort():读取一个 16 位的 short 值
暂无
(3)、readInt():读取一个 32 位的 int 值
暂无
(4)、readLong():读取一个 64 位的 long 值
暂无
(5)、readDouble(): 读取一个 64 位的 double 值
暂无
(6)、readFloat():读取一个 32 位的 float 值
暂无
(7)、readBoolean():读取一个 boolean 值
暂无
(8)、readChar():读取一个 16 位的 char 值
暂无
(9)、readUTF():读取UTF-8 修改版格式的 String
暂无
(10)、readObject():从 ObjectInputStream 读取对象
暂无
5、实例:读取文件中的数据
暂无
(六)、OutputStream
1、概述:是字节输出流的超类
2、常用方法
(1)、write(int b):将指定的字节写入此输出流
暂无
(2)、write(byte[] b):将 b.length 个字节从指定的 byte 数组写入此输出流
暂无
(3)、write(byte[] b, int off, int len):将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流
暂无
(4)、close():关闭系统资源
暂无
(5)、flush():刷新输出流
暂无
(七)、FileOutputStream
1、概述:是OutputStream的实现类;称为文件字节输出流
2、作用:将程序中的字节输出到磁盘中去
3、构造方法
(1)、FileOutputStream(File file):直接通过文件对象创建
暂无
(2)、FileOutputStream(File file, boolean append):直接通过文件对象创建,通过append控制是否为覆盖还是追加
暂无
(3)、FileOutputStream(String name):直接通过文件路径创建
暂无
(4)、FileOutputStream(String name, boolean append):直接通过文件路径创建,通过append控制是否为覆盖还是追加
暂无
(5)、FileOutputStream(FileDescriptor fdObj):通过文件描述符创建连接
暂无
4、特有方法:无
5、实例:将数据写入文件
暂无
(八)、BufferedOutputStream
1、概述:是FilterOutputStream的子类;称为缓存字节输出流
2、构造方法
(1)、BufferedOutputStream(OutputStream out):直接使用默认大小的缓存区大小来来创建
暂无
(2)、BufferedOutputStream(OutputStream out, int size):直接使用指定大小的缓存区大小来来创建
暂无
3、特有方法:无
4、实例:将数据写入文件
暂无
(九)、ObjectOutputStream
1、概述:是OutputStream的实现类;称为对象字节输出流
2、作用:提供序列化功能,可以将程序中的数据按照数据类型+值存入文件中去
3、构造方法
(1)、ObjectOutputStream():是一个受保护的构造方法,是为了实现扩展ObjectOutputStream的一种方式
暂无
(2)、ObjectOutputStream(OutputStream out):使用字节输出流创建对象输出流
暂无
4、特有方法:可以写入把八大基本类型包装类型、String、对象的数据
(1)、writeByte():写入一个 8 位字节
暂无
(2)、writeShort():写入一个 16 位的 short 值
暂无
(3)、writeInt():写入一个 32 位的 int 值
暂无
(4)、writeLong():写入一个 64 位的 long 值
暂无
(5)、writeDouble():写入一个 64 位的 double 值
暂无
(6)、writeFloat():写入一个 32 位的 float 值
暂无
(7)、writeBoolean():写入一个 boolean 值
暂无
(8)、writeChar():写入一个 16 位的 char 值
暂无
(9)、writeUTF():以 UTF-8 修改版格式写入此 String 的基本数据
暂无
(10)、writeObject():将指定的对象写入 ObjectOutputStream
暂无
5、实例:将数据写入文件
暂无
(十)、Reader
1、概述:是字符输入流的超类
2、常用方法
(1)、read():读取单个字符
暂无
(2)、read(byte[] b):将字符读入数组
暂无
(3)、read(byte[] b, int off, int len): 将字符读入数组的某一部分,需要子类去实现
暂无
(4)、close():关闭资源,需要子类去实现
暂无
(十一)、FileReader
1、概述:是InputStreamReader的子类;称为文件字符输入流
2、作用:就是将文件里的文本内容读取到控制台中
3、构造方法
(1)、FileReader(File file):直接通过文件对象创建
暂无
(2)、FileReader(String fileName):直接通过文件路径创建
暂无
(3)、FileReader(FileDescriptor fd):通过文件描述符创建连接
暂无
4、特有方法:无
5、实例:读取文件的内容
暂无
(十二)、BufferedReader
1、概述:是Reader的实现类;称为缓存字符输入流
2、作用:从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取
3、构造方法
(1)、BufferedReader(Reader in):直接使用默认大小的缓存区大小来来创建
暂无
(2)、BufferedReader(Reader in, int sz):使用指定大小的缓存区大小来来创建
暂无
4、特有方法
(1)、mark():标记流中的当前位置
暂无
(2)、reset():将流重置到最新的标记
暂无
(3)、readLine():读取一个文本行
暂无
5、实例:读取文件的内容
暂无
(十三)、InputStreamReader
1、概述:是Reader的是实现类,称为字节字符转换流,是字节流通向字符流的桥梁
2、作用:将一个字节流的输入对象变为字符流的输入对象
3、构造方法
(1)、InputStreamReader(InputStream in):直接使用字节输入流创建
暂无
(2)、InputStreamReader(InputStream in, String charsetName):直接使用字节输入流创建并指定字符集编码
暂无
(3)、InputStreamReader(InputStream in, Charset cs):直接使用字节输入流创建并指定字符集编码
暂无
(4)、InputStreamReader(InputStream in, CharsetDecoder dec):使用字节输入流创建并指定字符集解码器
暂无
4、特有方法:无
5、实例:读取文件的内容
暂无
(十四)、Writer
1、概述:是字符输出流的超类
2、常用方法
(1)、write(int b):将指定的字节写入此输出流
暂无
(2)、write(byte[] b):将 b.length 个字节从指定的 byte 数组写入此输出流
暂无
(3)、write(byte[] b, int off, int len):将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输
暂无
(4)、write(String str):写入字符串
暂无
(5)、write(String str, int off, int len):写入字符串的某一部分
暂无
(6)、append(char c):将指定字符添加到此 writer
暂无
(7)、append(CharSequence csq):将指定字符序列添加到此 writer
暂无
(8)、append(CharSequence csq, int start, int end):将指定字符序列的子序列添加到此 writer.Appendable
暂无
(9)、close():关闭系统资源
暂无
(10)、flush():刷新输出流
暂无
(十五)、FileWriter
1、概述:是OutputStreamWriter的子类;称为文件字符输出流
2、作用:将程序中的字节输出到磁盘中去
3、构造方法
(1)、FileWriter(File file):直接通过文件对象创建
暂无
(2)、FileWriter(File file, boolean append):直接通过文件对象创建,通过append控制是否为覆盖还是追加
暂无
(3)、FileWriter(String fileName):直接通过文件路径创建
暂无
(4)、FileWriter(String fileName, boolean append):直接通过文件路径创建,通过append控制是否为覆盖还是追加
暂无
(5)、FileWriter(FileDescriptor fd): 通过文件描述符创建连接
暂无
4、特有方法:无
5、实例:将数据写入文件
暂无
(十六)、BufferedWriter
1、概述:是Writer的实现类;称为缓存字符输出流
2、作用:将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入
3、构造方法
(1)、BufferedWriter(Writer out):直接使用默认大小的缓存区大小来来创建
暂无
(2)、BufferedWriter(Writer out, int sz):使用指定大小的缓存区大小来来创建
暂无
4、特有方法
(1)、newLine():写入一个行分隔符
暂无
5、实例:将数据写入文件
暂无
(十七)、OutputStreamWriter
1、概述:是Writer的是实现类,称为字节字符转换流,是字符流通向字节流的桥梁
2、作用:将一个字符流的输出对象变为字节流的输出对象
3、构造方法
(1)、OutputStreamWriter(OutputStream out):直接使用字节输出流创建
暂无
(2)、OutputStreamWriter(OutputStream out, String charsetName):直接使用字节输出流创建并指定字符集编码
暂无
(3)、OutputStreamWriter(OutputStream out, Charset cs):直接使用字节输出流创建并指定字符集编码
暂无
(4)、OutputStreamWriter(OutputStream out, CharsetEncoder enc):使用字节输出流创建并指定字符集解码器
暂无
4、特有方法
(1)、getEncoding():返回此流使用的字符编码的名称
暂无
5、实例:读取文件的内容
暂无
(十八)、Properties
1、概述:专门用于读写配置文件的集合类
2、常用方法
(1)、load:加载配置文件的键值对到 Properties 对象
public class Load {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
properties.load(new FileReader("src\\mysql.properties"));
String ip = properties.getProperty("ip");
System.out.println("ip是:" + ip);
}
}
(2)、list:将数据显示到指定设备
public class List {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
properties.load(new FileReader("src\\mysql.properties"));
properties.list(System.out);
}
}
(3)、getProperty(key):获取值
public class GetProperty {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
properties.load(new FileReader("src\\mysql.properties"));
String ip = properties.getProperty("ip");
String username = properties.getProperty("username");
String password = properties.getProperty("password");
System.out.println("ip是:" + ip);
System.out.println("用户名是:" + username);
System.out.println("密码是:" + password);
}
}
(4)、setProperty(key,value):设置值
public class SetProperty{
public static void main(String[] args) throws IOException {
properties.setProperty("user", "琴酒");
properties.setProperty("pswd", "123");
properties.setProperty("charset", "utf-8");
properties.store(new FileOutputStream("src\\mysql.properties"), null);
}
}
(5)、store:将 Properties 对象的数据写入到文件中去
public class Store {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
properties.setProperty("user", "琴酒");
properties.setProperty("pswd", "123");
properties.setProperty("charset", "utf-8");
properties.store(new FileOutputStream("src\\mysql.properties"), null);
}
}
十五、多线程
1、概述:是多任务的一种特别的形式
2、相关术语
(1)、进程:是计算机中的程序关于某数据集合上的一次运行活动
(2)、线程:是操作系统能够进行运算调度的最小单位
(3)、单线程:同一时刻,只允许执行一个线程
(4)、多线程:同一时刻,可以执行多个线程
(5)、并发:同一时刻,多个任务交替执行
(6)、并行:同一时刻,多个任务同时执行
3、作用:提高程序的处理效率
4、实现多线程
(1)、实现Runnable接口,重写run方法
class Cat implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("我是小猫咪!" + i );
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
class Text {
public static void main(String[] args) {
Cat cat = new Cat();
new Thread(cat).start();
}
}
(2)、继承Thread类,重写run方法
class Cat extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("我是小猫咪!");
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
class Text {
public static void main(String[] args) {
Cat cat = new Cat();
cat.start();
}
}
5、生命周期
(1)、新建状态
(2)、就绪状态
(3)、运行状态
(4)、阻塞状态
(5)、死亡状态
6、常用方法
(1)、currentThread():获取当前的线程对象
暂无
(2)、getId():返回该线程的标识
暂无
(3)、getName():返回该线程的名称
暂无
(4)、setName(String name):改变线程名称
暂无
(5)、getPriority():返回线程的优先级
暂无
(6)、setPriority(int newPriority):更改线程的优先级
暂无
(7)、getState():返回该线程的状态
暂无
(8)、interrupt():中断线程
暂无
(9)、interrupted():测试当前线程是否已经中断
暂无
(10)、isAlive():测试线程是否处于活动状态
暂无
(11)、isDaemon():测试该线程是否为守护线程
暂无
(12)、isInterrupted():测试线程是否已经中断。
暂无
(13)、join():等待该线程终止
暂无
(14)、run():启动run方法
暂无
(15)、setDaemon(boolean on):将该线程标记为守护线程或用户线程
暂无
(16)、sleep(long millis):线程开始休眠millis毫秒
暂无
(17)、start():使该线程开始执行
暂无
(18)、yield():暂停当前正在执行的线程对象,并执行其他线程
暂无
十六、反射
1、概述:是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法
2、优点与缺点
(1)、优点:可以动态的创建和使用对象,使用灵活,没有反射机制,框架技术就失去了底层机制
(2)、缺点:使用反射基本是解释执行,对执行速度有影响
(一)、Class
1、定义:是一个特殊类,它用于表示JVM运行时类或接口的信息
2、常用方法
(1)、newInstance():创建对象
暂无
(2)、getName():返回完整类名带包名
暂无
(3)、getSimpleName():返回类名
暂无
(4)、getFields():返回类中public修饰的属性
暂无
(5)、getDeclaredFields():返回类中所有的属性
暂无
(6)、getDeclaredField(String name):根据属性名name获取指定的属性
暂无
(7)、getModifiers():获取属性的修饰符列表,返回的修饰符是一个数字,每个数字是修饰符的代号
暂无
(8)、getDeclaredMethods():返回类中所有的实例方法
暂无
(9)、getDeclaredMethod(String name, Class<?>… parameterTypes):根据方法名name和方法形参获取指定方法
暂无
(10)、getDeclaredConstructors():返回类中所有的构造方法
暂无
(11)、getDeclaredConstructor(Class<?>… parameterTypes):根据方法形参获取指定的构造方法
暂无
(12)、getSuperclass():返回调用类的父类
暂无
(13)、getInterfaces():返回调用类实现的接口集合
暂无
(14)、getSuperclass():获取一个类的父类
暂无
(15)、getInterfaces():获取一个类实现的接口
暂无
3、获取class对象的方式
(1)、已知类的全类名,通过Class类的静态方法forName()获取
暂无
(2)、已知具体类的实例,调用该实例的getClass()获取
暂无
(3)、直接通过类名.class()获取
暂无
4、注意事项
(1)、该类的对象不是new出来的,而是系统创建的
(2)、对于某个类的Class对象,在内存中只有一份,因为类只加载一次
(3)、每个类的实例都会记得自己是由哪个Class实例所生成
(4)、通过Class可以完整地得到一个类的完整结构
(5)、Class对象是存放在堆的
(6)、类的字节码二进制数据,是存放在方法区的
(二)、Field
1、概述:提供类或接口中成员变量信息
2、常用方法
(1)、getName():返回属性名
暂无
(2)、getModifiers():获取属性的修饰符列表,返回的修饰符是一个数字,每个数字是修饰符的代号
暂无
(3)、getType():以Class类型,返回属性类型
暂无
(4)、set(Object obj, Object value):设置属性值
暂无
(5)、get(Object obj):读取属性值
暂无
(三)、Method
1、概述:提供类或接口成员方法信息
2、常用方法
(1)、getName():返回方法名
暂无
(2)、getModifiers():获取方法的修饰符列表,返回的修饰符是一个数字,每个数字是修饰符的代号
暂无
(3)、getReturnType():以Class类型,返回方法类型
暂无
(4)、getParameterTypes():返回方法的修饰符列表
暂无
(5)、invoke(Object obj, Object… args):调用方法
暂无
(四)、Constructor
1、概述:提供类的构造方法信息
2、常用方法
(1)、getName():返回构造方法名
暂无
(2)、getModifiers():获取构造方法的修饰符列表,返回的修饰符是一个数字,每个数字是修饰符的代号
暂无
(3)、getParameterTypes():返回构造方法的修饰符列表
暂无
(4)、 newInstance(Object … initargs):创建对象
暂无
(五)、Modifier
1、定义:提供类和成员访问修饰符信息
2、常用方法
(1)、isStatic:如果使用 static 修饰符修饰则返回 true,否则返回false
暂无
(2)、isPublic:如果使用 public 修饰符修饰则返回 true,否则返回false
暂无
(3)、isProtected:如果使用 protected 修饰符修饰则返回 true,否则返回false
暂无
(4)、isPrivate:如果使用 private 修饰符修饰则返回 true,否则返回false
暂无
(5)、isFinal:如果使用 final 修饰符修饰则返回 true,否则返回false
暂无
(6)、toString:以字符串形式返回所有修饰符
暂无
十七、JDBC
1、概述:指 Java 数据库连接,是一种标准Java应用编程接口,用来连接 Java 编程语言和广泛的数据库
2、步骤
(1)、第一步:注册驱动
(2)、第二步:获取连接
(3)、第三步:获取数据库操作对象
(4)、第四步:执行SQL语句
(5)、第五步:处理查询结果集
(6)、第六步:释放资源
4、获取数据库连接的方式
(1)、第一种
class JDBC{
private static final String url = "jdbc:mysql://localhost:33306/user";
private static final String username = "root";
private static final String password = "root";
public static Connection getConnection(){
Connection con = null;
try{
Driver driver = (Driver)Class.forName("com.mysql.cj.jdbc.Driver").newInstance();
Properties properties = new Properties();
properties.setProperty("user",username);
properties.setProperty("password",password);
con = driver.connect(url,properties);
}catch(Exception e){
e.printStackTrace();
}
return con;
}
}
(3)、第二种
class JDBC{
private static final String url = "jdbc:mysql://localhost:33306/user";
private static final String username = "root";
private static final String password = "root";
public static Connection getConnection(){
Connection con = null;
try{
Driver driver = (Driver)Class.forName("com.mysql.cj.jdbc.Driver").newInstance();
DriverManager.registerDriver(driver);
con = DriverManager.getConnection(url,username,password);
}catch(Exception e){
e.printStackTrace();
}
return con;
}
}
(4)、第四种
class JDBC{
private static final String url = "jdbc:mysql://localhost:33306/user";
private static final String username = "root";
private static final String password = "root";
public static Connection getConnection(){
Connection con = null;
try{
Class.forName("com.mysql.cj.jdbc.Driver");
con = DriverManager.getConnection(url,username,password);
}catch(Exception e){
e.printStackTrace();
}
return con;
}
}
(5)、第五种
user=root
password=root
url=jdbc:mysql://localhost:33306/user
driver=com.mysql.cj.jdbc.Driver
class JDBC{
public static Connection getConnection(){
Connection con = null;
try{
Properties properties = new Properties();
properties.load(new FileInputStream("jdbc.properties"));
String url = properties.getProperty("url");
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String driver = properties.getProperty("driver");
Class.forName(driver);
con = DriverManager.getConnection(url,user,password);
}catch(Exception e){
e.printStackTrace();
}
return con;
}
}
(一)、Connection
1、概述:与特定数据库的连接,在连接上下文中执行 SQL 语句并返回结果
2、常用方法
(1)、setAutoCommit:设置是否自动提交事务
暂无
(2)、commit:开始提交事务
暂无
(3)、rollback:回滚事务
暂无
(4)、close:关闭资源
暂无
(二)、ResultSet
1、概述:表示数据库结果集的数据表,通常通过执行查询数据库的语句生成
2、常用方法
(1)、next:查看下一行是否还有元素
暂无
(2)、getObject:通过SQL语句中的占位符的数量进行赋值,其中Object可以更换为基本数据类性和String
暂无
(3)、previous”向上一行查看元素
暂无
(4)、close:关闭资源
暂无
(三)、Statement
1、概述:用来执行静态SQL语句并返回生成的结果的对象
2、存在问题:SQL语句注入(在用户输入数据使用非法的SQL语句段或命令,攻击数据库,造成数数丢失)问题
3、常用方法
(1)、executeQuery:执行查询操作
暂无
(2)、executeUpdate:执行更新操作
暂无
(3)、execute:执行任意SQL,返回布尔值
暂无
(4)、close:关闭资源
暂无
(四)、PreparedStatement
1、概述:预编译的 SQL 语句的对象
2、常用方法
(1)、setObject:通过SQL语句中的占位符的数量进行赋值,其中Object可以更换为基本数据类性和String
暂无
(2)、executeQuery:执行查询操作
暂无
(3)、executeUpdate:执行更新操作
暂无
(4)、execute:执行任意SQL,返回布尔值
暂无
(5)、close:关闭资源
暂无
(6)、addBatch:添加批处理地SQL语句或参数
暂无
(7)、executeBatch:执行批处理的语句
暂无
(8)、clear:清空批处理的语句
暂无
(五)、连接池
1、概述:负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏
2、常见的连接池
(1)、C3P0:速度相对较慢,稳定型不错;下载官网:c3p0
(2)、Druid:速度快,稳定性好;下载网址:druid
(3)、Proxool:有监控连接池状态的功能,稳定性较C3P0差一点
(4)、DBCP:速度想多C3P0较快,但不稳定
3、C3P0
(1)、第一种
user=root
password=root
url=jdbc:mysql://localhost:33306/user
driver=com.mysql.cj.jdbc.DrivQer
public class C3P0{
public static Connection getConnection() throws Exception{
//获取数据库的数据源
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
//获取配置文件中内容
Properties properties = new Properties();
properties.load(new FileInputStream("jdbc.properties"));
String url = properties.getProperty("url");
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String driver = properties.getProperty("driver");
//设置数据库连接的用户名
comboPooledDataSource.setUser(user);
//设置数据库连接的密码
comboPooledDataSource.setPassword(password);
//设置数据库连接的url
comboPooledDataSource.setJdbcUrl(url);
//设置数据库连接的驱动
comboPooledDataSource.setDriverClass(driver);
//设置数据库初始连接数
comboPooledDataSource.setInitialPoolSize(10);
//设置最大的连接数
comboPooledDataSource.setMaxPoolSize(20);
//获取连接
return comboPooledDataSource.getConnection();
}
}
(2)、第二种
<!-- 名字国定:c3p0-config.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 数据源名称代表连接池 -->
<named-config name="myc3p0">
<!-- 驱动类 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<!-- url -->
<prpperty name="jdbcUrl">jdbc:mysql://localhost:33306/user</prpperty>
<!-- 用户名 -->
<property name="user">root</property>
<!-- 密码 -->
<property name="password">root</property>
<!-- 每次增长连接数 -->
<property name="acquireIncrement">2</property>
<!-- 初始连接数 -->
<property name="initialPoolSize">4</property>
<!-- 最大连接数 -->
<property name="maxPoolSize">20</property>
<!-- 最小连接数 -->
<property name="minPoolSize">2</property>
<!-- 可连接的最多的命令对像数 -->
<property name="maxStatements">5</property>
<!-- 每个连接对象可连接的最多的命令对象数 -->
<property name="maxStatementsPerConnection">2</property>
</named-config>
</c3p0-config>
public class C3P0{
public static Connection getConnection() throws Exception{
//获取数据库的数据源
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("myc3p0");
//获取连接
return comboPooledDataSource.getConnection();
}
}
4、Druid
user=root
password=root
url=jdbc:mysql://localhost:33306/user
driver=com.mysql.jdbc.Driver
initialSize=10
minIdle=5
maxActive=50
maxWait=5000
public class Druid {
private static DataSource dataSource;
static {
try {
Properties properties = new Properties();
properties.load(new FileInputStream("druid.properties"));
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws Exception{
return dataSource.getConnection();
}
public static void close(ResultSet reflect, Statement statement, Connection connection) {
try {
if (reflect != null) {
reflect.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.commit();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
(六)、封装
1、传统资源封装
class Util {
private static String user;
private static String password;
private static String url;
private static String driver;
static {
user = "root";
password = "root";
url = "jdbc:mysql://localhost:33306/user?rewriteBatchedStatements=true";
driver = "com.mysql.jdbc.Driver";
}
/**
* 获取数据库连接
*/
public static Connection getConnection() {
Connection connection = null;
try {
Class.forName(driver);
connection = DriverManager.getConnection(url, user, password);
} catch (Exception e) {
throw new RuntimeException(e);
}
return connection;
}
/**
* 关闭资源
*/
public static void close(ResultSet reflect, Statement statement, Connection connection) {
try {
if (reflect != null) {
reflect.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.commit();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
2、使用Druid连接池封装
user=root
password=root
url=jdbc:mysql://localhost:33306/user
driver=com.mysql.jdbc.Driver
initialSize=10
minIdle=5
maxActive=50
maxWait=5000
public class Druid {
private static DataSource dataSource;
static {
try {
Properties properties = new Properties();
properties.load(new FileInputStream("druid.properties"));
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws Exception{
return dataSource.getConnection();
}
public static void close(ResultSet reflect, Statement statement, Connection connection) {
try {
if (reflect != null) {
reflect.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.commit();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
3、通用Dao
public class BaseDao<T> {
private QueryRunner queryRunner = new QueryRunner();
/**
* 修改、删除、添加
*/
public int update(String sql, Object... parameters) {
Connection connection = null;
try {
connection = Util.getConnection();
int update = queryRunner.update(connection, sql, parameters);
return update;
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
Util.close(null, null, connection);
}
}
/**
* 获取多行的数据
*/
public List<T> queryMulti(String sql, Class<T> ClassT, Object... parameters) {
Connection connection = null;
try {
connection = Util.getConnection();
return queryRunner.query(connection, sql, new BeanListHandler<T>(ClassT), parameters);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
Util.close(null, null, connection);
}
}
/**
* 获取单行的数据
*/
public T querySingle(String sql, Class<T> ClassT, Object... parameters) {
Connection connection = null;
try {
connection = Util.getConnection();
return queryRunner.query(connection, sql, new BeanHandler<T>(ClassT), parameters);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
Util.close(null, null, connection);
}
}
/**
* 获取单行单列的数据
*/
public Object queryScalar(String sql, Object... parameters) {
Connection connection = null;
try {
connection = Util.getConnection();
return queryRunner.query(connection, sql, new ScalarHandler(), parameters);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
Util.close(null, null, connection);
}
}
}
十八、正侧表达式
1、概述:使用单个字符串来描述、匹配一系列匹配某个句法规则的字符
(一)、Pattern
1、概述:是一个正则表达式的编译表示
2、常用方法
(1)、maches:用于整体匹配,验证输入的字符串是否满足条件使用
暂无
(2)、compile:获取正则表达式的编译对象
暂无
(二)、Matcher
1、概述:是对输入字符串进行解释和匹配操作的引擎
2、常用方法
(1)、start:返回以前匹配的初始索引
暂无
(2)、start(int group):返回在以前的匹配操作期间,由给定组的所捕获的子序列的初始索引
暂无
(3)、end:返回最后匹配字符之后的偏移量
暂无
(4)、en(int group):返回在以前的匹配操作期间,由给定组所捕获子序列的最后字符之后的偏移量
暂无
(5)、lookingAt:尝试将从区域开头开始的输入序列与该模式匹配
暂无
(6)、find:尝试查找与该模式匹配的输入序列的下一个子序列
暂无
(7)、find(int start):重置此匹配器,然后尝试查找匹配该模式,从指定索引开始的输入序列的下一个子序列
暂无
(8)、matches:尝试将整个区域与该模式匹配
暂无
十九、常用类
(一)、Object
1、概述:类层次结构的根类
2、常用方法
(1)、equals():判断是否和某个对象是否相等,只能判断引用类型,子类往往都会重写该方法
暂无
(2)、hashCode():返回对象的哈希码值,但是哈希值只是根据地址值而来,但是不能完全将哈希值等价于地址
暂无
(3)、toString():返回该对象的字符串表示;默认返回全类名 + @ + 哈希值的十六进制,子类往往到会重写
暂无
(4)、finalize():当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法;子类可以重写该方法,做释放资源的操作
暂无
(5)、getClass():返回此 Object 的运行时类
暂无
(二)、包装类
1、概述:八种基本数据类型对应的引用类型
2、对应关系
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
double | Double |
boolean | Boolean |
char | Character |
3、基本数据类型与包装类型的转换
(1)、jdk5之前:手动装箱和拆箱,装箱与拆箱:基本类型<—>包装类型
(2)、jdk5之后:自动装箱和拆箱;底层原理是valueOf方法
4、常用通用方法
(1)、valueOf():将基本数据类型转换为包装类型
暂无
(2)、toString():将包装类型转换为字符串类型
暂无
(三)、String
1、概述:代表不可变的字符序列,用双引号括起来的字符序列
2、常用构造方法
(1)、String():初始化一个新创建的 String 对象,使其表示一个空字符序列
暂无
(2)、String(char[] a):通过指定的char数组,构造一个新的String
暂无
(3)、String(byte[] b):通过指定的 byte 数组,构造一个新的 String
暂无
(4)、String(String original):初始化一个新创建的 String 对象
暂无
3、创建方式
(1)、直接赋值:String str = "海";
(2)、调用构造器:String str = new String("海");
4、特性
(1)、String是一个final类,是代表不可变的字符序列
(2)、字符串是不可变的,一个字符串对象一旦分配,其内容是不可变的
(3)、实现了接口Serializable、Comparable,分别可以串行化、比较大小
5、常用方法
(1)、equals:区分大小写,判断内容是否相等
暂无
(2)、equalsIgnoreCase:忽略大小写,判断内容是否相等
暂无
(3)、length:获取字符的个数,字符串的长度
暂无
(4)、indexOf:获取字符在字符串中第一次出现的索引,索引从0开始,如果找不到,就返回-1
暂无
(5)、lastIndexOf:获取字符的字符串中最后一次出现的索引,索引从0开始,如果找不到,就返回-1
暂无
(6)、substring:截取指定范围的的子串
暂无
(7)、trim:去除前后空格
暂无
(8)、charAt:获取指定位置的字符
暂无
(9)、toUpperCase:将字符串全部转换为大写字母
暂无
(10)、toLowerCase:将字符串全部为小写字母
暂无
(11)、concat:拼接字符串
暂无
(12)、replace:将字符串中的前的字符串替换为后的字符串,形成新的字符
暂无
(13)、split:根据指定字符进行分割
暂无
(14)、compareTo:按字典顺序比较两个字符串
暂无
(15)、toCharArray:将此字符串转换为一个新的字符数组
暂无
(16)、format:使用指定的格式字符串和参数返回一个格式化字符串
暂无
(17)、intern:返回的是常量池的地址
暂无
(四)、StringBuffer
1、概述:可变的字符序列,线程安全
2、常用构造器
(1)、StringBuffer():创建一个大小为16的char[]
暂无
(2)、StringBuffer(int capacity);:创建一个指定大小的char[]
暂无
(3)、StringBuffer(String str);:通过一个String创建StringBuffer
暂无
3、常用方法
(1)、append:在最后进行追加
暂无
(2)、delete:根据索引进行删除
暂无
(3)、replace:根据指定位置将指定字符串进行替换
暂无
(4)、indexOf:查找指定的字符串第一次出现的索引,否则就返回-1
暂无
(5)、insert:在指定位置插入元素
暂无
(6)、length:获取StringBuffer的长度
暂无
4、String和StringBuffer比较
(1)、String保存的是字符串常量,里面的值不能更改,每次String类实际上的就是更改地址,效率较低
(2)、StringBuffer保存字符串变量,里面的值可以更改,每次StringBuffer的更新实际可以更新内容,不用更新地址,效率较高
(五)、StringBuilder
1、概述:可变的字符序列,线程不安全,与StringBuffer使用同一个api
2、String、StringBuufer、StringBuilder之间的区别
(1)、StringBuilder和StringBuffer非常类似,代表可变的字符序列,且方法不一样
(2)、String是不可变序列,效率低,但是复用率高
(3)、StringBuffer是可变序列,效率较高(增删)、线程安全
(4)、StringBuilder是可变序列,效率最高,线程不安全
(六)、Math
1、概述:用于执行基本数学运算的方法
2、常用的方法
(1)、abs:绝对值
暂无
(2)、pow:求幂
暂无
(3)、ceil:向上取整
暂无
(4)、floor:向下取整
暂无
(5)、round:四舍五入
暂无
(6)、sqrt:求平方
暂无
(7)、random:求随机数
暂无
(8)、max:求两个数的最大值
暂无
(9)、min:求两个数的最小值
暂无
(七)、System
1、概述:前Java程序的运行平台
2、常用方法
(1)、exit:退出程序
暂无
(2)、arraycopy:复制数组元素,适合底层调用;一般使用Arrays.copyOf()复制数组
class Array<T> {
public String[] arraycopy(String[] oldArray){
String[] newArray = new String[oldArray.length];
System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
return newArray;
}
}
(3)、currentTimeMillis:返回当前时间距离1970-1-1的毫秒数
暂无
(4)、gc:运行垃圾回收机制
暂无
(八)、BigInteger、BigDecimal
1、应用场景
(1)、BigInteger:适合保存比较大的整形
(2)、BigDecimal:适合保存精度更高的浮点数
2、常用方法
(1)、add:加
暂无
(2)、subtract:减
暂无
(3)、multiply:乘
暂无
(4)、divide:除
暂无
(九)、Date
1、概述:表示精确的时间、瞬间,用毫秒表示(第一代日期类)
2、构造器
(1)、Date():获取当前的系统时间
暂无
(2)、Date(Long log):通过指定的毫秒数从而得到时间
暂无
3、常用方法
(1)、getTime:返回1970-1-1的毫秒数
暂无
(2)、setTime:设置1970-1-1的毫秒数
暂无
(十)、SimpleDateFormat
1、概述:将日期进行格式化、解析
2、模式匹配
(1)、y ——年
(2)、M ——月
(3)、dd ——日
(4)、H ——时(0-23)
(5)、m ——分
(6)、s ——秒
3、构造器
(1)、SimpleDateFormat():创建一个默认的格式去转换
暂无
(2)、SimpleDateFormat(String pattern):根据指定的格式和语言环境去转换
暂无
4、常用方法
(1)、format:将日期转换为指定的字符串
暂无
(2)、parse:解析字符串,转换为Date对象
暂无
(十一)、Calendar
1、概述:它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR等日历字段之间的转换提供了一些方法
2、 常用的字段
(1)、Calendar.YEAR:年
(2)、Calendar.MONTH:月
(3)、Calendar.DAY_OF_MONTH:日
(4)、Calendar.HOUR_OF_DAY:小时
(5)、Calendar.MINUTE:分钟
(6)、Calendar.SECOND:秒
(十二)、LocalDateTime
1、概述:获取时间、日期。JDK1.8加入
2、得到LocalDateTime对象:使用now方法
3、常用方法
(1)、getYear:年
暂无
(2)、getMonthValue:月
暂无
(3)、getDayOfMonth:日
暂无
(4)、getHour:时
暂无
(5)、getMinute:分
暂无
(6)、getSecond:秒
暂无
(十三)、DateTimeFormatter
1、概述:格式化日期对象
2、得到DateTimeFormatter对象:使用ofPattern方法
3、常用方法
(1)、format:将日期转换为指定的字符串
暂无
(2)、parse:解析字符串,转换为Date对象
暂无
二十、网络编程
(一)、网络
1、概述:两台或多台设备通过一定物理设备连接起来构成了网络
2、分类:根据网络的覆盖范围不同进行分类
(1)、局域网:范围最小
(2)、域域网:范围较大
(3)、广域网:范围最大(万维网)
3、网络通信:将数据通过网络从一台设备传输到另一台设备中去
(二)、IP地址
1、概述:用于唯一标识网络中的每台计算机
2、查看IP地址:ipconfig
3、组成:网络地址+主机地址
4、IPV6
(1)、概述:为了替代IPV4的IP协议
(2)、作用:解决了网络地址资源数量的问题,还解决了多种接入设备连入互联网的障碍
(三)、域名
1、概述:将IP地址映射为域名
2、优点:为了方便记忆,解决记IP得困难
(四)、端口号
1、概述:用于标识计算机上的某个特定的网络程序
2、表示形式:以整数形式,它的范围是0~65535
3、常见程序端口号
(1)、tomcat:8080
(2)、mydql:3306
(3)、oracle:1521
(4)、sqlServer:1433
4、注意事项:在开发过程中,不要使用0-1024的端口号
(五)、相关类
1、InetAddress
(1)、定义:对域名进行解析是使用本地机器配置或者网络命名服务和网络信息服务来实现
(2)、常用方法
①、getLocalHost:获取本机的InetAddress对象
暂无
②、getByName:根据指定的主机名/域名获取IP地址
暂无
③、getHostName:获取InetAddress对象的主机
暂无
④、getHostAddress:获取InetAddress对象的地址
暂无
2、Socket
(1)、定义:计算机之间进行通信的一种约定或一种方式
(2)、常用方法
①、accept:获取Socket对象
暂无
②、close():关闭此套接字
暂无
③、isBound():返回套接字的绑定状态。
暂无
④、isClosed():返回套接字的关闭状态。
暂无
⑤、isConnected():返回套接字的连接状态
暂无
(六)、网络通信协议
1、TCP协议
(1)、概述:是面向连接的通信协议,即先建立连接,才可以传输数据
(2)、前提:数据传输前需要采用"三次握手"方式,来保证数据连接可靠
(3)、注意事项
①、在连接时,需要确保客户端和服务端
(4)、优点:安全
(5)、缺点:效率低
(6)、示例
①、发送数据
public class Client {
public static void main(String[] args) throws IOException {
// 创建流套接字并将其连接到指定主机上的指定端口号。
Socket socket = new Socket("127.0.0.1", 10005);
// 获取输出流,写数据
OutputStream os = socket.getOutputStream();
os.write("Java YYDS!".getBytes());
// 释放资源
socket.close();
}
}
②、接受数据
public class Server {
public static void main(String[] args) throws IOException {
// 创建服务器端的Socket对象(ServerSocket)
ServerSocket ss = new ServerSocket(10005);
// 侦听要连接到此套接字并接受它
Socket socket = ss.accept();
// 获取输入流,读数据,并把数据显示在控制台
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
String data = new String(bys, 0, len);
System.out.println("数据是:" + data);
// 释放资源
ss.close();
}
}
2、UDP协议
(1)、概述:是无连接通信协议,即可以不建立连接,就可以传输数据
(2)、注意事项
①、数据包的大小限制在64kb内,不能超过
(3)、优点:效率高,使用资源少
(4)、缺点:不安全可靠,容易造成数据丢失
(5)、示例
①、发送数据
public class Send {
public static void main(String[] args) throws IOException {
// 1、创建发送端的Socket对象(DatagramSocket)
DatagramSocket ds = new DatagramSocket();
// 2、创建数据,并把数据打包
byte[] bys = "Java YYDS!".getBytes();
DatagramPacket dp = new DatagramPacket(bys, bys.length, InetAddress.getByName("127.0.0.1"), 10086);
// 3、调用DatagraSocket对象的方法发送数据
ds.send(dp);
// 4、关闭发送端
ds.close();
}
}
②、接受数据
public class Receive {
public static void main(String[] args) throws IOException {
// 1、创建接收端的Socket对象(DatagramSocket)
DatagramSocket ds = new DatagramSocket(10086);
// 2、创建一个数据包,用于接收数据
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, bys.length);
// 3、调用DatagramSocket对象的方法接收数据
ds.receive(dp);
// 4、解析数据包,并把数据在控制台显示
System.out.println("数据是:" + new String(dp.getData(), 0, dp.getLength()));
// 5、关闭接收端,释放资源
ds.close();
}
}
二十一、Java8新特性
(一)、Lanbda表达式
1、概述: Lambda 允许把函数作为一个方法的参数
2、原则:可推导可省略
3、格式:(参数列表) -> {代码}
4、特征
(1)、可选类型声明:不需要声明参数类型,编译器可以统一识别参数值
(2)、可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号
(3)、可选的大括号:如果主体包含了一个语句,就不需要使用大括号
(4)、可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数
5、示例
(1)、第一个
①、原始写法
public static void thread(){
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("你知道吗 我比你想象的 更想在你身边");
}
}).start();
}
②、Lanbda式
public static void thread() {
new Thread(() -> {
System.out.println("你知道吗 我比你想象的 更想在你身边");
}).start();
}
(2)、第二个
①、原始写法
public static int calculateNum(IntBinaryOperator operator) {
int a = 10;
int b = 20;
return operator.applyAsInt(a, b);
}
public static void main(String[] args) {
int i = calculateNum(new IntBinaryOperator() {
@Override
public int applyAsInt(int left, int right) {
return left + right;
}
});
System.out.println(i);
}
②、Lanbda式
public static int calculateNum(IntBinaryOperator operator) {
int a = 10;
int b = 20;
return operator.applyAsInt(a, b);
}
public static void main(String[] args) {
int i = calculateNum((int left, int right) -> {
return left + right;
});
System.out.println(i);
}
(3)、第三个
①、原始写法
public static void printNum(IntPredicate predicate) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i : arr) {
if (predicate.test(i)) {
System.out.println(i);
}
}
}
public static void main(String[] args) {
printNum(new IntPredicate() {
@Override
public boolean test(int value) {
return value % 2 == 0;
}
});
}
②、Lanbda式
public static void printNum(IntPredicate predicate) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i : arr) {
if (predicate.test(i)) {
System.out.println(i);
}
}
}
public static void main(String[] args) {
printNum((int value) -> {
return value % 2 == 0;
});
}
(4)、第四个
①、原始写发
public static <R> R typeConvert(Function<String, R> function) {
String str = "1235";
R result = function.apply(str);
return result;
}
public static void main(String[] args) {
Integer convert = typeConvert(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.valueOf(s);
}
});
System.out.println(convert);
}
②、Lanbda
public static <R> R typeConvert(Function<String, R> function) {
String str = "1235";
R result = function.apply(str);
return result;
}
public static void main(String[] args) {
Integer convert = typeConvert((String s) -> {
return Integer.valueOf(s);
});
System.out.println(convert);
}
(5)、第五个
①、原始写发
public static void foreachArr(IntConsumer consumer) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i : arr) {
consumer.accept(i);
}
}
public static void main(String[] args) {
foreachArr(new IntConsumer() {
@Override
public void accept(int value) {
System.out.println(value);
}
});
}
②、Lanbda
public static void foreachArr(IntConsumer consumer) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i : arr) {
consumer.accept(i);
}
}
public static void main(String[] args) {
foreachArr((int value) -> {
System.out.println(value);
});
}
6、省略规则
(1)、参数类型可以省略方法体只有一句代码时大括号
(2)、return和唯一句代码的分号可以省略方法
(3)、只有一个参数时小括号
(二)、Stream流
1、概述:可以被用来对集合或数组进行链状流式的操作,可以更方便的对集合或数组操作
2、案例
@Data
public class Author {
private Long id;
private String name;
private Integer age;
private String intro;
private List<Book> books;
}
@Data
public class Book {
private Long id;
private String name;
private String category;
private Integer score;
private String intro;
}
public class StreamTest {
private static List<Author> getAuthors() {
Author author = new Author(1L, "蒙多", 33, "一个从菜刀中明悟理的祖安人", null);
Author author2 = new Author(2L, "登拉索", 15, "狂风也追逐不上他的思考速度", null);
Author author3 = new Author(3L, "S", 14, "是这个世界在限制他的思维", null);
Author author4 = new Author(3L, "S", 14, "是这个世界在限制他的思维", null);
List<Book> books1 = new ArrayList<>();
List<Book> books2 = new ArrayList<>();
List<Book> books3 = new ArrayList<>();
books1.add(new Book(1L, "刀的两侧是光明与黑略", "哲学,爱情", 88, "用一把刀划分了爱恨"));
books1.add(new Book(2L, "一个人不能死在同一把刀下", "个人成长,爱情", 99, "讲述如何从失败中明悟真理"));
books2.add(new Book(3L, "那风吹不到的地方", "哲学", 85, "带你用思维去领略世界的尽头"));
books2.add(new Book(3L, "那风吹不到的地方", "哲学", 85, "带你用思维去领略世界的尽头"));
books2.add(new Book(4L, "吹或不吹", "爱情,个人传记", 56, "一个哲学家的恋爱观注定很难把他所在的时代理解"));
books3.add(new Book(5L, "你的到就是我的剑", "爱情", 56, "无法想象一个武者能对他的件倡这么的宽容"));
books3.add(new Book(6L, "风与剑", "个人传记", 100, "两个哲学家灵魂和肉体的碰撞会没起怎么样的火花呢?"));
books3.add(new Book(6L, "风与创", "个人传记", 100, "两个哲学家灵魂和肉体的碰撞会激起怎么样的火花呢? "));
author.setBooks(books1);
author2.setBooks(books2);
author3.setBooks(books3);
author4.setBooks(books3);
return new ArrayList<>(Arrays.asList(author, author2, author3, author4));
}
public static void main(String[] args) {
List<Author> authorList = getAuthors();
authorList.stream()
.distinct()
.filter(author -> author.getAge() < 18)
.forEach(author -> System.out.println(author.getName()));
}
}
3、常用操作
(1)、创建流
①、单列集合
List<Author> authors = StreamTest.getAuthors();
Stream<Author> stream = authors.stream();
②、数组
Integer[] arr = {1, 2, 3, 4, 5};
Stream<Integer> stream = Arrays.stream(arr);
③、双列集合
Map<String, Integer> map = new HashMap<>(3);
map.put("蜡笔小新", 19);
Stream<Map.Entry<String, Integer>> stream = map.entrySet().stream();
(2)、中间操作
①、filter:对流中的元素进行过滤
List<Author> authorList = getAuthors();
authorList.stream()
//作家名字的长度大于1打印
.filter(author -> author.getName().length() > 1)
.forEach(author -> System.out.println(author.getName()));
②、map:对流中的元素进行计算或转换
List<Author> authorList = getAuthors();
authorList.stream()
//打印所有作家的姓名
.map(author -> author.getName())
.forEach(s -> System.out.println(s));
③、distint:去除流中重复的元素
List<Author> authorList = getAuthors();
authorList.stream()
//打印所有的作家,不能重复
.distinct()
.forEach(author -> System.out.println(author.getName()));
④、sorted:可以流中的元素进行排序
List<Author> authorList = getAuthors();
authorList.stream()
//对流中的元素按照年龄进行降序排序,并要求不能有重复的元素
.distinct()
.sorted((o1, o2) -> o1.getAge() - o2.getAge())
.forEach(author -> System.out.println(author.getName()));
⑤、limit:可以对流的长度进行长度
List<Author> authorList = getAuthors();
authorList.stream()
//对流中的元素按照年龄进行降序排序,并且要求不能有重复的元素,然后打印其中年龄最大的两个作家的如
.distinct()
.sorted((o1, o2) -> o1.getAge() - o2.getAge())
.limit(2)
.forEach(author -> System.out.println(author.getName()));
⑥、skip:可以跳过流中的前N个元素
List<Author> authorList = getAuthors();
authorList.stream()
//对流中的元素按照年龄进行降序排序,并且要求不能有重复的元素,然后打印其中年龄最大的两个作家的如
.distinct()
.sorted((o1, o2) -> o1.getAge() - o2.getAge())
.limit(1)
.forEach(author -> System.out.println(author.getName()));
⑦、flatMap:把一个对象转换成多个对象作为流中的元素
List<Author> authorList = getAuthors();
authorList.stream()
//打印所有书籍的名字。要求对重复的元素进行去重。
.flatMap((Function<Author, Stream<Book>>) author -> author.getBooks().stream())
.distinct()
.forEach(book -> System.out.println(book.getName()));
(3)、终结操作
①、forEach:对流中元素进行遍历
List<Author> authorList = getAuthors();
authorList.stream()
//输出所有作家的名字
.map(author -> author.getName())
.distinct()
.forEach(s -> System.out.println(s));
②、count:获取流中的元素的个数
List<Author> authorList = getAuthors();
long count = authorList.stream()
//打印这些作家的所出书箱的数目,注意删除重复元素。
.flatMap((Function<Author, Stream<Book>>) author -> author.getBooks().stream())
.distinct()
.count();
System.out.println(count);
③、min-max:获取流中的最大(小)值
List<Author> authorList = getAuthors();
Optional<Integer> max = authorList.stream()
//分别获取这些作家的所出书籍的最高分和最低分并打印。
.flatMap((Function<Author, Stream<Book>>) author -> author.getBooks().stream())
.map(book -> book.getScore())
.max((o1, o2) -> o1 - o2);
System.out.println(max);
Optional<Integer> min = authorList.stream()
//分别获取这些作家的所出书籍的最高分和最低分并打印。
.flatMap((Function<Author, Stream<Book>>) author -> author.getBooks().stream())
.map(book -> book.getScore())
.min((o1, o2) -> o1 - o2);
System.out.println(min);
④、collect:把流中转换成一个集合
List<Author> authorList = getAuthors();
List<String> list = authorList.stream()
//获取一个存放所有作者名字的List集合
.map(author -> author.getName())
.collect(Collectors.toList());
System.out.println(list);
Set<Object> set = authorList.stream()
//获取一个所有书名的Set集合
.flatMap((Function<Author, Stream<Book>>) author -> author.getBooks().stream())
.collect(Collectors.toSet());
System.out.println(set);
Map<String, List<Book>> map = authorList.stream()
//获取一个map集合
.distinct()
.collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));
System.out.println(map);
⑤、anyMatch:可以用来判断是否有任意符合匹配条件的元素
List<Author> authorList = getAuthors();
boolean match = authorList.stream()
//新是否有年龄在29以上的作家
.anyMatch(author -> author.getAge() > 29);
System.out.println(match);
⑥、allMatch:可以用来判断是否都符合匹配条件,
List<Author> authorList = getAuthors();
boolean match = authorLi st.stream()
//判断是否所有的作家都是成年人
.allMatch(author -> author.getAge() >= 18);
System.out.println(match);
⑦、noneMatch:可以判断流中的元素是否都不符合匹配条件
List<Author> authorList = getAuthors();
boolean match = authorList.stream()
//判断作家是否都没有超过100岁的
.noneMatch(author -> author.getAge() > 100);
System.out.println(match);
⑧、findAny:获取流中的任意一个元素,没有办法保证获取的一定是流中的第一个元素
List<Author> authorList = getAuthors();
Optional<Author> any = authorList.stream()
//获取任意一个年龄大于18的作家,如果存在就输出他的名字
.filter(author -> author.getAge() > 18)
.findAny();
any.ifPresent(author -> System.out.println(author.getName()));
⑨、findFirst:获取流中的第一个元素
List<Author> authorList = getAuthors();
Optional<Author> first = authorList.stream()
//获取一个年龄最小的作家,并输出他的姓名
.sorted((o1, o2) -> o1.getAge() - o2.getAge())
.findFirst();
first.ifPresent(author -> System.out.println(author.getName()));
⑩、reduce:对流中的数据按照你制定的计算方式计算出一个结果
List<Author> authorList = getAuthors();
Integer sum = authorList.stream()
//使用reduce求所有作者年龄的和
.map(author -> author.getAge())
.reduce(0, (BinaryOperator<Integer>) (integer, integer2) -> integer + integer2);
System.out.println(sum);
Integer max = authorList.stream()
//使用reduce求所有作者中年龄的最大值
.map(author -> author.getAge())
.reduce(0, (BinaryOperator<Integer>) (integer, integer2) -> integer < integer2 ? integer2 : integer);
System.out.println(max);
Integer min = authorList.stream()
//使用reduce求所有作者中年龄的最小值
.map(author -> author.getAge())
.reduce(0, (BinaryOperator<Integer>) (integer, integer2) -> integer > integer2 ? integer2 : integer);
System.out.println(min);
4、注意事项
(1)、情性求值(如果没有终结操作,没有中间操作是不会得到执行的)
(2)、流是一次性的(一旦一个流对象经过一个终结操作后。这个流就不能再被使用)
(3)、不会影响原数据(我们在流中可以多数据做很多处理。但是正常情况下是不会影响原来集合中的元素的。这往往也是我们期望的)
(三)、Optional
1、概述:避免程序中出现空指针的异常
2、常用方法
(1)、ofNullable():获取optional对象
暂无
(2)、of():获取optional对象
暂无
(3)、empty():判断是否为空
暂无
(4)、ifPresent():判断是否为空
暂无
(5)、get():获取值
暂无
(6)、orElseGet():获取值
暂无
(7)、orElseThrow():获取值
暂无
(8)、filter():过滤
暂无
(9)、map:数据类型转换
暂无
(四)、函数式接口
1、概述:只有以抽象方式的接口,在接口上使用@FunctionalInterface进行标识
2、常用接口
(1)、Consumer:消费接口
(2)、Function:计算转换接口
(3)、Predicate:判断接口
(4)、Supplier 生产接口
3、常用默认方法
(1)、and
(2)、or
(3)、negate
(五)、方法引用
1、概述:进一步简化Lanbda表达式
2、格式:类名::方法名