【Java】从入门到放弃-05:高级语法
1、流 stream
1)Java 中 stream 和 C++ 中的 stream完全不一样:
- java stream:用来处理容器中的数据,以流水线式的操作方式处理内存中的数据,包括过滤、筛选等,和SQL语句功能类似;
- C++ stream:是 C++ 标准库中用于输入 / 输出(I/O)操作的抽象
2)数据处理 有点像视频处理框架 GStreamer 对媒体数据的处理流程,有中间处理(GStreamer的过滤组件)和终端处理(GStreamer的槽)
- 中间处理:每次处理后,返回值是新的流,可以继续直接调用下一个处理方法,实现链式调用,常用的有
- filter:过滤,list.stream().filter(s -> s.length() > 3) // 保留长度>3的字符串
- map:映射,list.stream().map(String::toUpperCase) // 字符串转大写
- sorted:排序,list.stream().sorted(String.CASE_INSENSITIVE_ORDER) // 忽略大小写排序
- distinct:去重:
- 终端处理:返回值不是流,因此后续无法再继续调用其他的流方法,位于流的末端(终端)
- collect:收集结果,转为新的容器(Java中好像喜欢称为集合)
List result = list.stream().filter(s -> s.startsWith(“a”)).collect(Collectors.toList()); - count:计数,返回元素的数量
long count = list.stream().filter(s -> s.length() > 5).count(); - forEach:遍历每个元素
list.stream().forEach(System.out::println); // 打印所有元素 - 聚合:max(Comparator c)、min(Comparator c)、reduce(…) —— 求最大 / 小值或自定义聚合
- collect:收集结果,转为新的容器(Java中好像喜欢称为集合)
3)完整示例
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;public class StreamExample {public static void main(String[] args) {List<String> words = Arrays.asList("apple", "banana", "cat", "date", "apple");# 需求:筛选长度>3的单词,去重,转大写,收集为列表List<String> result = words.stream().filter(word -> word.length() > 3) # 中间操作:筛选.distinct() # 中间操作:去重.map(String::toUpperCase) # 中间操作:转大写.collect(Collectors.toList()); # 终端操作:收集结果System.out.println(result); # 输出:[APPLE, BANANA, DATE]}
}
2、IO
Java Stream 是针对内存的操作;
Java IO 则是针对外设的操作,比如:磁盘读写、键盘输入和显示器输出等
1)字节输入流抽象类:InputStream
- read:读取下一个字节,返回取值为0~255的int型数据
- read(byte[] b):读取一定长度的字节
- mark(int readlimit):在输入流的当前位置放置一个标记
- reset:返回当前所做的标记处
- markSupported():返回是否支持 mark 和 reset 标记
- skip(long n):跳过n个字节
- close:关闭流,释放资源
2)字符(Unicode编码,两个字节)输入流抽象类:Reader
3)字节输出流抽象类:OutputStream
- write(int b):写入单个字节,b的取值为0~255
- write(byte[] b):写入多个字节
- wirte(byte[] b, int off, int len):从偏移量 off 开始写入 len 个字节
- flush:刷新输出,清空缓冲区
- close:关闭流
4)字符(Unicode编码,两个字节)输出流抽象类:Writer
5)File:文件类
- 构造函数创建:File(String path) 等
- getName:获取文件名称
- canRead:文件是否可读
- canWrite:文件是否可写
- exites:文件是否存在
- length:文件的长度
- getAbsolutePath:获取文件绝对路径
6)以字节形式读写文件:FileInputSteam、FileOutputStream
7)以字符形式读写文本:FileReader、FileWriter(Unicode编码,两个字节)
8)待缓冲区的读写:BufferedInputStream、BufferedOuputStream、BufferedReader、BufferedWriter
9)读写各种数据,例如:字符串、double、int、boolean、UTF编码字符等:DataInputStream、DataOutputStream
10)序列化和反序列化:ObjectOutputStream(系列化一个对象)、ObjectInputSteam(反序列化一个对象)
3、反射与注解
1)Java 可以通过反射机制,动态获取类的信息(如类名、方法、字段等),并动态调用类的方法、操作字段,而无需在编译期知道类的具体信息。
C++中没有内置反射机制;
2)通过反射可以访问:
- 包路径:getPackage
- 类名称:getName
- 继承类:getSuperclass
- 接口:getInterfaces
- 构造方法:
- getConstructor:指定构造方法,Constructor对象(public构造方法)
- getConstructors:Constructor数组(public构造方法)
- getDeclaredConstructor:指定构造方法,Constructor对象(所有构造方法)
- getDeclaredConstructors:Constructor对象(所有构造方法)
- 方法:
- getMethod:指定方法,Method 对象(public方法)
- getMethods:Method 数组(public方法)
- getDeclaredMethod:指定方法,Method 对象(所有的方法)
- getDeclaredMethods:Method 数组(所有的方法)
- 成员变量
- getField:指定成员变量,Field 对象(public)
- getFields:Field 数组(public)
- getDeclaredField:指定成员变量,Field 对象(所有)
- getDeclaredFields:Field 数组(所有)
- 内部类
- getClasses:public 内部类 Class 数组
- getDeclaredClasses :所有内部类 Class 数组
- 内部类的声明类
- getDeclaringClass:如果是内部类,返回它的成员类,否则返回null
3)反射相关类
- Constructor:构造
- Modifier:方法
- Field:成员变量
4)Annotation 注解
Java 的注解 Annotation 为一种元数据机制,为代码(类、方法、字段、参数等)添加额外信息;
常用注解
注解 | 作用 | 适用范围 |
---|---|---|
@Override | 标记方法必须重写父类的方法,编译期检查是否正确重写(如方法名、参数是否匹配)。 | 方法 |
@Deprecated | 标记类、方法、字段等已过时,使用时编译器会警告。 | 类、方法、字段、参数等 |
@SuppressWarnings | 抑制编译器警告(如未使用变量、 unchecked 类型转换的警告)。需指定警告类型(如 unchecked、deprecation)。 | 类、方法、字段、参数等 |
@FunctionalInterface | 标记接口为函数式接口(仅含一个抽象方法),编译期检查是否符合规范(Java 8+)。 | 接口 |
@SafeVarargs | 断言可变参数的使用是安全的,抑制 unchecked 警告(Java 7+)。 | 构造器、方法(静态或 final) |
@Target | 指定注解可修饰的元素类型(如类、方法、字段等),取值来自 ElementType 枚举(如 TYPE、METHOD、FIELD)。 | |
@Retention | 指定注解的生命周期(保留到哪个阶段),取值来自 RetentionPolicy 枚举:SOURCE:仅保留在源码,编译后丢弃(如 @Override)。 CLASS:保留到字节码,运行时不加载(默认)。 RUNTIME:保留到运行时,可通过反射读取(如框架常用的注解)。 | |
@Documented | 标记注解会被 Javadoc 工具提取到文档中。 | |
@Inherited | 标记注解可被子类继承(即父类的注解会被子类继承)。 | |
@Repeatable | 允许注解在同一元素上重复使用(Java 8+),需指定一个容器注解。 |
4、数据库操作
1)Java 中将操作SQL语句的 API 称为:JDBC,主要功能为
- 与 数据库建立连接
- 向 数据库发送SQL语句
- 从 数据库中获取结果
2)常用类和接口
- DriverManager:管理数据库驱动程序
- Connection:连接数据库
- Statement:向数据库中发送SQL语句
- PrepaerdStatement:动态地执行SQL
- ResultSet:保存数据库查询结果(一个表格)
5、多线程
1)两种实现线程的方法:
- 继承:java.lang.Thread 重写 run 方法,调用 start 方法来启动
- 实现:java.lang.Runnable 接口,创建 Thread 对象,调用 start 来启动
- 实现:Callable 接口,重写 call 方法,调用 start 来启动
2)线程生命周期
- 出生状态:创建时,new Thread
- 就绪状态:调用 start 后
- 运行状态:根据系统的资源,自动进入运行状态
- 等待状态:调用 wait 之后
- 休眠状态:调用 sleep 之后
- 阻塞状态:调用 notify、notifyAll之后
- 死亡状态:调用 interrupt
3)线程同步
- 同步块(类似C++临界区):synchronized(Object)
- 同步方法:synchronized void f(){}
6、并发
- 串行:顺序执行,一个线程被CPU执行完毕后,再执行另外一个;
- 并行:多个CPU同时执行多个线程;
- 并发:实际为穿插执行,不同时间段执行不同的线程,看上去像是“同时”在执行
- yield:很谦让,自己放弃CPU时间段,系统会考虑这个建议,单不一定接收这个建议
- 注意避免死锁
- 守护线程:比如 Java 的垃圾回收线程,注意:和 Linux 的守护线程有区别
- 用户线程:JVM虚拟机调用的 main 函数
- 线程本地变量:ThreadLocal,为每个使用该变量的线程,提供变量副本
- set:设置 ThreadLocal 变量
- get:获取 ThreadLocal 变量
- remove:清除 ThreadLocal 变量中的值
- wait:阻塞当前线程,并释放锁,等待其它线程调用 notify 或者 notifyAll
- notify:唤醒正在等待的线程
- notify:唤醒全部正在等待的线程
- 线程池:ThreadPoolExecutor
7、网络通讯
1)TCP、IP、UDP
- InetAddress:与 IP 地址相关,比如:获取IP地址、主机地址等信息
- ServerSocket:TCO 服务器套接字
- Socket:TCP 客户端
- DatagramSocket:UDP 套接字
- DatagramPacket:数据包
2)NIO:同步非阻塞网络编程
- Buffer:缓冲区,可以写入数据的内存块
- Channel:通道,单向的,非阻塞
- SocketChannel:建立TCP网络连接
- SeriverSocketChannel:监听新建的 TCP 连接通道
- Selector:选择器,检查NIO通道,确定哪些通道已准备好读或者写
3)AIO:异步非阻塞网络编程
8、Swing 和 绘图
略,本人只打算使用 Java 开发 web 项目