java笔记04

Java第一阶段总复习(高级、API)

1, IO流

1)学习方式:学习抽象父级的公共方法 学习子类流对象的创建方式

2)流的分类
根据方向:输入流 输出流
根据操作单位:字节流 字符流

主流分类:

按照方向进行分类:输入流 输出流(相对于程序而言,从程序写数据到文件是输出)

按照传输类型进行分类:字节流 字符流

组合:字节输入流 字符输入流 字节输出流 字符输出流

学习方法:在抽象父类中学习通用方法,在子类中学习如何创建对象

  1. 字节输入流InputStrream:

InputStream--抽象父类--不能实例化

FileInputStream--文件字节输入流-FIS

BufferedInputStream--高效字节输入流-BIS

FIS in = new FIS(new File(路径));
FIS in = new FIS(路径);
BIS in = new BIS( new FIS(new File(路径)));
BIS in = new BIS(new FIS(路径));

字节输出流OutputStrream:

OutputStream--抽象父类,不能实例化

FileOutputStream--文件字节输出流--FOS

BufferedOutputStream--高效字节输出流-BOS

FOS out = new FOS(new File(路径));
FOS out = new FOS(路径);
BOS out = new BOS(new FOS(new File(路径)));
BOS out = new BOS(new FOS(路径));

字节输入流:

InputStream 抽象类,不能new,可以作为超类,学习其所提供的共性方法

FileInputStream 子类,操作文件的字节输入流,普通类

BufferedInputStream 子类,缓冲字节流,普通类

字节输出流:

OutputStream 抽象类,不能new,可以作为超类,学习其所提供的共性方法

FileOutputStream 子类,操作文件的字节输出流,普通类

BuffereOutputStream 子类,缓冲字节输出流,普通类

字符输入流Reader:

Reader--抽象父类--不能实例化

FileReader--文件字符输入流-FR

BufferedReader--高效字符输入流-BR

FR in = new FR(new File(路径));
FR in = new FR(路径);
BR in = new BR(new FR(new File(路径)))
B R in = new BR(new FR(路径));

字符输出流Writer:

Writer--抽象父类,不能实例化

FileWriter--文件字符输出流--FW

BufferedWriter--高效字符输出流--BW

FW out = new FW(File/File,append/String pathname/String pathname,append);
BW out = new BW(Writer–所以传的是子类FW(上面那4种));
注意:这里的append参数表示流向文件输出数据的时候是追加还是覆盖, 如果不写,默认false是覆盖,如果改为true,表示追加

字符输出流:

Reader 抽象类,不能new,可以作为超类,学习其所提供的共性方法

FileReader 子类,操作文件的字符输入流,普通类

BUfferedReader 子类,缓冲字符输入流,普通类

字符输出流:

Writer 抽象类,不能new,可以作为超类,学习其所提供的共性方法

FileWriter 子类,操作文件的字符输出流,普通类

BufferedWriter 子类,缓冲字符输出流,普通类

  1. 序列化与反序列化

序列化与反序列化的作用就是对象的保存与传输
序列化:把内存中的对象通过序列化流输出到磁盘中(比如文件里),使用的流是ObjectOutputStream【把数据写出到文件】
反序列化:通过反序列化流将磁盘中的数据恢复成对象,使用的流是ObjectInputStream【把之前写到文件里的数据读到程序中】
注意1:一个类的对象如果想被序列化,那么这个类必须实现可序列化接口
实现这个接口的目的是相当于给这个类做了一个标记,标记可以序列化
注意2:序列化时会自动生成一个UID,表示当前序列化输出的对象的版本信息
反序列化时会拿着当前的UID与之前序列化输出的UID做比较,一致,反序列化成功,不一致,报错
注意3: 所以,标准操作是一次序列化对应一次反序列化
如果目标对象所在的类没有做任何修改,一次序列化也可以对应多次反序列化(根本原因是UID没变)

  1. 集合
  1. 泛型

