Java面象对象编程学习(保姆级教学)

1、基本数据类型和引用数据类型的区别( 用内存的角度 ):
基本数据类型 :数据值是存储在自己的空间中
特点:赋的值也是真实的值
引用数据类型 :数据值存储在其他空间中,自己空间存储的是地址值
特点:赋的值是地址值 ★【 注意 :在静态代码块中,随着类的加载进行,而且只进行一次(语法:static{//方法体})
2、 二维数组的学习: 语法:数据类型[][]数组名=new 数据类型[m][n]{{元素 1,元素2},{元素1,元素2}};
注意:m表示可以存放多少个一维数组
n表示每一个一维数组可以存放多少元素
范例:int[][]arr=new int[2][3];
表示可以存放2个一维数组,每一个一维数组可以存放3个int类型的元素
赋值:arr[1][2]=10;将10赋值给第二个数组且索引为2的数据
3、 构造方法的特点:
1、方法名和类名相同,大小也要一致。
2、不能存在返回值,void不存在。
3、可以带参数,没有具体的返回值,不能带有return。
注意事项:·如果没有定义构造方法,系统会默认一个无参数的方法。
·如果定义了构造方法,系统将不再提供默认的构造方法。
4、 什么是方法的重载?
一个类中、方法名相同、但是参数不同。
推荐使用:无论是否使用,都手动书写无参和有参构造。(快捷键: Alt+insert)
5、 对象的内存图
注意:·堆内存里存储的是对象,每当我们通过new关键字建立对象,在堆里面
都会开辟一个新的空间。(几个new几个独立的空间)
·堆内存存储着成员变量和成员方法,可以将独立开辟的空间看做地址值。
·在栈内存里面将堆内存里的地址值赋值给等号左边的变量。
6、 Object是所有java类的祖先,位于java.lang包中
常见方法:
1:toString();返回字符串对象
2:boolean equals();返回是否是同一对象
3:Object clone();返回当前对象的一个副本
4:int hashCode();返回该对象的哈希代码
5:getClass();返回运行时的类
7、继承[访问修饰符]class <子类>extends<父类·>
方法重载和方法重写的区别是什么? 方法重载对返回值类型和访问修饰符无关
8、super关键字的作用--调用父类的属性和构造方法-访问构造方法super(参
数)、super.(属性、方法)
注意:1、必须出现在子类中
2、可以访问父类的成员属性和构造方法
3、无法通过super关键字访问private成员
4、如果存在多级继承关系,构造方法的调用规则会多次向更高一级的父类传
递,一直到执行顶级父类Object。
5、子类的构造方法默认调用父类无参构造方法,这种情况,使用super()也
无效。
6、如果子类super调用父类的带参构造方法,则不在执行无参构造方法。
7、 在类的构造方法中,super语句或this语句只能是第一条语句。
9、 static静态关键字修饰作用--调用方法:类名.属性或方法
注意:1、在静态方法中不能直接访问实例方法,可以创建新的实例对象,使用
对象名.出来。
2、static修饰局部变量只改变生命周期,不改变作用域。
3、静态方法中不能出现this关键字。
4、static会改变成员变量和函数的链接属性,从而使作用域变小。(外部链接 属性被修改成内部链接属性)
10、 多态(具有表现多种形态的能力)<特定类型的变量可以引用不同类型的对象>
一、实现多态的三个条件
1、必须存在继承(没有继承就没有多态)
2、子类重写父类的方法(多态调用的是子类重写或继承的方法)
3、父类引用变量指向子类对象(向上转型)
二、多态的优势----1.可替换性2.可扩充性3.灵活性4.简化性
三、子类到父类的转型(向上转型)--父类到子类的转型(向下转型)
向上转型(语法):<父类型><引用变量>=new<子类>();
向下转型(语法):<子类型><引用变量>=(<子类型>)<父类引用变量>;(可以看成父类被强转为子类型)。
注意:如果需要调用子类特有的方法,需用到向下转型,转换同时可能出现转
换类型异常, 因为在向下转型时没有转换为真实的子类类型 ,就需要用到
instance of
可以译为“属于”或“是一个……的实例”。(向下转型必须转换为父类指向的
真实子类类型)
11、instance of关键字的作用:检查对象的真实类型,再进行相应的强制类型转换,可以避免类型转换异常
语法:<父类引用对象名>instance of<子类型>(一般用于if判断)。
强转语法:((<子类型>)父类引用对象名).<属性或方法>。
12、 抽象类和接口(abstract关键字修饰)【抽象类不能被实例化,只能通过
继承它的子类来创建对象来实现】
抽象类可以默认为子类提供默认实现,实现了方法定义和方法实现分离,使代
码实现松耦合,更易于维护。
语法:<访问修饰符>abstract class<类名>----[访问修饰符] abstract<返回类
型><方法名>([参数列表])
注意:1、 抽象方法与普通方法最大的区别就是 :抽象方法没有方法体。
2、抽象类中可以包括抽象方法和普通方法。
3、 abstract不能和private、static、final共用。
static:抽象方法只是声明,方法没有实现,而static通过类名去点直接访问。
private:抽象方法需要在子类中重写,private不能被子类继承,只能用在本类
中。
final:final修饰的方法不能被子类重写
13、 final关键字: 不能再被继承,方法不能再重写,常量中,只能在初始化进
行赋值,在修饰引用变量时,变量值不变,变量所指对象的属性值可变。
14、 接口的使用(继承只是单继承,但可以调用多个接口) 接口也可以看成一个抽象类。
抽象类利于代码的复用,接口利于代码的扩展。
定义接口的语法:[访问修饰符] interface 接口名{}
类实现接口的语法:class 类名 implements 接口名{}
复杂接口的继承:[访问修饰符] interface 接口名 extends 父接口1、父接口
2……{}
类继承接口的语法:class 类名 extends 父类名 implements 接口1、接口
2……{}
注意:1、在接口中属性系统会自动添加 public static final 修饰(在接口中变量
是常量)
2、方法系统会自动添加 public abstract 修饰(方法是抽象方法) 3、接口的实现类必须实现接口中定义的所有的抽象方法
15、 面向对象的设计原则
1、摘取代码变化部分,形成接口。
2、多用组合,少用继承(多组少继)。
3、不依赖具体实现( 以抽象类或接口作为依赖的类型 )。
4、遵循“开闭原则”(不修改原有的接口,定义一个新的接口)。
16、 异常try-catch-finally的使用(快捷键:Ctrl+Alt+T)
input.hasNextInt()的作用是避免 输入不匹配的数据类型而引发异常。
1 Exception 类型的常用方法 void printStackTrace() 输出异常堆栈信息。
一般调用ex.printStackTrace() ,输出异常信息是最完整的。
String getMessage() 返回异常的详细信息。是 printStackTrace() 方法的一部分。
2 、怎么将 finally 语句块不被执行?在异常处理代码中使用 System.exit(1) 方法退
JVM 。【括号里的 1 代表状态码,以非零状态退出, 0 代表成功退出,非零数
字代表异常退出】
3 、多重 catch 语句的使用 语法: catch( 异常类型 异常对象 ex)
注意: · 系统会自动从上到下的顺序依次检测每个 catch 语句,当匹配到第一个
catch ,后面不再执行。(相当于 if-else多重运用)。
当异常类型为 Exception catch 语句必须放在最后的位置,它包含所有异常类
型。
17 、异常分类 Error 类和 Exception 类 【 Error 类一般指 JVM 的相关问题】
Exception 类:可以分为( RunTimeException )运行异常和( Checked )检查异
常、编译错误
RunTimeException )运行异常:
1. NullPointerException (空指针异常): 当试图在对象引用上调用方法或访问
属性时,但该引用为空( null )时抛出。
2. ArrayIndexOutOfBoundsException (数组越界异常): 当尝试访问数组中不
存在的索引位置时抛出,通常是索引值小于 0 或者大于等于数组长度。
3. ClassCastException (类转换异常): 当试图将对象强制类型转换为不兼容的
类型时抛出,例如将一个不能转换为指定类型的对象强制转换为该类型。 4. NumberFormatException (数字格式异常): 当字符串转换为数字的过程中
发生格式错误时抛出,通常是因为字符串中包含无法解析为数字的字符。
5. IllegalArgumentException (非法参数异常): 当方法接收到的参数不合法或
不合适时抛出,如参数值不在允许的范围内、类型不匹配等。
6. IllegalStateException (非法状态异常): 当对象的状态无法支持正在执行的
操作时抛出,例如尝试在对象处于不正确状态时调用方法。
7. ArithmeticException (算术异常): 当出现除以零或者其他算术错误时抛
出,例如整数除法时除数为零。
8. ConcurrentModificationException (并发修改异常): 在使用迭代器遍历集
合时,如果在迭代过程中修改了集合的结构(添加、删除元素等),则会抛出
此异常。
9. IndexOutOfBoundsException (索引越界异常): 当使用某种方法访问字符
串、数组或集合等数据结构时,访问了无效的索引时抛出。
10. NullPointerException (空指针异常): 当试图在 对象 引用上调用方法或访问
属性时,但该引用为空( null )时抛出。
11. UnsupportedOperationException (不支持的操作异常): 当调用不支持的
操作时抛出,通常是由于对象的不可变性或者特定实现不支持的操作引起的。
(Checked)检查异常:
1.IOException (输入 / 输出异常): 表示在输入输出操作期间发生的异常,例
如文件无法找到、读取或写入文件时的错误等。
2.SQLException SQL 异常): 表示与数据库操作相关的异常,例如连接数据
库失败、执行 SQL 查询出错等。
3.ClassNotFoundException (类未找到异常): 表示在运行时试图加载类时找
不到对应的类的异常。
4.NoSuchMethodException (方法未找到异常): 表示试图通过反射调用不
存在的方法时抛出的异常。
5.ParseException (解析异常): 表示在解析字符串、日期等数据时出现错误
的异常。
6.InstantiationException (实例化异常): 表示试图通过反射创建一个抽象类
或者接口的实例时抛出的异常。
7.IllegalAccessException (非法访问异常): 表示试图访问一个不可访问的
类、字段或方法时抛出的异常。
8.InvocationTargetException (调用目标异常): 表示通过反射调用方法时目
标方法抛出异常时的异常,通常是作为其他异常的包装器。
9.FileNotFoundException (文件未找到异常): 表示在尝试打开一个不存在
的文件时抛出的异常。
10.MalformedURLException URL 格式异常): 表示 URL 字符串格式错误
时抛出的异常。
11.ParseException (解析异常): 表示在解析字符串、日期等数据时出现错误
的异常。 12.ClassNotFoundException (类未找到异常): 表示在运行时试图加载类时
找不到对应的类的异常。
18、 throws 关键字的使用
throws用于可能抛出异常方法的声明
语法:public void 方法名()throws 异常类型1,异常类型2.......{//方法体}(第
二种:throws+继承异常的父类)
19、抛出异常—— throw关键字
语法:throw new 异常名-【异常类】(参数列表)
注意:异常名不能为String,因为String类不是Throwable类的子类。
20、自定义异常
(1):定义异常类,继承Exception类或RuntimeException
(2):编写异常类的构造方法,并继承父类的实现。
(3):实例化自定义异常对象,并使用throw关键字抛出 (throw new 异常
名)
常见四种构造方法:
1、public Exception(){
      super()}
