20145215《Java程序设计》第八周学习总结

教材学习内容总结

NIO与NIO2

认识NIO

  • NIO使用频道(Channel)来衔接数据节点,在处理数据时,NIO可以设定缓冲区(Buffer)容量,在缓冲区中对感兴趣的数据区块进行标记,像是标记读取位置、数据有效位置,对于这些区块标记,提供了clear()、rewind()、flip()、compact()等高级操作。
  • 例如在10.1.1中看过的dump()方法:
public static void dump(InputStream src,OutputStream dest)throws IOException{
try(InputStream input = src;OutputStream output = dest){
byte[] data = new byte[1024];
int length;
while((length = input.read(data))!=-1){
output.write(data,0,length);
}
}
}

如果使用NIO的话,可以这样写:

public static void dump(ReadableByteChannel src,WritableByteChannel dest)throws IOException{
ByteBuffer buffer = ByteBuffer.allocate(1024);
try(ReadableByteChannel srcCH = src;WritableByteChannel destCH = dest){
while(srcCH.read(buffer)!=-1){
buffer.flip();
destCH.write(buffer);
buffer.clear();
}
}
}
  • Channel继承架构:

想要取得Channel的操作对象,可以使用Channels类,它定义了静态方法newChannel(),可以让你从InputStream、OutputStream分别建立ReadableByteChannel、WritableByteChannel,有些InputStream、OutputStream实例本身也有方法可以取得Channel实例,例如:FileInputSteam、FileOutputStream都有个getChannel()方法可以分别取得FileChannel实例。

  • Buffer继承架构:

  1. Buffer的直接子类们都有个allocate()静态方法,可以让你指定Buffer容量(Capacity),如果想取得Buffer内部的阵列,可以使用array()方法,如果有个数组想要转为某个Buffer子类实例,每个Buffer子类实例都有wrap()静态方法可以提供操作。
  2. Buffer是容器,填装的数据不会超过它的容量,容量大小可以使用capacity()方法取得,实际可读取或写入的数据界限(Limit)索引值可以由limit()方法得知或设定,下一个可读取数据的位置(Position)索引值,可以使用position()方法得知或设定。

NIO2文件系统

  • NIO2文件系统API提供一组标准接口与类,应用程序开发者只要基于这些标准接口与类进行文件系统操作,底层实际如何进行文件系统操作,是由文件系统提供者负责(由厂商操作)。

  • NIO2文件系统的中心是java.nio.file.spi.FileSystemProvider,本身为操作类,是文件系统提供者才要操作的类,作用是产生java.nio.filejava.nio.file.attribute中各种抽象类或接口的操作对象:

  • 应用程式开发者可以通过java.nio.file套件中FileSystems、Paths、Files等类提供的静态方法,取得相关操作对象或进行各种文件系统操作,这些静态方法内部会运用FileSystemProvider来取得所需的操作对象,完成应有的操作。

通用API

日志

  • 日志API简介:
  1. java.util.logging包提供了日志功能相关类与接口,它们是从JDK1.4之后加入标准API,要取得Logger实例,必须使用Logger的静态方法getLogger():
Logger logger = Logger.getLogger("ch08.Main");
  1. 调用getLogger()时,必须指定Logger实例所属名称空间(Name space),名称空间以"."作为层级区分,名称空间层级相同的Logger,其父Logger组态相同。
  2. 取得Logger实例之后,可以使用log()方法输出讯息,输出讯息时可以使用Level的静态成员指定讯息层级(Level)。
  • 指定日志层级:
  1. Logger与Handler预设都会先依Level过滤信息,如果没有做任何修改,取得的Logger实例之父Logger组态,就是Logger.GLOBAL_LOGGER_NAME名称空间Logger实例的组态,这个实例的Level设定为INFO,可通过Logger实例的getParent()取得父Logger实例,可通过getLevel()取得设定的Level实例。
  2. 在经过Logger过滤之后,还得再经过Handler的过滤,一个Logger可以拥有多个Handler,可通过Logger的addHandler()新增Handler实例。
  3. 实际上进行信息输出时,目前Logger的Handler处理完,还会传播给父Logger的所有Handler处理(在通过父Logger层级的情况下)。
  • 如果你不想让父Logger的Handler处理日志,可以调用Logger实例的setUseParentHandlers()设定为false,可以使用Logger实例的setParent()方法指定父Logger。
  • Logger与Handler都有setFilter()方法,可以指定Filter操作对象,如果想让Logger与Handler除了依层级过滤之外,还可以加入额外过滤条件,就可以操作Filter接口:
import java.util.logging;
public interface Filter{
public boolean isLoggable(LogRecord record);
}
  • 可以通过logging.properties来设定Logger组态,启动JVM时,指定java.util.logging.config.file系统属性为.properties名称。

国际化基础

  • 应用程序根据不同地区使用者,呈现不同语言、日期格式等称为本地化(Localization),如果应用程序设计时,可在不修改应用程序情况下,根据不同使用者直接采用不同语言、日期格式等,这样的设计考虑称为国际化(internationalization),简称i18n。
  • 使用ResourceBundle:
  1. 对于日后可能变动的文字信息,可以考虑将信息移至程序之外,使用ResourceBundle来做信息绑定。
  2. .properties文档必须放置在CLASSPATH的路径设定下,文档中撰写的是键/值配对,之后在程序中可以使用键来取得配对。
  3. ResourceBundle的静态getBundle()方法会取得一个ResourceBundle的实例,所给定的自变量名称是信息文档的主文件名,getBundle()会自动找到对应的.properties文档,取得ResourceBundle实例后,可以使用getString()指定键来取得。
  • 使用Locale:
  1. 国际化的三个标准是地区(Locale)信息、资源包(Resource bundle)与基础名称(Base name)。
  2. 地区信息代表了特定的地理、政治或文化区,由一个语言编码(由两个小写字母表示)与可选的地区编码(由两个大写字母表示)来指定。地区信息的对应类是Locale,如Locale locale=new Locale("zh","TW");。
  3. 资源包中包括了特定地区的相关信息。
  4. 代表同一组信息但不同地区的各个资源包会共享相同的基础名称。

规则表示式

  • 规则表示式主要用于字符、字符串格式比较,包含字面意义字符与元字符。字面意义字符是指按照字面意义比较的字符,元字符是不按照字面意义比较,在不同情境有不同意义的字符。元字符就像是程序语言中的控制结构之类的语法,找出并理解元字符想要诠译的概念,对于规则表示式的阅读非常重要。
  • 字面意义字符:
  1. 字母和数字在规则表示式中都是按照字面意义比较的,有些字符之前加上\之后会被当做元字符。
  2. 元字符在规则表示式中有特殊意义,比较标点时可以在每个符号前加上\。
  3. “X或Y”可以用X|Y表示,“X或Y或Z”可以用[XYZ]表示。
  • 字符类:
  1. 规则表示式中,多个字符可以分归在一起,成为一个字符类,会比较文字中是否有任一个字符符合字符类中某个字符。字符类中可以再有字符类。
  2. 归类字符的方式之一是将字符放于[]中。“1到5任意数字出现”表示为[1-5]。
  3. 字符类中可以使用作为字符类元字符,[]则为反字符类。“a、b、c以外的字符”表示为[^abc]。
  • 贪婪、逐步、独吐量词:
  1. {n}是贪婪量词表示法的一种,表示前面的量词出现n次,会尽可能找出长度最长的符合文字。
  2. 在贪婪量词表示法后加上?,将会成为逐步量词,会尽可能找出长度最短的符合文字。
  3. 在贪婪量词表示法后加上+,将会成为独吐量词,没有任何文字符合。
  • 分组与参考:
  1. 可以使用()来将规则表示式分组,除了作为子规则表示式之外,还可以搭配量词使用。
  2. 分组计数是遇到的左括号来计数,如果有个规则表示式((A)(B(C))),其中有四个分组:((A)(B(C)))、(A)、(B(C))、(C)。
  3. 分组回头参考时,是在\后加上分组计数,表示参考第几个分组的比对结果 。\d\d要求比对两个数字,(\d\d)\1的话,表示要输入四个数字,输入的前两个数字与后两个数字必须相同 。
  • 在程序中使用表示式,必须先针对规则表示式做剖析、验证等动作,确定规则表示式语法无误,对字符串进行比较,java.util.regex.Pattern实例是规则表示式在JVM中的代表对象,Pattern的构造函数被标示为private,必须通过Pattern的静态方法compile()来取得。