泛型通常与集合一起使用,用来约束集合中元素的类型
泛型< type >必须写引用类型而不是基本类型
泛型方法 public static ==< E > == void get(E[] e){},两处位置都 出现了泛型,缺一不可

  1. 集合被称作Collection,是一个可以存放多个数据的容器,而且集合中提 供了丰富的方法来操作集合中的元素
    是集合层次的根接口,学习抽象父级的公共方法

单个集合的操作:

boolean add(E e) 将指定元素添加到集合中
void clear() 清空集合
boolean contains(Object o) 判断本集合是否包含指定的元素
boolean equals(Object o) 比较集合对象与参数对象o是否相等
int hashCode() 返回本集合的哈希码值
boolean isEmpty() 判断本集合是否为空
boolean remove(Object o) 从本集合中移除指定元素o
int size() 返回本集合中元素的个数
Object[] toArray() 将本集合转为数组

集合间的操作:

boolean addAll(Collection<> c) 将c集合中的所有元素添加到本集合 中
boolean containsAll(Collection<> c) 判断本集合是否包含c集合的 所有元素
boolean removeAll(Collection<> c) 移除本集合中属于参数集合c的 所有元素
boolean retainAll(Collection<> c) 保留本集合与参数集合c的公共 元素

集合的迭代:

Iterator iterator() 返回本集合的迭代器

  1. List接口的特点

List集合是有下标的

List集合是有顺序的

List集合可以存放重复的数据

单个集合的操作:

void add(int index, E element) 在集合的指定下标index处插入指定 元素element
E get(int index) 返回本集合中指定下标index处的元素
E remove(int index) 移除本集合中指定下标index处的元素
E set(int index, E element) 用参数元素element替换集合中指定下 标index处的元素
int indexOf(Object o) 判断指定元素o在本集合中第一次出现的下标, 如果不存在,返回-1
int lastIndexOf(Object o) 判断指定元素o在本集合中最后一次出现 的下标,如果不存在,返回-1
List subList(int fromIndex, int toIndex) 截取子集合,包含 formidex处的元素,不包含toIndex处的元素

集合间的操作与集合的迭代

boolean addAll(int index, Collection<> c) 将参数集合c中的所有 元素,插入到本集合中指定的下标index处
ListIterator listIterator() 返回此列表元素的迭代器,这个是List 自己的,不太常用,可以逆序迭代

  1. List接口的两个常用实现类

ArrayList的特点:
(1)底层的数据结构是数组,内存空间是连续的
(2)元素有下标,通常可以根据下标进行操作
(3)增删操作比较慢,查询操作比较快【数据量大时】
LinkedList的特点:
(1)底层的数据结构是链表,内存空间是不连续的
(2)元素有下标,但是通常首尾节点操作比较多
(3)增删操作比较快,查询操作比较慢【数据量大时】
注意:LinkedList查询慢也不是都慢,首尾操作还是比较快的

简单方法:

void addFirst(E e) 添加首元素
void addLast(E e) 添加尾元素
E removeFirst() 删除首元素
E removeLast() 删除尾元素
E getFirst() 获取首元素
E getLast() 获取尾元素
E element() 获取首元素

功能一致但是名字不太好记的方法:

boolean offer(E e) 添加尾元素
boolean offerFirst(E e) 添加首元素
boolean offerLast(E e) 添加尾元素
E peek() 获取首元素
E peekFirst() 获取首元素
E peekLast() 获取尾元素
E poll() 返回并移除头元素
E pollFirst() 返回并移除头元素
E pollLast() 返回并移除尾元素

  1. Map接口

Map接口的特点

map集合的结构是:键值对、KEY与VALUE、Map.Entry<K,V>的映射关系

map中key值不允许重复,如果重复,对应的value会被覆盖

map中的映射关系是无序的

map没有自己的迭代器,所以迭代时通常需要转成set集合来迭代

简单方法:

void clear() 清空集合
boolean equals(Object o) 判断集合对象与参数o是否相等
int hashCode() 返回本集合的哈希码值
boolean isEmpty() 判断集合是否为空
int size() 返回本集合中键值对的个数