2、public Exception(String message){
      super(message)}
3、public Exception(String message,Throwable cause){
      super(message,cause)} 
4、public Exception(Throwable cause){
      super(cause)}
21 、日志框架Log4j 2(Java中记录日志之一) (下载log4j-2.13.3.jar和下载log4j
core-2.13.3.jar)【直接导包+右键Add as Library】
Log4j 2配置——下载完成之后,打开idea中的file-Project Structure
Modules,右侧窗格中选择"Dependencies",点击右侧“+”按钮,选择“JARs
or directories”命令,添加两个.jar文件
或者:在项目中创建一个lib目录,导入.jar文件,右键Add as library就OK了。
22、Log4j记录日志的使用
(1):编写配置文件 (log4j2.xml) XML即可扩展标记语言
(2):定义日志记录器Logger——创建一个Logger对象,Logger 对象名
=LogManager.getLogger(类名.class.getName());
注意:getLogger(String类型的参数), 参数是通过类名.class.getName()
(3):记录日志(Logger类常用记录日志的方法)【日志记录级别共八级,从
低到高依次如下all(所有)<trace(追踪)<debug(调试)<info(消息)
<warn(警告)<error(错误)<fatal(严重错误)<OFF(关闭)】
例如:记录debug/info/warn/error/fatal级别日志:public void
debug(Object msg) public void debug(Object msg,Throwable t)
常用API--包装类 (将基本数据类型转换为Object类型)【可以通过创建包装类
来完成手动装箱-"value of()"】
自动拆箱:将Object类型->基本数据类型 //创建包装类对象
自动装箱:将基本数据类型->Object类型//调用包装类里的type.typeValue()
方法【type指基本数据类型】 ★重点:Java以后键盘录入都使用String类型的nextLine()方法,再结合包装类
的方法转换为基本数据类型。
①value of()将其他数据类型转换为包装类型
②将字符串转换为基本数据类型,通过包装类+点+parse大写基本数据类型
【例:int result= Integer.parseInt(String s)
③包装类Character没有提供parse(),可以通过 str.charAt(index) 方法获
取,或者将字符转换为包装类来获取相应的值 Character.valueof().charValue()。
【▲注意:②、③只使用于参数为String类型的数据】
匿名内部类: (临时性、一次性)★【定义之后不能在其他地方调用, 只在一个具体的代码块或方法内部被实例化和使用
23、 Collection类(集合祖宗): (框架) ▲注意:Collections是一个 工具
,包含了 sort()--排序(默认升序)->reverse() 反转元素顺序 ->shuffle()--
打乱顺序,在Set集合中可以转换为List列表来运用。
【注意:Collection是个接口,不能实例化对象】
Collection接口常用的方法:
List接口 (继承Collection接口,Set集合的方法上基本上与Collection的API一
致,但有扩展方法)
【List接口不允许重复、有索引、有序】包括->(ArraysList->底层: 数组
(LinkedList->底层: 链表(双向)
链表(双向): 数值左右都存储了一个null的地址值,便于增、删数据。
ArraysList集合 (泛型类:可以约束集合里存储的数据类型)
通过创建集合对象去调用集合的方法来实现
使用局限:底层是数组,增、删、会频繁前后移动位置,导致效率低。
LinkedList集合 (双链结构:可以频繁增、删)【 每个元素都被封装为一个节点(Node ),形成链表结构
Set接口 (继承Collection接口,Set集合的方法上基本上与Collection的AP一
致)
【不允许重复、无序、无索引】包括
  • HashSet(允许插入一个null,无序)、
  • TreeSet(不允许插入null元素,有序)、
  • LinkedHashSet(有序:保证存和取的顺序一致【Linked双向链】)
HashSet(使用场景:集合需要去重)底层原理:(哈希表:在jdk8之前:数
组+链表-----之后:数组+链表+红黑树)
①创建一个默认长度16,默认 加载因子 0.75的数组,数组名table【加载因子就
是HashSet集合的扩容,例如:16*0.75=12,当集合存储数量达到12时,集合容量翻倍成32】
②根据元素的哈希值跟数组的长度计算出应存入的位置
③判断当前位置是否为nul,如果是nul直接存入
④如果位置不为nul,表示有元素,则调用equals方法比较属性值
⑤一样:不存 不一样:存入数组,形成链表
JDK8以前:新元素存入数组,老元素挂在新元素下面
JDK8以后:新元素直接挂在老元素下面
【链表:处理哈希碰撞 红黑树: 提高查找、插入和删除操作的效率
JDK8以后,当链表长度超过8,而且数组长度大于等于64时,自动转换为红黑树
哈希值:(通过哈希值计算索引的公式: int index=(集合长度-1)&哈希值【&
在这里是按位运算符,返回一个 二进制 的数值】
定义: 对象的整数表现形式
1.如果没有重写hashCode方法,不同对象计算出的哈希值是不同的
2,如果已经重写nashcode方法,不同的对象只要属性值相同,计算出的哈希值
就是一样的
3。但是在小部分情况下,不同的属性值或者不同的地址值计算出来的哈希值也
有可能一样。(哈希碰撞)
注意:HashSet利用HashCode()和equals()机制保证去重的
如果集合中存储的是自定义对象,必须要重写hashCode和equals方法(快捷
健:alt+insert选择equals()andHashcode())
TreeSet(使用场景:集合需要排序)底层原理:(红黑树)
Lambda(可用于函数式接口)表达式语法: (参数1,参数2...) ->{//方法体} -> 组成,表示将参数与表达式或代码块进行关联。
★Lambda表达式只能 简化函数式接口的匿名内部类 的写法
1.TreeSet:集合的特点是怎么样的?
●可排序、不重复、无索引,底层基于红黑树实现排序,增删改查性能较好
2.TreeSet集合 自定义 排序规则有几种方式【数值型:默认从小到大;字符型:
字典a->z】
●方式一:Javabean类实现Comparable 接口 ,重写Comparable里的抽象方法
【快捷健:选中接口+Alt+回车】指定比较规则(例如:参数为-自定义对象) ●方式二:创建集合时,自定义Comparator 比较器 对象,(Comparator属于
函数类接口, 可以使用 Lambda 表达式,它是一种便捷的方式来创建 函数式接
的实例 )指定比较规则(使用场景:根据长度去排序)
Comparator 排序通常根据返回的整数值来确定对象的顺序
①函数类接口实现:
//1.创建集合
//o1:表示当前要添加的元素
/o2:表示己经在红黑树存在的元素
//返回值差值为负左正右
TreeSet<String>ts new TreeSet<>(new Comparator<String>(){
@Override
public int compare(String o1,String o2){
//按照长度排序
int i=o1.length()-o2.length();
//如果一样长则按照首字母排序
i=i==0?o1.compareTo(o2):i;
return i;
   }
});

②Lambda表达式实现:
TreeSet<string>ts new Treeset<>((o1,o2)->{
//按照长度排序
int i=o1.length()-o2.length();
//如果一样长则按照首字母排序
i=i==0?o1.compareTo(o2):i;
return i;
});
Lambda使用注意: 1:Lambda会自动推断数据类型->可省略。2:可从函数式接口删除到方法名。
★3.方法返回值的特点【 Comparable 还是 Comparator 接口进行排序,都涉及
到通过 返回正负数值 来确定对象的顺序
●负数:表示当前要添加的元素是小的,存左边
●正数:表示当前要添加的元素是大的,存右边
●0:表示当前要添加的元素已经存在,舍弃
Collection集合的遍历:
迭代器遍历 (Iterator):是否存在下一个遍历元素--boolean hasNext(); 遍
历下一元素--Object next();删除上一次next()返回的元素--void remove();
1.迭代器在遍历集合的时候是不依赖索引的
2.迭代器需要掌握三个方法:
  • Iterator<String>it =list.iterator();//创建迭代器对象
  • while(it.hasNext()){//使用hasNext()方法判断是否存在下一个元素
  • String str it.next();//next()方法遍历下一个元素
  • System.out.println(str);}//打印输出
3.迭代器的四个细节:
▪如果当前位置没有元素,还要强行获取,会报NoSuchElementException
▪迭代器遍历完毕,指针不会复位
▪循环中只能用一次next()方法
▪重点:迭代器遍历时,不能用集合的方法进行增加或者删除【可以调用迭代器 中自带的增、删方法】
增强for遍历 (底层:迭代器)【使用场景: 所有单列集合(List、Set)和数
语法:for(数据类型 变量名: 数组或集合){//方法体}
Lambda表达式 forEach() 方法遍历-->后接必须是函数式接口)【机制:通过匿名内部类改成Lambda表达式】
//forEach方法的底层其实就是·个循环遍历,依次得到集合中的每一个元素
/并把每一个元素传递给下面的accept方法
/accept方法的形参s,依次表示集合中的每一个元素
list.forEach(new Consumer<String>(){
@Override
public void accept(String s){
System.out.println(s);
}
});
列表迭代器遍历 (ListIterator):ListIterator<String>it =list.listIterator();//创建列表迭代器对象
普通for循环 (List集合中存在索引)
总结(五种遍历方式的使用场景): 迭代器遍历:在遍历的过程中需要 删除元素 ,使用普通迭代器。
列表迭代器:在遍历的过程中需要 添加元素 ,请使用列表迭代器。
增强for遍历或者Lambda:表达式:仅仅想遍历,那么使用增强for或Lambda表达式。
普通for:如果遍历的时候想操作索引,可以用普通for。
24、Map集合 (存储若干个键-值对象<key-value>)【双列集合】 ★注意:Linked系列的集合都可以保证元素存、取的顺序。
【◆注意:Hashtable 不允许空键或空值, Properties 对象来存储和管理 属性
置数据】
Properties:( 双列集合,拥有 Map 集合的所有方法 )
①Properties类提供了load()和store()方法,用于从输入流加载属性并将属性写
入输出流(store方法可以向文件中添加注释信息)
②Properties类提供了setProperty()和getProperty()方法,用于设置和获取属性值。
③可以使用stringPropertyNames()方法获取所有属性的键,并通过键获取相应的值(使用场景:增强for)。
双列集合(Map)的特点:
①双列集合一次需要存一对数据,分别为键和值
②键不能重复,值可以重复
③键和值是一一对应的,每一个键只能找到自己对应的值
④键+值这个整体我们称之为“键值对”或者“键值对对象”,在Java中叫做“Entry对象”。
▲注意:Map集合在添加数据的时候:
①键不存在,直接添加在集合里--
②键存在,会将原有的键值对(对象)覆盖,并返回被覆盖的值(value)。
Map中定义的另一种接口Map.Entry,获取元素形式如“key-value”。
Map.Entry接口的常用方法:
获取Key值:Object getKey()--获取value值:Object getValue()--返回键值对
的哈希值:int hashCode()--修改value值:Object setValue(Object value);
Map集合的三种遍历方式: ▲注意: Map 接口用于存储键值对 映射 ,不属于Collection的子类。
迭代器遍历: 通过keySet()和entrySet()方法返回一个Set集合【因为迭代器
依赖于Collection集合】,再创建迭代器对象(Interator)。
增强for遍历: (底层:迭代器)【使用场景: 所有单列集合(List、Set)和
数组, 但是可以通过keySet()和entrySet()转换为Set集合
语法:for(数据类型 变量名: 数组或集合){//方法体}
Lambda表达式: forEach() 方法遍历-->后接必须是函数式接口)【机制:
通过匿名内部类改成Lambda表达式】
HashMap集合类 :(底层:哈希表结构)
注意:如果 存储的是自定义对象,需要重写hashCode和equals方法----如果 存储自定义对象,不需要重写hashCode和equals方法
LinkedHashMap集合类:
由键决定: 有序、不重复、无索引。
●这里的有序指的是保证存储和取出的元素顺序一致
●原理:底层数据结构是依然哈希表,只是每个键值对元素又额外的多了一个双
链表的机制记录存储的顺序。
1.TreeMap集合的特点是怎么样的?
●不重复、无索引、可排序
●底层基于红黑树实现排序,增删改查性能较好
2.TreeMap集合排序的两种方式
●实现Comparable接口,指定比较规则
●创建集合时传递Comparator比较器对象,指定比较规则 25、 可变参数: (本质:数组;作用:在形参中接收多个数据)【格式:数据类型..参数名称->举例:int..a】
【注意事项:①形参列表中可变参数只能有一个②可变参数必须放在形参列表的最后面】
26、不可变集合的特点->定义完成后不可以修改,或者添加、删除(创建方式:
List、Set、Map接口中,都存在 of() 方法)
▲注意:Map:元素不能重复、键值对数量最多是10个,超过10个用 ofEntries() 方法。
27、枚举的使用( 表示一组固定的、相关的常量 )【常量集合--调用方式:枚举名.常量名】
语法:访问修饰符 enum 枚举名{常量1,常量2...}(在单独的一个类中定义)
枚举的遍历: 调用枚举中的 values() 方法。▲注意:int compareTo()方法比较
机制:在枚举中定义的位置-> 索引之差
枚举的作用:
提高代码可读性和可维护性 限制取值范围 增加类型安全性 支持迭代和循环
28、 日期类 (易用性差、不是线性安全的)【常见的日期类:LocalData、LocalTime、LocalDataTime-->日期类的实例是不可变的对象,无法直接修改属性值,通常重新实例化】
1、日期类通用方法:
①返回当前时间:日期类 now()【也可通过创建Date对象, 创建SimpleDateFormat对象[日期类格式器]并指定格式,调用formatter()】
②指定日期/时间:日期类 of()-->获取所有盘符:listRoots();
③返回月份:Month getMonth()【★注意:Month属于枚举类型】
④返回月份天数:int getDayOfMonth()
⑤返回年数:int getYear()
⑥在指定的日期上添加年/月/日/周:日期类
plusYears/Months/Days/Weeks();
⑦在指定的日期上减少年/月/日/周:日期类
minusYears/Months/Days/Weeks();
⑧将字符串转换为日期类型:日期类.parse();【例如: LocalDate
date=LocalDate. parse (str.next() 2、创建格式化器:【注意:MM->月份--mm->分钟--ofPattern:指定日期格式】
DateTimeFormatter fm2 DateTimeFormatter.ofPattern("yyyy-MM-dd,HH:mm:ss");
3、直接通过format()方法将日期格式化为字符串(两种形式)
形式一:日期类对象.format(格式化对象)
形式二:格式化对象.format(日期类对象)
4、如何将long类型的最后修改时间lastModified()指定格式化?
//将文件最后修改时间转换为LocalDateTime对象
Long lastModifiedTime file.lastModified();
//ofEpochMilli()方法通常用于将时间戳(毫秒数)转换为Instant实例
Instant instantInstant.ofEpochMilli(lastModifiedTime);
/从Instant和区域ID获取LocalDateTime的实例
LocalDateTime fileLastModifiedTime LocalDateTime.ofInstant(instant,ZoneId.systemDefault());
/格式化文件最后修改时间
String formattedFileLastModifiedTime fileLastModifiedTime.format(formatter);
System.oUt.println("文件最后修改时间为:"+formattedFileLastModifiedTime);
29、 Random类 (生成随机数)【注意:rd.nextInt()->左闭右开区间】
构造方法:①Random():创建一个随机数生成器 ②Random(long seed):单个
long种子创建随机数生成器【注意: 生成可重现的随机数序列
ASCII 编码( 字符编码系统):例如: "A":->65----"a"->97
30 File (操作文件和目录)【 parent: 父级路径 child: 子级路径 -- 注意:路径分隔符"/" "\\" ,其中 "\\" 第一个 "\" 表示转义符。】
File 类常见构造方法: ①File(File parent,String child)
File(String pathname)
③File(String parent,String child)
★【注意:delete()方法删除文件和空文件夹,不走回收站。(mkdirs()方法可创建多级文件夹、单级也行) createNewFile()方法创建文件时,必须处理异
File类获取属性值:
①获取文件名:getName()
②获取文件路径:getPath()
③获取绝对路径:getAbsolutePath()
④检查文件是否存在:exists()
⑤获取文件大小:length()
⑥获取最后修改时间:lastModified()
⑦获取当前该路径下所有内容(返回值类型:数组)- > File[] listFiles();
★注意: File 类中使用 递归思想(自己调用自己) 能够有效地处理文件系统中
的复杂结构, 方便对文件和文件夹进行各种操作(先遍历)
① 删除多级文件 :
private static void delete
(File aaa)
File[]files aaa.listFiles();
for (File file files){
if(file.isFile()){
file.delete();
}else{
delete (file);
}
aaa.delete();
}//递归思想
②返回多级文件的总长度:
public static long getLen(File aaa){
long len =0;
File[]files aaa.listFiles();
for (Filefile files){
if(file.isFile()){
len len file.length();
}elsef
lenlen getLen(file);
return len;
【注意:单位换算-> 1 KB= 1024 字节( Bytes 1MB= 1024 KB 1 GB= 1024 MB
31 I/O 流概述 (流,是指一连串流动的字符,是以先进先出的方式发送和接收
数据的通道)【 注意:字节流和字符流都为抽象类, 必须使用子类实例化对
-- 《重点:随用随创建,在编写代码中,必须要处理可能会发生的异常,处理完
流之后,需要关闭流【 按照逆序关闭流 】》 【输入流:读取数据--输出流:写出数据】
1、 字节流 (字节输入流/输出流--InputStream/OutputStream) byte []
bytes= new byte [ 1024 ]
InputStream 抽象类的主要方法:( 将字符串转换为byte[]数组: str.getBytes()--
将byte[]数组转换为字符串: new String(byte[]b,int off,int len)--
将int转换为char:(char)int)
  1. ①读取一个字节数据:int read()
  2. ②将数据读取到字节数组中:int read(byte[]b)
  3. ③确定范围返回byte数组中:int read(byte[]b,int off,int len)【▲注意:off->
  4. 开始位置--len->读取的长度】
  5. ④关闭输入流:void close()
  6. ⑤返回输入流读取的字节数:int avilable()
OutputStream 抽象类的主要方法:
字节类 -- (文件输入流/输出流--FileInputStream/FileOutputStream):
FileInputStream类常见的构造方法:
① FileInputStream(File,file) ② FileInputStream(String name)
【注意: name表示路径名称】
循环read()读取数据:【 重点: 一定要定义第三方变量(data),read():表示 读取数据,而且是读取一个数据就移动一次指针
//执行读取操作 int data=0;
while ( (data=input.read())!=-1 ){//-1表示输入流已经读到末尾,while中括
号里的循环条件就可以理解为已经读取过了。
System.out.print((char)data);}
FileOutputStream类常见的构造方法:
  • ①FileOutputStream(File file)
  • ②FileOutputStream(String name)
  • ③FileOutputStream(String name,boolean append)
  • 【▲注意:append(续写开关)表示是否在文件末尾追加数据--换行需要输出的话:write("\r\n")】
◆如何拷贝文件?定义一个参数为(资源文件夹、拷贝文件夹)->关键代码:
new File(dest,file.getName())
◆如何简单对文件加密:【结合 异或^ ,判断两边是否相等】
①结合FileOutputStream/FileOutputStream创建对象关联原始文件和加密文
②加密处理:在循环遍历时进行 异或 处理;1:int b;2:while((b
fis.read())!=-1){3:fos.write(b^2);
-- (字节缓冲输入流/输出流--BufferedInputStream/BufferedOutputStream)
减少系统调用次数, 可以提高读取数据的效率
BufferedInputStream常见的构造方法:【注意:基于输入流对象,size:指定
缓冲流的大小】
①BufferedInputstream(Inputstream in)《建议:创建字节数组,采用
read(bytes)方法进行读取》
②BufferedInputstream(Inputstream in,int size)
BufferedOutputStream常见的构造方法:
①BufferedOutputStream(Inputstream in)
②BufferedOutputStream(Inputstream in,int size)
--( 数据操作输入流/输出流DataInputStream/DataOutputStream )【 以二进
制格式处理基本数据类型
Ⅰ构造方法:DataInputStream(InputStream in); 【注意:可以直接读取或输
出UTF-8字符编码的字符串】
提供额外的读取方法:readInt/Double/Float/Char/Boolean/ UTF()
Ⅱ构造方法:DataOutputStream(OutputStream out);
提供额外的输出方法:writeInt/Double/Float/Char/Long/ UTF()
-( 序列化流/对象输入流->ObjectInputStream--反序列化流/对象输出流-
>ObjectOUtputStream )【使用合格证:Serializable接口】
《▲注意:使用序列化流之前必须调用 Serializable接口 ,接口中没有定义方
法,是个标识接口。
如果在序列化的过程中遇到版本兼容性问题时,需要设置 序列号、版本号, 默认的定义方式:
private static final long serialVersionUID=1L》
①序列化流/对象输入流->ObjectInputStream:-构造方法:
ObjectInputStream(InputStream in)
读取对象的方法:final void readObject(Object obj)
②反序列化流/对象输出流->ObjectOUtputStream:-构造方法:
ObjectOutputStream(OutputStream out)
输出对象的方法:final void writeObject(Object obj)
①使用序列化流将对象写到文件时,需要让Javabean类实现 Serializable 接口。
否则,会出现NotSerializableException.异常
②序列化流写到文件中的数据是不能修改的,一旦修改就无法再次读回来了 ③序列化对象后,修改了Javabean类,再次反序列化,会不会有问题?
会出问题,会抛出InvalidClassException异常,解决方案:给javabean类添加
serialVersionUID 序列号、版本号 )
④如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
解决方案:给该成员变量加 transient 关键字修饰,该关键字标记的成员变量不
参与序列化过程
--( 解压缩流/压缩流--ZipInputStream/ZipOutInputStream )【通过创建 ZipEntry 对象:表示需要添加到Zip中的文件或目录,ZipEntry对象的参数是
Zip 内部 中文件的 相对路径 或者是 根目录
常见的构造方法:①ZipInputstream(Inputstream in)
②ZipInputstream(Inputstream in,Charset charset)
常见的两种成员方法:①获取压缩包中的文件和文件夹:
zip.getNextEntry() ②将压缩包对象(ZipEntry)放到压缩包中:
zip.putNextEntry() ③获取父级路径:getParentFile();
常见的五大步骤:①选择解压缩流/压缩流类型 ②创建输入流/输出流 ③通过创
建ZipEntry对象来获取解压缩/压缩条目④读取/输出数据⑤释放资源(关流-
>close())->压缩包文件处理完毕:closeEntry()。
解压缩文件夹思路( 定义一个参数为资源文件 src 和目的文件 dest 的方法 ):
创建ZipInputStream解压缩流(参数为:FileInputStream)。
②创建ZipEntry(压缩文件)对象,通过解压缩流的getNextEntry()方法转换
成ZipEntry对象,可结合循环遍历。
③考虑两个点,第一压缩文件为文件夹,file.mkdirs()创建文件夹,否则结合
文件输出流循环遍历写进write();
④关闭压缩文件closeEntry()及其它流。《▲注意:ZipInputStream会 自动
历所有条目,不需要使用 递归 思想》

压缩文件夹思路(难点:定义一个参数为资源文件夹src和 压缩流-
> ZipOutInputStream 和name:压缩文件内部路径):
①测试类中创建
ZipOutputStream 压缩流 参数为: FileOutputStream)。
②通过循环遍历资源文件的所有文件,将其转换成压缩文件( ZipEntry )对象
【注意:创建 ZipEntry 对象时,参数应为name+File.separator("\\")+资源
文件名称】,使用 putNextEntry() 方法将压缩对象添加到压缩流中。
③创建字节输入流,结合循环read()和write()方法读取并写进。
④关闭压缩文件 closeEntry() 和其他流。【▲注意: 压缩流 放在循环外关闭】
⑤结合递归思想遍历其他文件。

Java中编码的方法:↓ ->String类中的方法(说明:charsetName字符编码类型)
使用默认方式进行编码->public byte[]getBytes()
使用指定方式进行编码->public byte[]getBytes(String charsetName)
Java中解码的方法:↓
String(byte[]bytes)->使用默认方式进行解码
String(byte[]bytes,String charsetName)->使用指定方式进行解码
注意: 如何不产生乱码?
1,不要用字节流读取文本文件
2,编码解码时使用同一个码表,同一个编码方式 字符类 (常见的三种字符:ASCII,GBK,Unicode)
1.在计算机中,任意数据都是以 二进制 的形式来存储的
2.计算机中最小的存储单元是一个字节
3.ASCII字符集中,一个英文占一个字节
4.简体中文版Windows,默认使用GBK字符集
5.GBK字符集完全兼容ASCII字符集:
一个英文占一个字节,二进制第一位是0
一个中文占两个字节,二进制高位字节的第一位是1
Unicode字符集的UTF-8编码格式:
一个英文占一个字节,二进制第一位是0,转成十进制是正数
一个中文占三个字节,二进制第一位是1,第一个字节转成十进制是负数
字符 --(字符输入流/输出流--Reader/Writer)
Reader 抽象类的主要方法:
  • ①读取一个字节数据:int read()
  • ②将数据读取到字节数组中:int read(byte[]b)
  • ③确定范围返回byte数组中:int read(byte[]b,int off,int len)【▲注意:off->
  • 开始位置--len->读取的长度】
  • ④关闭输入流:void close()
重点:空参read()和有参read()的区别:有参方法里包含了读取、解码、强转,有参相当于 空参read()+类型强转
Writer抽象类的主要方法:
字符 --(文件字符输入流/输出流--FileReader/FileWriter)
FileWriter类常见的构造方法:
  • ①FileWriter(File file)
  • ②FileWriter(File file,boolean append)
  • ③FileWriter(String fileName)
  • ④FileWriter(String fileName,boolean append)
FileReader类常见的构造方法:
①FileReader(File file)
②FileReader(String fileName)
--●( 字符缓冲输入流/输出流--BufferedReader/BufferedWriter )【 缓冲流通过
在内存中设置缓冲区来提高 I/O 操作的效率
常用构造方法:【类对象形式的参数可以直接new类】->{使用场景:数据量
大、性能高、处理复杂数据、网络传输}
①BufferedReader(Reader in) ②BufferedReader (Reader in,int size)
①BufferedWriter(Writer out) ②BufferedWriter (Writer out,int size)
字符缓冲流提供两个特殊方法: ①按整行读取数据: br.readLine() ②换行
方法: bw.newLine();
--( 字符转换输入流/输出流--InputStreamReader/OutputStreamWriter
字节流与字符流的桥梁 ->> 可结合电脑基本单位是字节( byte )来理解
常用构造方法:【类对象形式的参数可以直接new类】 ①InputStreamReader(Inputstream in) ②InputStreamReader(Inputstream
in,string charsetName)
①OutputstreamWriter(Outputstream
out) ②OutputstreamWriter(Outputstream out,string charsetName)
⑴InputStreamReader: 是一个从字节流到字符流的桥梁。
⑵OutputStreamWriter: 是一个从字符流到字节流的桥梁。
例如:(将字节流文件转换为字符流):BufferedReader br =new
BufferedReader(new InputStreamReader(new FileInputStream( String name )));
字节打印流/字符打印流--PrintStream/PrintWriter (只写不读)【▲注意:字
节打印流会默认自动刷新,因为字节流底层没有缓冲区,开不开自动刷新都一样】
常用的构造方法: idea查看构造方法的快捷键( Ctrl+P
常用的成员方法:
32、 常用工具包--Commons-io(处理IO流)
使用步骤:
  1. ①在项目中创建一个文件夹:lib
  2. ②将jar包复制粘贴到lib文件夹
  3. ③ 右键点击jar包,选择Add as Library->OK
  4. ④在类中导包使用
Commons-io常见的两大类的常见方法:【FileUtils类和IOUtils类】
33、 Hutool工具包(提供了和很多类的简便方法)
API文档: https://apidoc.gitee.com/dromara/hutool/
中文使用文档: https://hutool.cn/docs/#/
FileUtil类常见的方法:
①file:根据参数创建一个file对象--②copy:拷贝文件或者文件夹
③touch:根据参数创建文件(父级路径不存在也可自动创建)
④writeLines:把集合中的数据写出到文件中,覆盖模式。
⑤appendLines:把集合中的数据写出到文件中,续写模式
⑥readLines:指定字符编码,把文件中的数据,读到集合中。
⑦readUtf8 Lines:按照UTF-8的形式,把文件中的数据,读到集合中
34、 多线程的运用 (最大程度利用CPU的高效程序,提高程序的效率和性能)
Thread类:【线程对象】-> 开启多线程都必须new Thread类,调用start()方法。
线程的状态转换: 即->新建、就绪、运行、阻塞、死亡
线程调度的成员方法: 【中断线程:Thread.currentThread().interrupt()】
【▲注意:
①setDaemon守护线程(备胎线程):启动前调用,非守护线程运行完毕,它也会随之运行完毕【负责后台线程】
②sleep休眠:给较低优先级线程运行机会
③礼让yield:给相同优先级或更高优先级运行机会】
Thread类提供了三个静态常量设置优先级:(1~10)
①MAX_PRIOITY->10 ②NORM_PRIOITY->5 ③MIN_PRIOITY->1
多线程实现的三种方式:
  • ①继承Thread类的方式进行实现,书写run()方法。
  • ②实现Runnable接口的方式进行实现,重写run()方法,创建接口类对象放入Thread类。
  • ③利用Callable接口和Future(异步计算)接口方式实现【获取多线程结果
  • 操作:指定相应的线程结果类型(泛型),重写call()方法,创建类对象(表示
  • 多线程要执行的任务),创建FutureTask对象(管理多线程运行结果)并get()返回线程结果。
synchronized关键字在多线程的作用 (创建同步代码块或同步方法)
同步代码块:synchronized(obj){//代码块} synchronized(this){} 【this和
obj都属于锁的对象】
【▲注意:当一个线程进入一个synchronized代码块或方法时,它会尝试获取该代码块或方法所属对象的锁。
获得锁的线程就可以共享数据,完成代码块的所有代码才会放锁,使其他线程,同步代码块不能嵌套使用,容易造成死锁。】
synchronized锁都是自动开锁、关锁,怎么可以自动获得、释放锁呢?
--可以创建一个Lock(锁)对象。【◆注意:Lock接口不能实例化,可以通过
实现类ReentrantLock的空参构造来实例化】
①获得锁:void lock();
②释放锁:void unlock()->为了确保正常释放锁,常把这串代码放在finally{}里。
  • 28
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值