P141 stream流
List<String> names = new ArrayList<>();
Collections.addAll(names, "张第一", "王二", "张第三", "张四");
Stream<String> s = names.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3);
List<String> zhangList = s.collect(Collectors.toList());// 重新转为List
Map<String, String> map = new HashMap<>();
map.put("a", "aaa");
map.put("b", "bbb");
map.put("c", "ccc");
Stream<Map.Entry<String, String>> keyStream= map.keySet().stream();
Stream<Map.Entry<String, String>> valueStream= map.values().stream();
Stream<Map.Entry<String, String>> entryStream= map.entrySet().stream();
// 数组获取流
String[] names2 = {"学生A", "路人B", "XXX"};
Stream<String> stream = Arrays.stream(names2);
P142 异常
异常处理方式1——throws
方法 throws Exception {
}
异常处理方式2——try/catch
try {
}catch(Exception e) {
e.printStackTrace();
}
P147 logback日志框架快速入门
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static final Logger LOGGER = LoggerFactory.getLogger("Test.class");
public static void main(String[] args) throws Exception {
LOGGER.debug("debug");
}
}
更多配置参考
P153 File类
File file = new File("D:\\a.txt");
File file2 = new File("模块名\\a.txt");
P156 字符集
ASCLL:一个字节存储一个字符
GBK:三个字节存储一个中文
unicode:UTF-8以两个字节存储一个中文
P158 (白学)IO流
文件字节输入、输出流 FileInputStream、FileOutputStream
文件字符输入、输出流 FileReader、FileWriter
缓冲流自带8kb缓冲区,提高原始字节流、字符流读写数据的性能
字节缓冲输入、输出流 BufferedInputStream、BufferedOutputStream
字符缓冲输入、输出流 BufferedReader、BufferedWriter
转换流 InputStreamReader、OutputStreamWrite
对象字节输入、输出流 ObjectInputStream、ObjectOutputStream
P165 (白学)代码与文件编码不一致导致乱码问题,转换流解决
InputStreamReader、OutputStreamWriter
FileInputStream fis = new FileInputStream("test.txt");
InputStreamReader isr = new InputStreamReader(fis, "GBK");
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
FileOutputStream fos = new FileOutputStream("test.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");
BufferedWriter bw = new BufferedWriter(osw);
bw.write("这是中文");
bw.close();
P166 对象序列化、反序列化
ObjectOutputStream、ObjectInputStream
被序列化的对象,属性增加修饰符transient,可以忽略使此属性在序列化后为null(常用于敏感信息)
被序列化的对象,必须实现接口Serializable
// 序列化
Book book = new Book("name");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("test.txt"));
objectOutputStream.writeObject(book);
objectOutputStream.close();
// 反序列化
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("test.txt"));
Object o = objectInputStream.readObject();
objectInputStream.close();
System.out.println(o);
P167 打印流、Properties、commons-io框架
打印流:PrintStream(字节)、PrintWriter(字符)
PrintStream printStream = new PrintStream("test.txt");
printStream.println("test");
printStream.flush();
改变输出语句的位置到文件
PrintStream ps = new PrintStream("log.txt");
System.setOut(ps);
System.out.println("test"); // 现在不会输出到console,会出现在log.txt文件中
Properties类
Properties properties = new Properties();
properties.setProperty("key1", "value1");
properties.store(new FileWriter("user.properties"), "备注信息");
commons-io框架(推荐使用)
P168 多线程
实现方案 | 继承Thread类 | 实现Runnable接口 | 实现Callable接口 |
步骤 |
|
|
|
优点 | 编码简单 可直接使用Thread类的方法 | 可以继续继承类和实现接口 | 可以继续继承类和实现接口 能得到执行结果 |
缺点 | 无法再继承其他类 无法返回结果 | 编程相对复杂 无法返回结果 | 编码复杂 |
// 方法一:继承Thread类
Thread t = new MyThread();
t.start();
// 方法二:实现Runnable接口
Runnable target = new MyRunnable();
Thread t = new Thread(target);
t.start();
// 方法三:实现Callable接口
Callable<String> call = new MyCallable();
FutureTask<String f1 = new FutureTask(call);
Thread t1 = new Thread(f1);
t1.start();
try {
String res = f1.get();// 得到结果
} catch (Exception e) {
e.printStackTracs();
}
线程同步:同步代码块、同步方法、Lock锁
同步代码块
锁对象的规范要求
- 建议使用共享资源作为锁对象
- 对于实例方法建议使用this作为锁对象
- 对于静态方法建议使用字节码(类名.class)作为锁对象
// 同步代码块
synchronize(同步锁对象) {
操作共享资源的代码
}
public void drawMoney(double money) {
String name = Thread.currentThread().getName();
synchronized(共享资源对象) {
// 取钱操作
}
}
同步方法
public synchronized void drawMoney(double money) {
String name = Thread.currentThread().getName();
// 取钱操作
}
Lock锁
private final Lock lock = new ReentrantLock();
public void drawMoney(double money) {
lock.lock();
try{
// do something
} finally() {
lock.unlock();
}
}
线程池
方式一:使用ExecutorService的实现类ThreadPoolExecutor创建一个线程池对象
方式二(不推荐):使用Executors(线程池的工具类)调用方法返回不同特点的线程池对象
public ThreadPoolExecutor(
int corePoolSize, // 核心线程数
int maximumPoolSize, // 可支持最大线程数(最大线程数 - 核心线程数 = 临时线程数)
long keepAliveTime, // 临时线程最大存户时间
TimeUnit unit, // 存活时间的单位
BlockingQueue<Runnable> workQueue, // 任务队列
ThreadFactory threadFactory, // 指定用哪个线程工厂创建线程
RejectedExecutionHandler handler // 线程忙,任务满时,处理规则
)
ExecutorService pool = new ThreadPoolExecutor(3, 5, 6, TimeUnit.SECOND, new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
// 处理Runnable任务
Runnable target = new MyRunnable();
pool.execute(target);
pool.execute(target);
pool.execute(target);
pool.execute(target);
// 处理Callable任务
Future<String> f1 = pool.submit(new MyCallable());
Future<String> f2 = pool.submit(new MyCallable());
Future<String> f3 = pool.submit(new MyCallable());
System.out.println(f1.get());
System.out.println(f2.get());
System.out.println(f3.get());
临时线程什么时候创建?
新任务提交时发现核心线程都在忙,任务队列也满了,并且还可以创建临时相册,此时才会创建
什么时候会拒绝任务?
核心线程和临时线程都在忙,任务队列也满了,新的任务过来会开始拒绝