map单个集合间的操作

boolean containsKey(Object key) 判断map中是否包含指定的key
boolean containsValue(Object value) 判断map中是否包含指定的value
V get(Object key) 根据指定的key返回对应的value,如果不存在,返回null
V remove(Object key) 删除本集合中参数key对应的键值对
V put(K key, V value) 向集合中添加映射关系(键值对)
void putAll(Map<> m) 向本集合中添加m集合的所有映射关系(键值对)

map的迭代

  Collection values() 把本map中的Value值取出放入一个Collection中并返回这个Collection
Set keySet() 把本map中的Key值取出放入一个Set集合中并返回这个Set集合
Set<Map.Entry<K,V>> entrySet()
把本map中的每一对KV都看成是一个Entry,把所有的Entry取出放入一个Set集合中并返回这个Set集合

   6)Set接口

   Set接口的特点

set集合没有重复的元素

set集合的元素是无序的

set集合可以存null值,并且null最多有一个

我们自定义对象如果想去重,需要在自定义类中添加重写的equals()与hashCode()

7)集合学习的方法

   学习父级的公共方法,学习子类的创建方式,学习各种集合的特点

关于List大多都是与下标有关的操作

关于Set通常都是去重的操作

关于map通常都是映射关系,也就是键值对

API要常练习,方法互相之间没有任何关系,用哪个,查哪个

3,进程与线程

1)程序:数据与指令的集合,而且程序是静态的

2)进程:运行中的程序,给程序加入了时间的概念,不同时间进程有不同 的状态,进程是动态的,代表OS中正在运行的程序
进程有独立性,动态性,并发性

3) 并行:相对来说资源比较充足,多个CPU同时并发处理多个不同的进程

4)并发:相对来说资源不太充足,多个资源同时抢占公共资源,比如CPU

5)线程:线程是OS能够进行运算调度的最小单位
一个进程可以拥有多个线程,当然,也可以只拥有一个线程,只有一个线程 的进程称作单线程程序
注意:每个线程也有自己独立的内存空间,当然也有一部分共享区域用来保 存共享的数据

6)线程的几种状态以及线程状态之间的切换
(1)新建状态:创建线程对象,申请PCB,对应的是new线程对象
(2)就绪状态/可运行状态:万事俱备,只欠CPU,刚刚创建好的线程对象所 有资源已经准备好,并且加入到了就绪队列之中
唯有等待操作系统的调度,只要分配了CPU,也就是时间片,当前线程可立即 执行,对应的是start()
注意:调用start()并不会立即执行线程对象,这个是由OS的调度规则决定 的。我们控制不了
(3)执行/运行状态:就绪队列中的线程对象被OS选中,分配了时间片, 正在执行
注意:只有就绪状态才能变成运行状态
(4)阻塞状态:线程在执行过程中遇到了问题,比如锁阻塞、休眠阻塞、 等待阻塞…
注意:我们的阻塞状态,等问题解决了以后/获取了临界资源【要抢占的公 共资源】后
是加入到就绪队列中的,转为就绪状态,而不是转为运行状态直接执行
(5)终止状态:线程成功执行完毕,释放资源,归还PCB
(6)线程的挂起:正在运行中的线程,由于CPU分配的时间片已经用完, 所以需要冻结当前线程运行的状态与各项信息
把它插入到就绪队列中,直到下次这个线程被调度执行时,重新恢复现场, 继续执行

  1. 多线程编程实现方案一:extends Thread继承方式
    (1)自定义一个多线程类用来继承Thread类
    (2)重写run()里的业务【这个业务是自定义的】
    (3)创建线程对象【子类对象】
    (4)通过刚刚创建好的自定义线程类对象调用start()
      注意1:不能调用run(),因为这样调用只会把run()看作一个普通的方法, 并不会以多线程的方式启动程序
    而且调用start()时,底层JVM会自动调用run(),执行我们自定义的业务
    注意2:我们除了可以调用默认的父类无参构造以外,还可以调用 Thread(String name),给自定义的线程对象起名字,相当于super(name);