JDK8 API增强功能

  • String新增join()静态方法可以指定每个字符串间以逗号分隔进行连接。
  • Arrays上新增parallelPrefix()、parallelSetAll()与parallelSort()方法:
  1. parallelPrefix()方法,可以指定xxxBinaryOperator实例,执行类似Stream的reduce()过程。
  2. parallelSetAll()方法,用来对数组进行初始化或全面重设每个索引元素。
  3. parallelSort()方法,可以将指定的数组分为子数组并以平行化方式分别排序,然后再进行合并排序。

教材学习中的问题和解决过程

  • 教材478页倒数第六行代码有错误:书上写的是package java.util.logging;,正确应该是import java.util.logging;,import的作用是导入java.util.logging包的,所以不应该用package。

  • 教材451页NIOUtil.java代码中index.html会自动保存在所建项目的工作目录下,但是打开之后内容好像不太对

  • 教材475页HandlerDemo.java代码中的config.log文件放在用户的根目录下,以我的为例(C:\用户\Think),打开后效果如图所示:

部分模式字符串:

  1. "/" 本地路径名分隔符
  2. "%t" 系统临时目录
  3. "%h" "user.home" 系统属性的值
  4. "%g" 区分循环日志的生成号
  5. "%u" 解决冲突的惟一号码
  6. "%%" 转换为单个百分数符号"%"

代码调试中的问题和解决过程

  • 以下是我编写的Logger测试代码:
package ch08;
import java.util.logging.*; public class LoggerTest {
public static void main(String[] args) {
Logger log = Logger.getLogger("lavasoft" );
log.setLevel(Level.INFO);
Logger log1 = Logger.getLogger("lavasoft" );
System.out.println(log==log1); //true
Logger log2 = Logger.getLogger("lavasoft.blog" );
log2.setLevel(Level.WARNING); log.info("aaa" );
log2.info("bbb" );
log2.fine("fine" );
}
}

它的输出结果是:

当把log2.setLevel(Level.WARNING);这一行注释掉之后,发现输出结果变成了:

这也就更加可以看出logger的名字是有层级关系的。

心得体会

本周虽然学习量相比于前几周不算多,但是我感觉学习的压力却比以往更大,这主要是因为这两章的内容相比之前更不容易理解。有的时候看着看着甚至会觉得有些迷茫,仔细反思了一下自己,或许前面的基础打得还是不够扎实,才让自己现在学起来比较累。经过这两个月以来的学习,我越来越感觉到学习是一个循序渐进的过程,是一个积累的过程,也是考验我们耐心与毅力的最好途径,学习Java是这样,学习其他东西亦是如此。只有将自己的心静下来,才能真正学到知识,否则既花费了时间和精力,到头来还是什么都没得到。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时 编写了Hello Java代码
第一周 100/100 2/2 12/12 编写了Hello Java代码
第二周 200/300 2/4 15/27 理解了printf和println的区别
第三周 450/750 1/5 22/49 对对象有了更深层次的理解
第四周 869/1619 1/6 28/77 对对象的三大特征有了更全面的认识
第五周 1123/2742 1/7 25/102 学会了异常处理
第六周 863/3605 2/9 30/132 理解了线程
第七周 505/4110 2/11 28/160 掌握了日期和时间的运用
第八周 490/4600 2/13 26/186 掌握了git托管的节奏

【附1】本周学习的代码已经成功托管,截图如下:

【附2】利用wc统计代码行数,截图如下:

参考资料

