20145333 《Java程序设计》第8周学习总结
教材学习内容总结
NIO和NIO2
NIO的定义
InputStream、OutputStream的输入输出,基本上是以字节为单位进行低层次处理,虽然需要直接面对数组,但实际上多半是对字节数组中整个区块进行处理。dump()方法是整块数据读入后又整块数据写出。NIO2的定义
现今世界上存在着各式各样的文件系统,不同的文件系统会提供不同的存取方式,文件属性,权限控制等操作。在JDK7出现以前,常需要对特定的文件撰写特定的程序,不仅撰写方式没有标准,针对特定功能撰写的程序也会增加应用程序开发者的负担。
NIO2文件系统API提供一组标准类接口与类,应用程序开发者只要基于这些标准接口与类进行文件系统操作,底层实际如何进行文件系统的操作,是由文件系统提供者负责。
通用API
- 日志API简介
使用日志的起点是logger类,logger实例的创建有许多要处理的要素,必须使用logger的静态方法getLogger().
通常在哪个类上取得的logger,名称空间就会命名为哪个类的全名,使用getName()就可以取得类全名,输出信息时可以使用静态成员指定信息层级。
Logger是起点,必须先通过Logger的Level与Filter过滤,再通过Handler的Level与Filter过滤,格式化信息的动作交给Formatter,输出信息的动作实际上是Handler负者。
Logger处理完自己的日志动作后,会向父Logger传播。
- 指定日志层级
取得的Logger实例之父Logger组态,就是Logger.GLOBAL_LOGGER_NAME名称空间Logger实例,可通过getParent()取得设定的Logger实例,可通过getLevel()取得设定的Level实例。
Logger的信息处理会往父Logger传播,在没有做任何组态设定的情况下,默认取得的Logger实例,层级必须大于或等于Logger.GLOBAL_LOGGER_NAME名称空间Logger实例设定的Lever.INFO,才有可能输出信息。
可以通过setLevel()设定Level实例,若log()时指定的Lever实例内含的int值小于Logger设定的Level实例内含的int值,Level就不会记录信息。
在经过Logger过滤之后,还得再经过Handler的过滤,一个Logger可以拥有多个Handler,可通过Logger的addHandler()新增Handler实例。实际上进行信息输出时,目前Logger的Handler处理完,还会传播给父Logger的所有Handler处理,可通过getHandlers()方法取得目前已有的Handler实例数组。
- 使用Handler与Formatter
标准API提供了几个操作类:MemoryHandler不会格式化日志信息,信息会暂存于内存缓冲区,直至超过大小才将信息输出至指定的目标Handler。
StreamHandler可自行指定信息输出时使用的OutputStream。
ConsoleHandler创建时,会自动指定OutputStream为System.err。
SocketHandler创建时可以指定主机位置与端口。
在建立FileHandler指定模式字符串时,可以使用“%h”来表示用户的根目录,还可以使用“%t”取得系统暂存目录,或者使用“%g”自动为文档编号。
- 自定义Handler、Formatter与Filter
handler是负责输出,Formatter负责格式化,而信息过滤是由Filter。
自定义Formatter,可以继承Formatter后操作抽象方法format(),这个方法会传入logRecord,储存所有日志信息。
- 使用logging.properties
可以通过logging.properties改变Logger组态。
国际化基础
- 使用ResourceBundle
对于日后可能变动的文字信息,可以考虑将信息移至程序之外,方法是使用ResourceBundle来做信息绑定。
准备一个.properties文档,如messages.properties,文档内容如下:
cc.openhome.welcome=Hello
cc.openhome.name=World
import static java.lang.System.out;
import java.util.ResourceBundle;
public class Hello {
public static void main(String[] args) {
ResourceBundle res = ResourceBundle.getBundle("messages");
out.print(res.getString("cc.openhome.welcome") + "!");
out.println(res.getString("cc.openhome.name") + "!");
}
}
以后想改变显示的信息,只要改变.properties文档的内容就可以了。
ResourceBundle的静态getBundle()方法会取得一个ResourceBundle实例,所给定的自变量名称是信息文档的主文件名。
- 使用Locale
使用ResourceBundle时,如何根据基础名称取得对应的信息文档:
(1)使用指定的Locale对象取得信息文档
(2)使用Locale.getDefault()取得的对象取得信息文档
(3)使用基础名称取得信息文档
- 规则表达式
字面意义字符是指按照字面意义比较的字符。
元字符时不按照字面比较,在不同情境有不同意义的字符。
java.util.regex.Pattern实例是规则表达式在JVM中的代表对象,Pattern的构造函数被标示为private,通过Pattern的静态方法compile()来取得。Pattern.compole()方法的另一版本,可以指定旗标(Flag)。
在取得Pattern实例后,可使用方法:
split()方法:将指定字符串依规则表达式切割
matcher()方法:指定要比较的字符串
find()方法:看看是不是有下一个符合字符串
lookingAt():看看字符串开头是否符合规则表达式
group():可以返回符合的字符串。
在取得Matcher实例后,可使用方法:
replaceAll()可以将符合规则表达式的部分以指定的字符串取代
replaceFirst()取代首个组合规则表达式的部分
replaceEnd()取代最后符合规则表达式的部分
start()方法可以取得符合字符串的初始索引
end()方法可以取得符合字符串最后一个字符后的索引
- JDK8 API增强功能
StringJoiner、Arrays新增API
1.String.join()、StringJoiner
String新增join()静态方法可以指定每个字符串间以逗号分隔进行连接。
2.Arrays
Arrays上新增parallelPrefix()、parallelSetAll()与parallelSort()方法,parallelSort()方法,可以将指定的数组分为子数组并以平行化方式分别排序,然后再进行合并排序。指定的数组之元素必须操作`Comparable。
Stream相关API
Files上有lines()、list()、walk()等方法。
Stream、InStream、DoubleStream等都有of()静态方法,可以使用可变长度自变量方式指定元素。
本周代码托管截图
其他(感悟、思考等,可选)
这周的学习目标主要是第十五章,需要我们学会使用日志API、了解国际化基础、认识JDK8增强功能等。通过前面几周的学习,java的核心知识与难点之前都已经学完了,后面的章节大概都是介绍一些类的应用。在不断的学习中,我也在不断的寻找适合自己的学习方法。平时自己要主动敲代码,主动发现问题,提高学习效率。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 3500行 | 15篇 | 400小时 | |
第一周 | 100/100 | 2/2 | 20/20 | |
第二周 | 150/250 | 1/3 | 18/38 | |
第三周 | 100/350 | 1/4 | 22/60 | |
第四周 | 300/650 | 1/5 | 30/90 | |
第五周 | 100/750 | 1/6 | 20/110 | |
第六周 | 350/1100 | 1/7 | 25/135 | |
第七周 | 250/1350 | 1/8 | 25/160 | |
第八周 | 250/1600 | 1/9 | 25/185 |