20145230 《Java程序设计》第7周学习总结
教材学习内容
Lambda语法概览
我们在许多地方都会有按字符串长度排序的需求,如果在同一个方法内,我们可以使用一个byName局部变量.如果是一个类中多个方法间要共享,那就使用一个byName的数据成员。因为byName要参考的实例没有状态问题,因为声明为static比较适合,如果要在多个类之间共享,那么就设定为public static。类似地,相对名称按照字典顺序排序,但忽略大小写差异,也不用再通过StringOrder的static方法了,只需要直接参考String的compareToIgnoreCase()方法。方法参考不仅避免了重复撰写Lambda表达式,也可以让程序代码更为清楚。
Lambda表达式与函数接口
在只有Lambda表达式的情况下,参数的类型必须写出来,如果有目标类型的话,在编译程序可推断出类型的情况下,就可以不写出Lambda表达式的参数类型。Lambda表达式本身是中性的,不代表任何类型的实例,同样的Lambda表达式,可用来表示不同目标类型的对象操作。JDK8的Lambda并没有导入新类型来作为Lambda表达式的类型,而是就现有的interface语法来定义函数接口,作为Lambda表达式的目标类型。
使用Optional取代null
由于含糊而不明确,要避免使用null的方式,就是确认使用null的时机与目的,并使用明确的语义。在过去使用null的请框中,开发者在方法中返回null,通常代表着客户端必须检查是否为null,并在null的情况下使用默认值,以便后续程序继续执行。
比准API的函数接口
Lambda表达式实际的类型要看函数接口而定,虽然可以自行定义函数接口,只不过对于几种常用的函数接口行为,JDK8已结定义了几个通用的函数接口,我们可以基于这些通用函数接口来撰写程序,在必要时再考虑自定义函数接口,JDK8定义的通用函数接口,基本上放置于java.util.function套件之中,就行为来说,可以分为Consumer,Function,Predicate,Supplier四个类型。
Lambda与并行处理
Collectors有groupingBy()与groupingByConcurrent()两个方法,前者代表循序处理,后者代表并行处理,是否调用后者,我们得思考处理过程是否能够分而治之而后合并结果,如果可能,才能从中收益。在collect()操作时若想要有平行效果,必须符合以下三个条件:1. Stream必须有并行处理能力
2.Collector必须有Collector.Characteristics.CONCURRENT特性 3.Stream是无序的(Unordered)或者是Collector具有Collector.Characteristics.UNORDERED特性
使用CompletableFuture
我们要异步(Asyncronous)读取文本文件,在文档读取完后做某些事,可以使用ExecutorService来submit()一个Runnable对象。CompletableFuture的静态方法supplyAsynv()接受Suppiier实例,可指定异步执行任务,它会返回CompletableFuture实例,可以调用whenComplete()以BiConsumer实例指定任务完成如何处理,第一个参数是Suppiier的返回值,若有例外发生则会指定给第二个参数,想要在任务完成后继续异步处理,则可以使用henCompleteAsynv()方法。
时间的度量
1.格林威治标准时间:格林威治标准时间简称GMT时间,一开始是参考自格林威治皇家天文台的标准太阳时间,格林威治标准时间的正午是太阳抵达天空最高点之时,格林威治标准时间常被不严谨的当成是UTC时间。 2.世界时:世界时是借由观测远方星体跨过子午线而得,也称UT,这会比观察太阳来得准确一些。1972年引入UTC之前,GMT与UT是相同的。 3.国际原子时:虽然观察远方星体会比观察太阳来得准确,不过UT基本上仍受地球自转速度影响而会有所误差。1967年定义的国际原子时(TAI),将秒的国际单位定义为铯原子辐射振动9192631770周耗费的时间,时间从UT的1958年开始同步。 4.世界协调时间:由于基于铯原子振动定义的秒长是固定的,然而地球自转会越来越慢,这会使得实际上 TAI时间会不断超前基于地球自转的UT系列时间,为了保持TAI与UT时间不要差距过大,因而提出了具有折衷修正版本的世界协调时间(UTC)。 5.Unix时间:Unix系统的时间表示法,定义为UTC时间1970年1月1日00:00:00为起点而经过的秒数,不考虑闰秒修正,用以表达时间轴上某一瞬间。 6.epoch:某个特定时代的开始,时间轴上某一瞬间。例如java.util.Date封装的时间信息,就是January 1,1970,00:00:00 GMT经过的毫秒数,可以简称为epoch毫秒数。
年历简历
儒略历是现今公历的前身,用来取代罗马历。儒略历修正了罗马历隔三年设置一闰年的错误,改采四年一润。格里高利历改革了儒略历,将儒略历1582年10月4日星期四的隔天,定为格里高利历1582年10月15日星期五。在一些相对来说较新的时间日期API应用场合中,你可能会看到ISO 8601,严格来说ISO 8601并非年历系统,而是时间日期表示方法的标准,用以统一时间日期的数据交换格式,ISO 8601在数据定义上大部分与格里高利历相同,不过还是有微小差别。
认识时区
从地理上来说,由于地球是圆的,基本上一边白天另一边就是夜晚,为了让人们对时间的认知符合作息,因而设置了UTC偏移,大致上来说,经度每15度是偏移一个小时,考虑了UTC偏移的时间表示上,通常会标识Z符号。不过有些国家的领土横跨的经度很大,一个国家有多个时间反而造成困扰,因而不采取每15度偏移一小时的做法,像美国仅有4个时区,而中国,印度只采用单一时区。
认识Date与Calendar
Date有两个构造函数可以使用,一个可使用epoch毫秒数构建,另一个为无自变量构造函数,内部亦是使用System.currentTimeMillis()取得epoch毫秒数,调用getTime()可取得内部保存的epoch毫秒数值。getTime()之外的getXXX()方法都废弃了,setTime()之外的setXXX()方法也都废弃了。Date实例基本上建议只用来当作时间轴上的某一瞬间,也就是1970年1月1日0时0分0秒至今经过的毫秒数,其他对时间日期字段的设定与取得,建议通过Calendar来执行。有关字符串时间格式的处理,职责落到了java.text.DateFormat身上,DateFormat是个抽象类,其操作类是java.text.SimpleDateFormat,你可以直接构建SimpleDateFormat实例,或是使用DateFormat的getDateInstance()、getTimeInstance()、getDateTimeInstance()等静态方法。
对时间的运算
LocalDate的plusMonths(),plusDays(),plusWeeks()知识时间运算时一些常用的指定方法,当然,时间允许按的需求很多,不可能列出全部的plusxxx()方法,对于时间计量,新时间与日期API以类Duration来定义,可用于计量天、使、分、秒的时间差,精度调整可以达纳秒等级,而秒的最大值可以是long类型可保存值。对于年、月、星期、日的日期差,则使用Period类定义。
教材学习中的问题和解决过程
在学习第十二章的时候遇到了这样一个问题:声明bylength时已经写了一次Comparator,为什么操作匿名类时又得写一次Comparator?我通过看书,然后有些看不懂的地方询问了同学大概知道了是因为:在使用Lambda表达式时,实际上从等号左边的Comparator的compare()的方法。编译程序可以从byLength变量的声明类型,推断name1与name2的类型。
本周代码托管截图
其他(感悟、思考等,可选)
又是一周的java学习,自己的体会就是很累,因为每次自己总会拖到最后期限才来完成java的全部任务,一周的任务量全部堆到一天时间来做,不累才怪。但自己真的很矛盾,感觉对java有点害怕的感觉,感觉能不碰它尽量不碰它,直到迫不得已了才会去面对那一本厚重的书,书中的内容感觉不是我的和蔼可亲的朋友,而是一行行冰冷的文字,让自己麻木。但我知道一定是自己的问题,自己还没有找到学习方法,还没有走上正确的道路,自己的态度还没有端正。所以自己很纠结,哎,希望能尽快调整好自己的状态吧!
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 2000 行 | 25篇 | 400小时 | |
第一周 | 100/100 | 2/2 | 20/20 | |
第二周 | 100/200 | 2/4 | 20/40 | |
第三周 | 50/250 | 1/5 | 20/60 | |
第四周 | 564/814 | 2/7 | 30/90 | |
第五周 | 623/1437 | 1/8 | 30/120 | 了解到了程序中的异常处理 |
第六周 | 2/9 | 30/120 | 了解到了java的输入与输出 | |
第七周 | 425/1872 | 2/11 | 20/140 | 了解到了Lambda语法与java中的日期与时间 |