8) 多线程编程实现方案二:implements Runnable 实现方式
(1)自定义一个类实现接口Runnable
(2) 实现接口中唯一一个抽象方法run()
(3) 创建接口实现类的对象,这个对象是作为我们的目标业务对象【因为这个  自定义类中包含了我们的业务】
(4)创建Thread类线程对象,调用的构造函数是Thread(Runnable target)
(5)通过创建好的Thread类线程对象调用start(),以多线程的方式启动同一个业 务target
注意1:由于Runnable是一个接口,无法创建对象,所以我们传入的目标业 务类,也就是接口实现类的对象
注意2:只有调用start()才能把线程对象加入到就绪队列中,以多线程的方 式启动,但是:
接口实现类与接口都没有这个start(),所以我们需要创建Thread类的对象来 调用start(),并把接口实现类对象交给Thread(target);
大家可以理解成“抱大腿”,创建的是Thread类的线程对象,我们只需要把业 务告诉Thread类的对象就好啦
使用方式二的优势:
(1)耦合性不强,没有继承,后续仍然可以继承别的类
(2)采用的是实现接口的方式,后续仍然可以实现别的接口
(3)可以给所有的线程对象统一业务,业务是保持一致的
(4)面向接口编程,有利于我们写出更加优雅的代码

9) 多线程编程实现方案三:Executors 创建线程池的方式
(1)创建线程池的工具类:Executors.newFixedThreadPool(int n);可以创建包含最 多n个线程的线程池对象
(2)创建好的线程池对象:ExecutorService
使用pool.excute()来讲线程池中的线程以多线程的方式启动,每次调用都会 将一个线程对象加入到就绪队列之中
这个线程池对象负责: 新建/启动/关闭线程,而我们主要负责的是自定义的 业务
注意:线程池是不关闭的,实现的效果就是线程池中线程对象的随取随用, 这样就避免了频繁的创建与销毁线程,不会造成资源浪费
(3)合理利用线程池可以拥有的优势:
降低系统的资源消耗:减少系统创建与销毁线程对象的次数,每个线程都可 以重复利用,执行多次任务
提高响应速度:当任务到达时,任务可以不用等待线程创建就能立即执行
提高线程的可管理性:可以根据系统的承受能力,调整线程池中线程的数目
防止因为创建多个线程消耗过多的内存导致服务器的崩溃
【每个线程大约需要1MB的内存,线程开的越多,消耗的内存也就越大, 最后死机】

10) 多线程数据安全隐患的解决方案
(1)出现数据安全问题的原因:多线程程序 + 多个线程拥有共享数据 + 多条 语句操作共享数据
(2)解决:加锁synchronized同步关键字
同步方法【不太常用】,格式:在方法的定义上加synchronized
同步代码块,格式:

synchronized(唯一的锁对象){

可能会出现数据不安全问题的所有代码

}

  注意1:锁对象必须唯一!!!

  比如:如果是实现接口的方式,只需要创建一个接口实现类对象。而这个对象当做的是目标业务对象,类中定义的锁对象自然也只有一个

  比如:如果是继承Thread类的方式,我们需要创建多个子类对象作为线程对象

            那这个时候不同的线程对象间应该共享同一把锁,所以需要把锁设置为静态,被全局所有对象共享

            而且建议,此种方式使用的锁对象是本类的字节码对象:类名.class

  注意2:加锁时,同步代码块的范围需要考虑, 不能太大,太大效率太低;也不能太小,太小锁不住

  注意3:加锁时,锁对象的类型不做限制,只要保证锁对象唯一即可

同步与异步
异步:是多个线程抢占资源的效果,不排队,所以效率高,但是数据不安全
同步:每次只有一个线程独占资源,排队,所以效率低,但是安全,为了安 全必要应该牺牲一部分资源

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值