20145215《Java程序设计》第8周学习总结的更多相关文章

  1. 20145213《Java程序设计》第九周学习总结

    20145213<Java程序设计>第九周学习总结 教材学习总结 "五一"假期过得太快,就像龙卷风.没有一点点防备,就与Java博客撞个满怀.在这个普天同庆的节日里,根 ...

  2. 20145213《Java程序设计》第二周学习总结

    20145213<Java程序设计>第二周学习总结 教材学习内容总结 本周娄老师给的任务是学习教材的第三章--基础语法.其实我觉得还蛮轻松的,因为在翻开厚重的书本,一股熟悉的气息扑面而来, ...

  3. 20145213《Java程序设计》第一周学习总结

    20145213<Java程序设计>第一周学习总结 教材学习内容总结 期待了一个寒假,终于见识到了神秘的娄老师和他的Java课.虽说算不上金风玉露一相逢,没有胜却人间无数也是情理之中,但娄 ...

  4. 21045308刘昊阳 《Java程序设计》第九周学习总结

    21045308刘昊阳 <Java程序设计>第九周学习总结 教材学习内容总结 第16章 整合数据库 16.1 JDBC入门 16.1.1 JDBC简介 数据库本身是个独立运行的应用程序 撰 ...

  5. 20145330孙文馨 《Java程序设计》第一周学习总结

    20145330孙文馨 <Java程序设计>第一周学习总结 教材学习内容总结 刚开始拿到这么厚一本书说没有压力是不可能的,开始从头看觉得很陌生进入不了状态,就稍微会有一点焦虑的感觉.于是就 ...

  6. 20145337 《Java程序设计》第九周学习总结

    20145337 <Java程序设计>第九周学习总结 教材学习内容总结 数据库本身是个独立运行的应用程序 撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找 JDBC可以 ...

  7. 20145337 《Java程序设计》第二周学习总结

    20145337 <Java程序设计>第二周学习总结 教材学习内容总结 Java可分基本类型与类类型: 基本类型分整数(short.int.long).字节(byte).浮点数(float ...

  8. 20145218《Java程序设计》第一周学习总结

    20145218 <Java程序设计>第一周学习总结 教材学习内容总结 今天下午看了Java学习的视频,感觉很是新奇,之前觉得Java学起来是艰难枯燥的,但通过第一章的学习觉得如果自己可以 ...

  9. 《Java程序设计》第九周学习总结

    20145224 <Java程序设计>第九周学习总结 第十六章 整合数据库 JDBC入门 ·数据库本身是个独立运行的应用程序 ·撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的 ...

  10. 《Java程序设计》第二周学习总结

    20145224陈颢文<Java程序设计>第二周学习总结 教材学习内容总结 一.类型.变量与运算符 1.类型 整数: 可细分为为short整数(占2字节),int整数(占4字节),long ...

随机推荐

  1. win10中文简体繁体切换快捷键

    win10中文简体繁体切换快捷键Ctrl+Shift+F

  2. nginx服务器中的安全配置

    一.关闭SELinux 安全增强型Linux(SELinux)的是一个Linux内核的功能,它提供支持访问控制的安全政策保护机制. 但是,SELinux带来的附加安全性和使用复杂性上不成比例,性价比不 ...

  3. java微信接口之三—上传多媒体文件

    一.微信上传多媒体接口简介 1.请求:该请求是使用post提交from来实现的,我们可以在网页上进行表单提交来实现.地址为: http://file.api.weixin.qq.com/cgi-bin ...

  4. 仅IE6/7中添加checked为true的input到DOM中为false

    HTML INPUT元素有个checked属性,多数情况type为radio和checkbox. 当创建一个input,checked属性赋值为true,添加到DOM文档中,当再次取checked属性 ...

  5. Python pass语句作用与用法

    Python中的pass语句作用是什么?表示它不做任何事情,一般用做占位语句.pass语句具体作用及使用方法,我们往下看. pass语句在函数中的作用 当你在编写一个程序时,执行语句部分思路还没有完成 ...

  6. php的amqp扩展set导致内存溢出

    最近做的一个项目中需要用到rabbitmq,按照自己的之前的一篇文章http://www.cnblogs.com/mingaixin/archive/2012/10/28/2743807.html进行 ...

  7. linux进程间通信-概述

    一 进程间通信有如下的目的: 1.数据传输,一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几M之间:2.共享数据,多个进程想要操作共享数据,一个进程对数据的修改,其他进程应该立刻看到 ...

  8. Adaboost 卡口车辆检测训练

    之前做了SVM的车脸检测,主要是针对车脸,接下来尝试利用Adaboost和Haar进行车脸的检测.我利用的主要是opencv中的cascade,其已经把Adaboost相关的算法做成了exe,直接调用 ...

  9. 【软件使用】用IntelliJ IDEA开发Android程序图解

    博主这里使用的最新的14.0.3版本,下载地址:http://www.jetbrains.com/idea/, 下载后直接安装就可以了. 环境: OS:Win 8 IDE:IntelliJ IDEA ...

  10. 拓扑排序 codevs 4040 cojs 438

    codevs 4040 EZ系列之奖金  时间限制: 1 s  空间限制: 64000 KB  题目等级 : 钻石 Diamond 题目描述 Description 由于无敌的WRN在2015年世界英 ...