JavaSE-4进阶流异常日志文件等
概述1
1. 不可变集合(对应python的元组?)
1.1 创建不可变集合——X.of方法
1 2
| List<Double> lists = List.of(569.5, 700.5, 523, 570.4);
|
2. Stream流(重点)
2.1 体会Stream流的方便(一根传送带)
1 2 3 4 5
|
names.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(s -> sout(s))
|
2.2 Stream流的获取(集合、数组获取方式不一样)
maps需要先获取到keySet()这种的,再通过Stream流
2.3 Stream流常用API
还有.count()
等,count和forEach是终结方法
2.4 Stream流的收集操作
使用示例,得到可变集合
简化,但是得到不可变集合
3. 异常处理
python中好像比较简单,就是
1 2 3 4
| try: xxx except: raise NotImplementError("xxxxx")
|
3.1 概述
3.2 常见运行时异常(编译阶段不会报错,运行时可能出现错误)
3.3 常见编译时异常(编译阶段就报错,必须处理否则代码不通过)
3.4 异常的默认处理流程
创建异常对象,层层往上抛给虚拟机
3.5 编译时异常的处理机制
编译阶段就出错的,所以必须处理,否则代码根本无法通过
3.5.1 异常处理方式1 —— throws
- 多个的(但不是全有机会抛出去,只有一个会出去的感觉)
3.5.2 异常处理方式2 —— try… catch…(重点)
1 2 3 4 5
| try { } catch(Exception e) { e.printStackTrace(); }
|
3.5.3 前两种方式结合
抛给上层调用者,然后上层调用者再try,否则不知道哪出问题了
3.6 运行时异常的处理机制
直接用try-catch抛就行,不用写throws
3.7 自定义异常
3.7.1 自定义异常的分类
4. 日志(对jar包的再次接触)
4.1 日志技术的概述
4.1.1 概述
输出语句打印到控制台,太捞了(python中有那个logger.info,写一套模板一直用就行了)
4.1.2 优势
4.2 日志技术体系结构(学习Logback)
4.3 Logback概述
需要下载三个jar包(未来使用maven?)
4.4 Logback快速入门(未来使用maven?项目直接maven导入jar包)
jar包的内部就是一些class文件,编译好的,能直接用
这玩意能在线更新吗,还是说配置文件的修改也需要冷启动系统什么的
xml文件很关键
4.5 Logback配置详解,logback.xml
比如有一些日志文件输出路径这些的,会配置就可以了
4.5.1 热更新xml文件
4.6 日志级别设置
5. File(这个地方可能跳过的内容多一些,未来使用到了再学习)
5.1 自己补充:使用java读取json文件并转化为Map<String, List<String>>
对象
你可以使用 Gson 库来读取 JSON 文件并将其转换为 Map<String, List<String>>
对象。
首先,你需要在项目中添加 Gson 依赖。如果你使用的是 Maven,可以在 pom.xml 中添加如下依赖:
1 2 3 4 5
| <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.6</version> </dependency>
|
然后,你可以使用如下代码来读取 JSON 文件并将其转换为 Map<String, List> 对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import java.io.FileReader; import java.lang.reflect.Type; import java.util.Map;
public class Main { public static void main(String[] args) throws Exception { Gson gson = new Gson(); Type mapType = new TypeToken<Map<String, List<String>>>(){}.getType();
FileReader reader = new FileReader("file.json"); Map<String, List<String>> map = gson.fromJson(reader, mapType);
for (Map.Entry<String, List<String>> entry : map.entrySet()) { String key = entry.getKey(); List<String> value = entry.getValue(); System.out.println(key + ": " + value); } } }
|
上述代码中file.json的示例是什么样的
例如,你可以定义一个名为 file.json 的文件,其内容如下:
1 2 3 4
| { "key1": ["value1", "value2"], "key2": ["value3", "value4"] }
|
在这个例子中,Map 对象的内容为 { “key1” -> [“value1”, “value2”], “key2” -> [“value3”, “value4”] }。
6. IO流(这里也跳过一些内容,未来有用到再学习)
7. 线程概述、线程创建方式一
7.1 概述
7.2 多线程的创建
7.2.1 方式一:继承Thread类(优缺点+注意点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| package com.curious.leetcode;
public class ThreadCreateDemo1 { public static void main(String[] args) { Thread t = new MyThread(); t.start();
for (int i = 0; i < 5; i++) { System.out.println("主线程执行输出: " + i); } } }
class MyThread extends Thread {
@Override public void run() { for (int i = 0; i < 5; i++) { System.out.println("子线程执行输出: " + i); } } }
|
子线程执行输出: 0
主线程执行输出: 0
主线程执行输出: 1
主线程执行输出: 2
主线程执行输出: 3
主线程执行输出: 4
子线程执行输出: 1
子线程执行输出: 2
子线程执行输出: 3
子线程执行输出: 4
7.2.2 方式二:实现Runnable接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| package com.curious.javasepro.d20_thread;
public class ThreadCreateDemo2 { public static void main(String[] args) { Runnable target = new MyRunnable(); Thread t = new Thread(target); t.start();
for (int i = 0; i < 10; i++) { System.out.println("主线程执行输出: " + i); } } }
class MyRunnable implements Runnable {
@Override public void run() { for (int i = 0; i < 10; i++) { System.out.println("子线程执行输出: " + i); } } }
|
扩展性更强,还可以继承
7.2.3 方式二:另外一种写法补充
7.2.4 方式三:JDK5.0新增:实现Callable接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| package com.curious.javasepro.d20_thread;
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask;
public class ThreadCreateDemo3 { public static void main(String[] args) { Callable<String> call = new MyCallalbe(100); FutureTask<String> ft = new FutureTask<>(call); Thread t = new Thread(ft); t.start();
Callable<String> call2 = new MyCallalbe(200); FutureTask<String> ft2 = new FutureTask<>(call2); Thread t2 = new Thread(ft2); t2.sleep(500); t2.start();
try { String res1 = ft.get(); System.out.println("第一个线程的执行结果: " + res1); } catch (Exception e) { e.printStackTrace(); }
try { String res2 = ft2.get(); System.out.println("第二个线程的执行结果: " + res2); } catch (Exception e) { e.printStackTrace(); }
}
}
class MyCallalbe implements Callable<String> {
private int n;
public MyCallalbe(int n) { this.n = n; }
@Override public String call() throws Exception { int sum = 0; for (int i = 0; i < this.n; i++) { sum += i; } return "子线程的执行结果是: " + sum; } }
|
7.3 Thread的常用方法
7.3.1 获取和设置线程名称
7.3.2 构造器
7.3.3 线程休眠方法
7.4 线程安全问题
7.4.1 线程安全问题是什么
7.4.2 线程安全问题模拟案例——取钱
可以if小红,sleep5秒;
7.5 线程同步——解决线程安全问题
共享资源加锁
7.5.1 方式一:同步代码块
小明小红、小黑小白,要使用上不同的锁,这个地方不能是一把锁锁住了千家万户
所以,建议使用共享资源作为锁对象!
小明和小红的Account对象是一个acc,所以这个
7.5.2 方式二:同步方法
只需要在取钱功能上加一个这个就行了
同步方法锁的范围更大,好用的感觉
7.5.3 Lock锁
接口不能构建对象,使用实现类来构建对象Collection那边也是这个说法
在Account对象那块加锁,这样同一个对象就是同一把锁了
为了保证解锁,加finally逻辑
try…finally…
7.6 线程通信(了解)
7.7 线程池(重点)
7.7.1 线程池概述
7.7.2 线程池实现的API、参数说明
7.7.3 线程池处理Runnable任务
线程池可以重复利用,但是如果再加一个变成这样,3个线程处理5个任务
1 2 3 4 5 6
| pool.execute(target); pool.execute(target); pool.execute(target); pool.execute(target); pool.execute(target);
|
7.7.4 线程池处理Callable任务
暂时也跳过,未来开发有接触到进一步使用
7.8 线程的其他内容,未来随着面试进一步学习了
TODO
8. 网络通信TCP/UDP入门
TODO,这个地方也暂时跳过了,未来有接触到再进一步学习