Java基础提升高级API---百知教育java基础学习3
Java基础提升高级API—百知教育java基础学习3
https://www.bilibili.com/video/BV1pE41137JY
函数接口回调 — todo day10
目录
P1-Object类 15:41
P2-Object类中的方法-1 1:08:32
P3-Object类中的方法-2 55:06
P4-包装类 49:17
P5-Object类习题课 45:36
P6-日期处理 24:56
P7-String类的用法 1:04:47
P8-String习题课 25:58
P9-字符串常量池 1:04:48
P10-集合的概念 48:30
P11-List的常用方法 35:27
P12-List的四种遍历方式 1:13:15
P13-泛型 45:57
P14-List的实现类 33:44
P15-Set集合 1:23:26
P16-Map集合 1:14:55
P17-集合习题课 1:01:16
P18-JDK5中的语法 44:22
P19-异常的分类 1:08:31
P20-异常的产生和传递 23:56
P21-声明抛出异常 55:41
P22-捕获异常 1:05:23
P23-IO流的分类 43:34
P24-字节流-1 25:39
P25-字节流-2 34:57
P26-缓冲字节流 1:16:22
P27-对象序列化 40:25
P28-对象的克隆 1:04:49
P29-字符编码与乱码问题 1:12:26
P30-字符流 33:46
P31-File类 20:06
P32-IO习题课 42:45
P33-多线程的基本编程 1:01:23
P34-线程的基本状态 35:57
P35-线程的阻塞 22:40
P36-线程池 1:01:04
P37-Callable和Future接口 54:46
P38-多线程的同步 1:06:12
P39-同步代码块 58:42
P40-同步方法 11:13
P41-线程安全的集合 50:24
P42-队列接口 31:51
P43-死锁问题 28:59
P44-类对象 56:58
P45-反射的应用 1:08:47
P46-单例设计模式 55:02
P47-工厂设计模式 42:55
类和包装类
P1-Object类 15:41
Object类,所有类的父类
如果一个类没有指定父类,默认继承Object类
Object o = 任何对象
Object o != 8种基本类型(byte short int long float double char boolean)
Object 类中定义的方法,是所有java对象都具有的方法 (public protected)
P2-Object类中的方法-1 1:08:32
P3-Object类中的方法-2 55:06
方法名 | 作用 | 备注 |
---|---|---|
getClass() | 获得对象的实际类型 | o1.getClass()=o2.getClass(); 判断类型是否相同 |
finalize() | 在对象被垃圾回收时调用 | 没有典型的使用场景 |
toString() | 返回对象的字符串形式 | System.out.println(o); 等于System.out.pringln(o.toSTring()); |
equals | 判断两个对象的内容是否相同 | o1.equals(o2) 判断o1和o2内容是否相同 |
垃圾自动收集:由JVM的垃圾收集器自动回收垃圾对象,释放对象的堆空间
问:什么对象被认为是垃圾对象?
答:零引用算法 如果一个对象,没有任何对象引用它,就判断它是垃圾
问: 垃圾对象何时被回收?
答:不得不回收时候,才回收(全家人一起吃饭,刷碗要等到所有人吃完饭以后一起刷,不会一个人吃饭饭后,刷一个碗)
问:finalize() 具体作用?
答: 没有什么作用
JVM规范
JVM产品
System.gc(); //呼吁垃圾回收器,开始收集垃圾
toString()
返回对象的字符串形式
打印一个对象,就是打印这个对象toString()方法的返回值String
可以在子类覆盖toString();方法
== 用在引用类型时候判断地址是否相同
equals 判断内容是否相同 s1.equals(s2) 说明s1 s2 内容相同
object类中的equals方法,依然比较两个对象的地址
getClass() 获得对象实际类型
instanceof 判断对象是不是某一类型 a instanceof Animal ; a instance of Dog ;
equals 标准写法
public boolean equals(Object o){
// 是否同一个对象
// 是否非Null
// 是否同一类
// 强转
// 属性比较
}
//this vs o 比较内容
public boolean equals(Object o){
//1 判断 this o 是不是同一对象 ,你媳妇 和你孩子他妈
if(this == o ) return true;
//2 判断o 是不是Null
if(o ==null) return false;
//3 判断this o 是不是属于同一个类
if(this.getClass() != o.getClass()) return false;
// 4 对o 做强制类型转化,变为 Employee 类型
Employee e =(Employee) o;
// 5 逐个比较属性 基本类型用 == 引用类型 用equals
if(this.age == e.age && this.name.equals(e.name)) {
return true;
}else{
return false;
}
}
P4-包装类 49:17
Object o= 任何对象
Object o =10; error
为8中基本数据类型 各自提供一个类(8个类,是8个基本类型的对象形式)
所有的基本数据类型就有了对应的对象形式
int ---- > Integer
基本类型 | 对应的包装类 |
---|---|
int | Integer |
char | Charactor |
byte | Byte |
short | Short |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
- 基本类型 与 包装类之间的转换
int — > Integer
Integer.valueOf(i); 获得一个Integer对象
Integer内部会预先创建 -128 ~ 127 256个对象,如果在此区间不会创建新对象
Integer —> int
a.intValue();
从jdk5开始,编译器帮助我们,自动封箱、自动拆箱 ;
虚拟机还是会区分,什么是基本类型 ,什么是 对象(包装类) ; - 基本类型与String之间的转换 (这块用的多 )
int ----> String
int i=12; String s=i+"";
String s =String.valueof(i);
String----> int
String s=“123456”; int i=Integer.ParseInt(s); - 包装类与String之间的转换
Integer ----> String
Integer a=1234; String s = a.toString(); //是对象所以有Object的toString()方法 ;
String ----> Integer
String s =“1234”; Integer a =Integer.valueof(s);
P5-Object类习题课 45:36
修饰符总结
表格 | 类 | 方法 | 构造方法 | 成员变量 | 局部变量 | 初始代码块 | 成员内部类 |
---|---|---|---|---|---|---|---|
private | √ | √ | √ | √ | |||
默认 | √ | √ | √ | √ | √ | ||
protected | √ | √ | √ | √ | |||
public | √ | √ | √ | √ | √ | ||
static | √ | √ | √ | √ | |||
final | √ | √ | √ | √ | |||
abstract | √ | √ |
System.out.println("=================================");
int a1=new Integer(128);
int a2=new Integer(128);
System.out.println(a1== a2); //true 比较的是值 所以 true
Integer integer1 = Integer.valueOf(a1);
Integer integer2 = Integer.valueOf(a2); //a1 a2 都不影响结果
System.out.println(integer1==integer2); //false 比较的是对象 且128 不在-128~127 需要单独创建
Integer int1=new Integer(120);
Integer int2=new Integer(120);
System.out.println(int1==int2); //false 比较对象
Integer integer11 = Integer.valueOf(int1);
Integer integer12 = Integer.valueOf(int2);//int1 int2 都不影响结果
System.out.println(integer11==integer12); //true 在-128~127 无需单独创建
Integer int3 = new Integer(128);
Integer int4 = new Integer(128);
System.out.println(int3==int4); //false 比较对象
System.out.println("=================================");
P6-日期处理 24:56
package day16;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
/**
* @author leowei
* @date 2020/12/29 - 13:40
*/
public class TestCalendar {
public static void main(String[] args) {
// *******
long timeNowLong = System.currentTimeMillis(); // 距离 1970 年 的毫秒数
System.out.println("timeNow = " + timeNowLong);
// *******
// Calendar c = Calendar.getInstance();
Calendar c = Calendar.getInstance(Locale.FRANCE); //
Date timeNow = c.getTime();
System.out.println("timeNow = " + timeNow);
// *******
c.setTimeInMillis(timeNowLong);
int year = c.get(Calendar.YEAR);
int dayM = c.get(Calendar.DAY_OF_MONTH);
int dayY = c.get(Calendar.DAY_OF_YEAR);
int dayW = c.get(Calendar.DAY_OF_WEEK);
int daySpe =c.getFirstDayOfWeek();
System.out.println("dayW: " + dayW+ " ; dayMonth:"+ dayM + "; dayYear:"+ dayY + " ; year: "+ year +"; firstDayofWeek:"+ daySpe);
//dayW: 3 ; dayMonth:29; dayYear:364 ; year: 2020; firstDayofWeek:1
// *******
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String formatTime = sdf.format(timeNow);
System.out.println("formatTime = " + formatTime);
}
}
P7-String类的用法 1:04:47
凡是没有数值含义的数字,一定不要把它当数值类型。
字符串中的常用方法
- 与字符数组相关操作
String(char[] cs) 利用字符数组构造字符串
toCharArray() 把字符串转字符数组 - 基础方法
toUpperCase()
toLowerCase()
charAt(int index)
length()
trim();
equals();
equalsIgnoreCase();//忽略大小写比较,使用场景 验证码 - 与子串相关
contains(String str)
indexof(String str)
indexof(String str,int fromIndex);
substring(int fromIndex)
substring(int fromIndex,int endIndex);
replace(string str1,string str2)
split(String str); str作为分隔符,将字符串切割为String[]
P8-String习题课 25:58
1.判断一个字符串是否为 回文 字符串 abcdcba --》 abcdcba
2. 在一个字符串“ABCDIFGABC234BC23432BAC2343ABCD”中找出所有的“BC”字符串
private static boolean huiwen03() {
String strInput="abcdefggfedcba"; //abcdcba abcba abba 都可以
for(int i=0;i< strInput.length()/2; i++){
if(strInput.charAt(i)!=strInput.charAt(strInput.length()-1-i)) return false;
}
return true;
}
private static void AllIndexOf(String s,String str){
int start=0;
while(true){
int indexOf = s.indexOf(str, start);
if(indexOf==-1) break;
System.out.println(indexOf);
start = indexOf + str.length();
}
}
P9-字符串常量池 1:04:48
串池,与 StringBuilder
一个String对象的内容是不可以改变的,因此多个引用可以指向同一个字符创对象。-----这句话体会一下串池的概念
当字符串的内容发生改变时候,只会创建新对象
虚拟机存储空间 :堆 栈 方法区
串池:字符串常量池 ,用来存放字符串对象,以供多个引用共享(通常存放在方法区)
public interface CharSequence {
package day14;
/**
* @author leowei
* @date 2020/12/29 - 15:27
*/
public class TestStringAppend {
public static void main(String[] args) {
String s1="ABC";
String s2="ABC";
System.out.println("s1 = s2 :" + s1== s2); //false why???
System.out.println("s1 = s2 :" + (s1== s2)); //true
System.out.println("s1.equals(s2) = " + s1.equals(s2)); //true
System.out.println("s2.equals(s1) = " + s2.equals(s1)); //true
String s3=new String("ABC");
String s4=new String("ABC");
System.out.println("s3==s4 = " + (s3 == s4)); //false
}
}
P10-集合的概念 48:30
集合: 用来存储对象的对象叫做集合-----容器
object[] 数组,最基础的集合
数组是一种基础集合,数组存在如下弊端
1.数组长度固定,数组扩充是需要复杂的拷贝操作
2.数组元素在插入,删除时候不方便
Object[] o={"ABC","DEF","XYZ"}; 要插入LMN 到数组第一个位置
Object[] o={"ABC","DEF","XYZ",null,null,null}; -- step1 扩容
Object[] o={"ABC","DEF","XYZ","XYZ",null,null}; --- step2 挪动
Object[] o={"ABC","DEF","DEF","XYZ",null,null};--- step3 挪动
Object[] o={"ABC","ABC","DEF","XYZ",null,null};--- step4 挪动
Object[] o={"LMN","ABC","DEF","XYZ",null,null}; --- step5 插入
// 自定义List 类
package day14.day15;
import java.util.Objects;
/**
* @author leowei
* @date 2020/12/29 - 16:18
*/
public class TestList {
public static void main(String[] args) {
MyList list = new MyList();
list.add("zhangsan");
list.add("lisi");
list.add("wangwu");
list.add("gousheng"); //大于三个自动扩容
list.add("xiaoli");
list.add(0,"huhu");
for(int i=0;i<list.size();i++){
Object o = list.get(i);
System.out.println("o = " + o);
}
/*
o = huhu o = zhangsan o = lisi
o = wangwu o = gousheng o = xiaoli
* */
}
}
class MyList{
private Object[] os =new Object[3];
private int index; //数组中有效元素的个数,也是元素下标范围 0 - index-1 ;
//添加到元素末尾
public void add(Object o){
if(os.length==index){
expand();
}
os[index]=o;
index++;
}
//添加元素到指定pos下标
public void add(int pos,Object o){
if(os.length==index){
expand();
}
for(int i=index;i>pos;i--){
os[i]=os[i-1];
}
os[pos]=o;
index++;
}
//数组扩容 2 倍
public void expand(){
Object[] os2 = new Object[os.length * 2];
for(int i=0;i<os.length;i++){
os2[i]=os[i];
}
os=os2;
}
public int size(){
return index;
}
public Object get(int pos){
return os[pos];
}
}
P11-List的常用方法 35:27
collection 方法 | 说明 |
---|---|
add(Object o) | 把对象放入当前集合 |
AddAll(Collection c) | |
Clear() | 清空集合 |
contains(Object o) | 判断集合中是否存在o |
remove(Object o) | 00 |
size() | 00 |
forEach() | 遍历当前集合 |
toArray() | 将当前集合转换为Object[] |
-----list方法-------- | ---------------- |
add(int pos,Object o) | 将元素插入到当前集合的pos下标上 |
get(int pos ) | |
indexOf(Object o) | |
remove(int pos) | 删除集合中pos位置的元素 |
set(int pos,Object o) | 将元素设置到当前集合的pos下标上 |
map 方法 | 说明 |
---|---|
put(K key,V value) | 把 key-value 键值对 放入map ,如果key 已经存在,新value覆盖老value |
V get(K key) | |
containsKey(K key) | |
containsValue(V value) | |
size() | |
remove(K key) | |
keySet | 返回所有键的集合 |
values | 返回map中所有值的集合 |
集合的组成 java.util 包
----collection----接口
接口特点: 元素是对象(Objet)
常用方法:(见上表 )
遍历: 见下
实现类: 无直接实现类
List Collection 子接口
接口特点: 元素有顺序,有下标 ,可以重复
常用方法:(见上表 )
遍历: (四种) 迭代遍历 for-Each遍历 forEach()自遍历 下标遍历
实现类: ArrayList
Set Collection 子接口
接口特点: 元素无顺序,无下标 ,内容不可以重复
常用方法:(见上表 )
遍历: (三种) 迭代遍历 for-Each遍历 forEach()自遍历
实现类: HashSet LinkedHashSet TreeSet (自动对元素进行排序,根据规则过滤重复元素,极少用)
----map----接口
接口特点: 元素是键值对 Key对象 无顺序,内容不可重复 ; value 对象 可以重复
常用方法:
遍历: 见下
实现类: HashMap 使用Hash算法实现(链表数组,红黑树) 1.2 线程不安全 允许Null作为key 或 value
LinkedHashMap HashMap的子类,维护键值对的添加顺序
TreeMap 自动对键进行排序
HashTable 1.0 线程安全 慢 不允许Null作为key 或 value
Properties Hashtable的子类 用于配置文件
简介: 英汉词典就是 map apple --苹果 (apple 不可以重复)
用户名密码 也是 map username1 -- pwd1 (username不可以重复)
P12-List的四种遍历方式 1:13:15
package day14.day15;
import javax.lang.model.SourceVersion;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Objects;
import java.util.function.Consumer;
/**
* @author leowei
* @date 2020/12/29 - 16:18
*/
public class TestList {
private static String result="";
public static void main(String[] args) {
//原始数据
// MyList list = new MyList(); // 自定义List类
list.add("zhangsan");
list.add("lisi");
list.add("wangwu"
//list 的四种遍历方式
System.out.println("==============下标遍历==================");
//方式一 下标遍历 (可以遍历List 不可以遍历Set ,因为set 没有下标 )
for(int i=0;i<list.size();i++){
Object o = list.get(i);
System.out.println(" o = " + o);
}
//方式二 迭代方式遍历 自jdk1.2 方式出现的迭代方式
System.out.println("===============迭代方式遍历=============");
Iterator it = list.iterator();
while(it.hasNext()){
Object next = it.next();
String s =(String) next;
System.out.println(" s = " + s);
}
//方式三 for-Each 自jdk1.5 方式出现的迭代方式
System.out.println("===========for-Each 遍历 ============");
for(Object o: list){
String s=(String)o;
System.out.println("s = " + s);
}
//方式四 forEach 自遍历 自jdk 8 开始 (有如下三种变形)
System.out.println("===========forEach 自遍历 1 接口回调 ============");
class MyConsumer implements Consumer{
@Override
public void accept(Object o) {
System.out.println(o);
}
}
// 接口回调
list.forEach(new MyConsumer());
System.out.println("===========forEach 自遍历2 匿名内部类 ============");
//方式4.1
list.forEach(new Consumer() {
@Override
public void accept(Object o) {
System.out.println(o);
}
});
System.out.println("===========forEach 自遍历 3 lambda ============");
//方式4.2 lambda 把代码当做参数传递
list.forEach(x-> System.out.println("x = " + x));
// final String result="";//result 外部类的局部变量
// lambda 中不能改变 外部类的局部变量
// lambda 访问外部类的局部变量的时候默认增加 final ,final 限定不可以改值,所以要将result放到外部,作为成员变量,供lambda表达式访问
System.out.println("===========番外: forEach 使用成员变量 ============");
list.forEach(x-> result+=x );
System.out.println("result = " + result);
}
}
P13-泛型 JDK 5 45:57
集合中存储的是对象,无法对元素的类型做出约定----类型不安全
List list = new ArrayList();
list.add(对象);
Object o =list.get(0);
String[]
Int[] --------------------数组是安全的,类型确定
JDK1.5 开始使用泛型 ,利用泛型,可以约定集合中元素的类型。
interface A{
void m1(String s);
Interger m2();
}
// 1.5 以后
interface A<T> {
void m1(T s);
}
class B implates A<String>{
public void m1(String){}
}
// 1.5 以后
interface A<T,V> {
void m1(T s);
V m2();
}
class B implements A<String,Integer>{
public void m1(String s){}
public Integer m2{ return 0; }
}
class C implements A<Double,String>{
public void m1(Double d){}
public String m2{ return ""; }
}
// E 约束了集合中元素的类型
interface List <E>{
void add(E o);
E get(int pos);
}
P14-List的实现类 33:44
不同的 list 实现类之间的区别是什么?
散列表: 分散排列
ArrayList (线程不安全,高效) 数组实现 --- 查询快 增删慢 ----- JDK1.2 (1998年)
LinkedList 链表实现 --- 查询慢 增删快
Vector (线程安全,低效) 数组实现 ----- JDK1.0 (1995年)
HashSet 散列表 --- 查询块 增删快
P15-Set集合 1:23:26
https://www.bilibili.com/video/BV1pE41137JY?p=15
看下图,散列表有很多的无效空间,散列表 查询也快,插入也快,是典型的用空间换时间的方式。
先看Hashcode ,hashcode 相同,再比较equals
Set 无下标,无序,不可以重复
(三种) 迭代遍历 for-Each遍历 forEach()自遍历
HashSet 底层 还是数组 ,具体的叫法是 链表数组
如果将自定义的对象放入HashSet ,为了保证元素内容不重复
1.)覆盖hashCode方法,保证内容相同的对象返回相同的整数
2.)覆盖equals方法,保证内容相同的对象返回true
3.)尽量保证不同对象,返回不同hashcode
P16-Map集合 1:14:55
https://www.bilibili.com/video/BV1pE41137JY?p=16
P17-集合习题课 1:01:16
P18-JDK5中的语法 44:22
1.静态引入
2. 可变长参数
//a: 0-n个参数
// 可变长参数相当于数组参数,int... a 相当于 int[] a
// 一个函数的参数表中,只能有一个可边长参数,且必须是参数表的最后一个参数
static void fn(int ... a){ //等同于 static void fn(int[] a){ }
for (int i:a){
System.out.println(i);
}
}
3 标注
// 普通注释: 给人看的
// 标注: 描述代码的代码 给机器看的
// 标注使用场景:
// 用在 包、类、属性、方法、构造函数等程序组件声明之前
//@标注名(属性1=值1,... 属性n=值n);
// 标记标注 没有属性 ()可以省略 @Override
// 单值标注 只有一个属性 如果属性名为value ,value 可以省略 直接写 @标注名(值)
// 普通标注 有属性
4. 格式化输出 printf
public static void main(String[] args) {
String name ="llll";
int age=40;
// 格式化输出
System.out.printf("Student nam=%s,age=%d",name,age); //printf 占位符
}
5. 泛型
6. 自动封箱 装箱
7. 枚举
P19-异常的分类 1:08:31
Throwable/Exception/RuntimeException/ … 继承这个包的类,为检查异常,可以通过人工确认,避免异常发生的 。
避免异常: 尽可能使异常不出现,不发生
处理异常: 当异常发生时,应对这种情况 有部分代码,正常情况不执行,异常发生时候才执行
异常的分类
Throwable 所有异常的父类
Error 错误 严重的底层错误 不可避免 无法处理
Exception 异常 可以处理的
RuntimeException 子类 运行时异常 (编译器)未检查异常 可以避免 (可以处理,可以不处理,如人为的火灾 )
非RuntimeException 子类 (编译器)已检查异常 不可避免 (必须处理, 如地址 )
if(a!=null) a.method(); //避免 NullPointerException
if(i>=0 && i<a.lentgh) System.out.println(a[i]); 避免ArrayIndexoutofBoundsException
if(a instanceof Dog) Dog d =(Dog) a; //避免 ClassCastException
//查看以上几个EXCEPTION都是RuntimeException 的子类,都是可以避免的运行时异常 ,
未检查异常
已检查异常
P20-异常的产生和传递 23:56
P21-声明抛出异常 55:41
异常处理方式:
1. 声明抛出 : 此种方式只是转移了异常,并没有真正处理异常
public void method() throws IOException
throws 异常类名1 , 异常类名2 , 异常类名3
方法覆盖时,子类不能比父类抛出更多的异常
2. 捕获异常
try{
语句1
语句2
语句…
语句n
}
catch(异常引用1 e){
}
catch(异常引用2 e){
}
catch(异常引用3 e){
}
package day18;
import java.io.EOFException;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* @author leowei
* @date 2020/12/30 - 9:42
* main ---- 总理
* mProvince --- 省长
* mCity ---- 市长
* mVillage ---- 村长
*/
public class TestException {
public static void main(String[] args) throws Throwable {
System.out.println("main 1 ------------------");
mProvince(2);
System.out.println("main 2 ------------------");
System.out.println("main 3 ------------------");
}
// 省长
static void mProvince(int i) throws Exception {
System.out.println("ma 1 =========");
mCity(i);
System.out.println("ma 2 =========");
System.out.println("ma 3 =========");
}
//市长
static void mCity(int i) throws IOException,MyException{
System.out.println("mb 1 ~~~~");
mVillage(i);
System.out.println("mb 2 ~~~~");
System.out.println("mb 3 ~~~~");
}
//村长
static void mVillage(int i) throws EOFException,FileNotFoundException,MyException {
System.out.println("mc 1");
if (i == 0) throw new NullPointerException("模拟空指针异常,夫妻吵架,村长处理");
if (i == 1) throw new EOFException("EOF 文件以外终止,旱灾 村长不处理,报告县长");
if (i == 2) throw new FileNotFoundException("文件没有找到,洪灾 村长不处理,报告县长");
if (i == 3) throw new MyException("我自己定义的异常 ,遇到疫情 村长不处理,报告县长");
System.out.println("mc 2");
System.out.println("mc 3");
}
}
//自定义异常类
class MyException extends Exception{
public MyException(){}
public MyException(String msg){
super(msg);
}
}
P22-捕获异常 1:05:23
try{} catch(){}
try{} catch(){} finally {}
try{} finally {}
package day18;
/**
* @author leowei
* @date 2020/12/30 - 12:15
*/
public class TestFinally {
public static void main(String[] args) {
System.out.println(fn(2)); //结果 2 不管错还是对 都执行 finnally 的语句
System.out.println("---------------------------------");
System.out.println(fn(0)); //结果 2 不管错还是对 都执行 finnally 的语句
}
static int fn(int n){
try {
int a=6/n;
return a;
} catch (Exception e) {
e.printStackTrace();
return 0;
} finally {
return 2;
}
}
}
P23-IO流的分类 43:34
Java程序的输入和输出
流对象(Stream): 用来传输数据的对象
流的分类:3中分类方式
方式1:按照流的方向
-------输入流:读数据
-------输出流 :写数据
方式2:数据单位
-------字节流:以字节为单位串数据, 可以处理一切数据
------- 字符流:以字符为单位串数据 , 专门用于处理文本数据(.txt .html .java .xml)
方式3: 流的功能
-------节点流:实际负责数据传输
-------过滤流:为节点流增强功能
P24-字节流-1 25:39
java.io.InputStream / OutputStream 是个抽象类 所有字节流的父类
*****InputStream,*****OutputStream ,父类作为子类的后缀
FileInputStream,FileOutputStream 文件字节流
在这里插入代码片
P25-字节流-2 34:57
标准处理FileOutoutStream流的方式
package day19;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* @author leowei
* @date 2020/12/30 - 14:45
*/
public class TestOutputStream2 {
public static void main(String[] args) {
OutputStream os=null;
try {
os =new FileOutputStream("a.txt");
os.write('D');
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(os!=null){
os.close();//关闭流
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
try-with-resource jdk 1.7 开始
try( 实现 AutoCloseable接口的 资源 ){}
catch(Exception e){}
//关闭资源 无需程序员关注了
// 用下面的语句替换上面的语句
//放入 try 块的所有资源必须实现 AutoCloseable接口
try(OutputStream os=new FileOutputStream("a.txt")) {
os.write('D');
}catch(IOException e){
e.printStackTrace();
}
package day19;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* @author leowei
* @date 2020/12/30 - 15:02
*/
public class TestInputStream {
public static void main(String[] args) throws Exception {
m1();
return;
}
// throw exception 的写法
private static void m1() throws IOException {
InputStream is = new FileInputStream("a.txt");
//int read = is.read(); //从文件中读一个字节,返回值就是字节对应的数字 (A --> 65 )
while (true){
int a= is.read();
if(a==-1){
break;
}
System.out.println("a = " + a);
System.out.println("change type a is " + (char)a);
}
is.close();
}
// try-with-resource 写法 (自 jdk 1.7 开始 )
private static void m2() {
try( InputStream inputStream = new FileInputStream("a.txt")){
while (true){
int a= inputStream.read();
if(a ==-1){
break;
}
System.out.println("change type a is " + (char)a);
System.out.println("a = " + a);
}
}catch (IOException e){
e.printStackTrace();
}
}
}
P26-缓冲字节流 1:16:22
BufferedInputStream / BufferedOutputStream 过滤流
缓冲功能,提高IO 效率
IO 编程基本顺序
1.创建节点流
2.封装过滤流
3.读写数据
4.关闭外层流
FileOutputStream fos = new FileOutputStream("a.txt");
BufferedOutputStream out = new BufferedOutputStream(fos);
out.write('A');
out.close();
package day19;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author leowei
* @date 2020/12/30 - 15:53
*/
public class TestBufferedStream {
public static void main(String[] args) throws IOException {
// m1();
m2();
}
// 缓冲流 标准 写法
private static void m1() throws IOException {
FileOutputStream fos = new FileOutputStream("a.txt");
BufferedOutputStream out = new BufferedOutputStream(fos);
out.write('A');
out.write('B');
out.write('C');
out.write('D');
out.flush(); //清空缓冲区, 不关闭流
//out.close(); //关闭 BufferedOutputStream 自动 关闭 其包装的 FileOutputStream
}
// 缓冲流 Jdk 1.7 后的 try-with-resource 写法
private static void m2() {
try (FileOutputStream fos = new FileOutputStream("a.txt");
BufferedOutputStream out = new BufferedOutputStream(fos);
) {
out.write('A');
out.write('B');
out.write('C');
out.write('D');
out.flush(); //清空缓冲区, 不关闭流
//out.close(); //关闭 BufferedOutputStream 自动 关闭 其包装的 FileOutputStream
} catch (Exception e) {
e.printStackTrace();
}
}
}
P27-对象序列化 40:25
ObjectOutputStream / ObjectInputStream 对象流
对象序列化: 把对象通过流来传输
只有实现了 java.io.serializable 这个接口,才能实现序列化
用transient修饰的属性成为临时属性,不参加序列化
package day19;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/**
* @author leowei
* @date 2020/12/30 - 16:42
*/
public class TestObjectStream {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Employee e = new Employee("lichao", 44);
FileOutputStream fos = new FileOutputStream("a.data"); // 1. 创建节点流
ObjectOutputStream oos =new ObjectOutputStream(fos); // 2. 创建过滤流
oos.writeObject(e); // 3. 写数据
oos.close(); // 4. 关闭节点
System.out.println("ok");
FileInputStream fis=new FileInputStream("a.data");
ObjectInputStream ois =new ObjectInputStream(fis);
Employee o = (Employee)ois.readObject();
ois.close();
System.out.println(o.getName()+" ---- "+ o.getAge());
// lichao ---- 0
// transient int age; age 使用transient 娶不到值 多以为空
}
}
class Employee implements Serializable{
String name;
transient int age;
//不想让属性参加序列化 -- Transient 临时属性,不参加序列化
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
P28-对象的克隆 1:04:49
透彻的讲 浅拷贝 深拷贝
https://www.bilibili.com/video/BV1pE41137JY?p=28
克隆一个对象: equals 为 true , == 为 false
浅拷贝:需要克隆的类,必须实现Cloneable接口,super.clone() 利用Object类的Clone方法实现
深拷贝:无需实现Cloneable接口
浅拷贝
代码路径: day20.TestClone
https://github.com/wei198621/javaBasic03Apis/blob/main/src/main/java/day20/TestClone.java
浅拷贝代码
浅拷贝: 对象在复制,但是对象内的属性没有复制
//1. 覆盖object类的clone方法,将访问修饰符从Protected提高为public
// 2. 需要克隆的类,必须实现Cloneable接口,
public Object Clone(){
try {
return super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
package day20;
/**
* @author leowei
* @date 2020/12/30 - 17:45
*/
public class TestClone {
public static void main(String[] args) {
Teacher t = new Teacher("hxz", 44);
Student s = new Student("weilie", 22,t);
System.out.println("s = " + s);
Student s2 =(Student)s.Clone();
System.out.println("s2 = " + s2); //Student implements Cloneable{ 正常clone
System.out.println("s== s2 = " + (s == s2)); // false 不是同一个对象
System.out.println(s.getTeacher()==s2.getTeacher()) ; //true
//System.out.println(s.getName() == s2.getName()); //true
}
}
class Student implements Cloneable{
private String name;
private int age;
private Teacher teacher;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public Teacher getTeacher() {
return teacher;
}
public Student(String name, int age, Teacher teacher) {
this.name = name;
this.age = age;
this.teacher = teacher;
}
// 浅拷贝
//1. 覆盖object类的clone方法,将访问修饰符从Protected提高为public
// 2. 需要克隆的类,必须实现Cloneable接口,
public Object Clone(){
try {
return super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", teacher=" + teacher +
'}';
}
}
class Teacher{
private String name;
private int age;
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
深拷贝
代码路径: day20.TestCloneDeep
https://github.com/wei198621/javaBasic03Apis/blob/main/src/main/java/day20/TestClone.java
package day20;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/**
* @author leowei
* @date 2020/12/30 - 17:45
*/
public class TestCloneDeep {
public static void main(String[] args) {
Teacher2 t = new Teacher2("hxz", 44);
Student2 s = new Student2("weilie", 22,t);
System.out.println("s = " + s);
//Student2 s2 =(Student2)s.Clone();
Student2 s2 =(Student2)s.ClonePlus();
System.out.println("s2 = " + s2); //Student implements Cloneable{ 正常clone
System.out.println("s== s2 = " + (s == s2)); // false 不是同一个对象
System.out.println(s.getTeacher()==s2.getTeacher()) ; //false
System.out.println(s.getName() == s2.getName()); //false
}
}
class Student2 implements Serializable{
private String name;
private int age;
private Teacher2 teacher;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public Teacher2 getTeacher() {
return teacher;
}
public Student2(String name, int age, Teacher2 teacher) {
this.name = name;
this.age = age;
this.teacher = teacher;
}
// 深拷贝
//1. 当前对象要实现 implements Cloneable ,Serializable 两个接口
public Object Clone() {
//将当前Student对象 放到a.data目录 a.data 在本地,涉及到 虚拟机向本地数据的存储
try (FileOutputStream fos = new FileOutputStream("a.dat");
ObjectOutputStream out = new ObjectOutputStream(fos);) {
out.writeObject(this);
} catch (Exception e) {
}
//将a.data目录数据取出 反序列化到Student对象
try (FileInputStream fis = new FileInputStream("a.dat");
ObjectInputStream in = new ObjectInputStream(fis);) {
Object o = in.readObject();
return o;
} catch (Exception e) {
return null;
}
}
// 深拷贝
//1. 当前对象要实现 implements Cloneable ,Serializable 两个接口
//ByteArrayInputStream ByteArrayOutputStream
public Object ClonePlus() {
//将当前Student对象 byte[] bs bs在虚拟机中,所以很快
byte[] bs =null ;
try ( ByteArrayOutputStream bos =new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);) {
out.writeObject(this);
bs = bos.toByteArray();
} catch (Exception e) {
}
//将byte[] bs 反序列化到Student对象
try ( ByteArrayInputStream bis =new ByteArrayInputStream(bs);
ObjectInputStream in = new ObjectInputStream(bis);) {
Object o = in.readObject();
return o;
} catch (Exception e) {
return null;
}
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", teacher=" + teacher +
'}';
}
}
class Teacher2 implements Serializable{
private String name;
private int age;
public Teacher2(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
P29-字符编码与乱码问题 1:12:26
P30-字符流 33:46
P31-File类 20:06
P32-IO习题课 42:45
P33-多线程的基本编程 1:01:23
P34-线程的基本状态 35:57
P35-线程的阻塞 22:40
P36-线程池 1:01:04
P37-Callable和Future接口 54:46
P38-多线程的同步 1:06:12
P39-同步代码块 58:42
P40-同步方法 11:13
P41-线程安全的集合 50:24
P42-队列接口 31:51
P43-死锁问题 28:59
P44-类对象 56:58
P45-反射的应用 1:08:47
P46-单例设计模式 55:02
P47-工厂设计模式 42:55
本文地址:https://blog.csdn.net/wei198621/article/details/111876706