20145201 《Java程序设计》第七周学习总结

教材学习内容总结

本周学习了课本第十二、十三章内容,即Lambda、时间与日期

第十二章 Lambda

12.1 认识Lambda语法

12.1.1

  • 如果使用JDK8的话,可以使用Lambda特性去除重复的信息,例:
Comparator<String>byLength =
(String name1,String name2)->name1.length() - name2.length();
  • JDK8提供了方法参考的特性,可以重用byLength方法。

    在java中引入了Lambda的同事,与现有API维持兼容性是主要老驴之一。

    方法参考的特性,在重用现有API上扮演了重要角色,重用现有方法操作,可避免到处写下Lambda表达式。

    方法参考不仅避免了重复撰写Lambda表达式,也可以让程序代码更清楚。

12.1.2

  • lambda表达式中,即使不接受任何参数,也必须写下括号。例如:
() -> "Justin"    //不接受参数,返回字符串
() -> System.out.println() //不接受参数,没有返回值
  • 在只有Lambda表达式的情况下,参数的类型必须写出来,如果有目标类型的话,在编译程序可推断出类型的情况下,就可以不写出Lambda表达式的参数类型。例如以下范例可从Comparator中推断出name1与name2的类型,实际上是String,因而不用写出参数类型:
Comparator<String>byLength = (name1,name2) -> name1.length() - name2.length();
  • Lambda表达式本身是中性的,不代表任何类型的实例,同样的Lambda表达式,可用来表示不同目标类型的对象操作。

  • JDK8的Lambda并没有导入新类型来作为Lambda表达式的类型,而是就现有的interface语法来定义函数接口,作为Lambda表达式的目标类型。

  • Lambda表达式只关心方法签署上的参数与返回定义,但忽略方法名称。

  • 有个新标注 @FunctionalInterface 在JDK8中被引入,它可以这么使用:

@FunctionalInterface
public iterface Func<P,R>{
R apply(P p);
}

如果接口使用了 @FunctionalInterface 来标注,而本身并非函数接口的话,就会引发编译错误.

12.1.3Lambda遇上this与final

  • Lambda表达式并不是匿名类的语法蜜糖。

Lambda表达式中this的参考对象以及toString()的接受者,是来自Lambda的周围环境,也就是看Lambda表达式是在哪个名称范畴,就能参考该范畴内的名称,像是变量或方法。

  • 在JDK中,如果变量本身等效于final局部变量,也就是说,如果变量不会再匿名类中有重新指定的动作,就可以不用加上final关键词。

  • 如果Lambda表达式中捕获的局部变量本身等效于final局部变量,可以不用在局部变量上加上fianl。

  • 在lambda表达式中不可以改变被捕获的局部变量值.

12.1.4方法与构造函数参考

  • Lambda表达式只是定义函数接口操作的一种方式,除此之外,只要静态方法的方法签署中,参数与返回值定义相同,也可以使用静态方法来定义函数接口操作。

    这样的特性在JDK8中成为方法参考,可以避免到处写下Lambda表达式。

    例:
String[] names = {"Justin","caterpillar","Bush"};
Arrays.sort(names,(name1,name2) ->name1.length() - name2.length());

可以写成:

String[] names={"Justin","caterpillar","Bush"};
Arrays.sort(names,StringOrder::byLength};

第十三章 时间与日期

13.1 认识时间与日期

13.1.1时间的度量

1.格林威治标准时间(GMT),现已不作为标准时间使用

2.世界时:在1972年引入UTC之前,GMT与UT是相同的

3.国际原子时(TAI),秒的单位定义是基于TAI,也就是铯原子辐射振动次数。

4.世界协调时间(UTC),UTC考虑了地球自转越来越慢而有闰秒修正,确保UTC与UT相差不会超过0.9秒。

5.Unix时间 不考虑闰秒修正,用以表达时间轴上某一瞬间

6.epoch:某个特定时代的开始,用以表达时间轴上某一瞬间

  • 就目前来说,即使标注为GMT(无论是文件说明,或者是API的日期时间字符串描述),实际上谈到时间指的是UTC时间。

13.1.2

1.儒略历:修正了罗马历隔三年设置一闰年的错误,改采四年一闰。

2.格力高利历:将儒略历1582年10月4号星期四的隔天,订为格里高利历1582年10月15日星期五。

3.ISO 8601标准,采用统一的数据格式例如:yyyy-mm-ddTHHH:MM:SS.SSS等。

13.1.3

  • 每个地区的标准时间各不相同,涉及到地理、法律、经济、社会、政治等问题。

13.2 认识Date与Calendar

如果想要取得系统时间,方法之一是使用System.currentTimeMillis()方法,返回的是long类型整数。

代码如下:

import java.util.*;
import static java.lang.System.*; public class DateDemo {
public static void main(String[] args) {
Date date1 = new Date(currentTimeMillis());
Date date2 = new Date(); out.println(date1.getTime());
out.println(date2.getTime());
}
}

Date有两个构造函数可以使用,一个可使用epoch毫秒数构建,另一个为无自变量构造函数,内部亦是使用System.currentTimeMillis()取得毫秒数,调用getTime()可取得内部保存的epoch毫秒数值。范例执行结果如下:

13.2.2

DateFormat是个抽象类,其操作类是java.text.SimpleDateFormat,你可以直接构建SimpleDateFormat实例,或是使用DateFormat的getDateInstance()、getTimeInstance()、getDateTimeInstance等静态方法,用较简便方式按不同需求取得SimpleDateFormat实例。

  • 通过DateFormat的各种静态方法进行格式化:
import java.util.*;
import static java.lang.System.out;
import static java.text.DateFormat.*; public class DateFormatDemo {
public static void main(String[] args) {
Date date = new Date();
dateInstanceDemo(date);
timeInstanceDemo(date);
dateTimeInstanceDemo(date);
} static void dateInstanceDemo(Date date) {
out.println("getDateInstance() demo");
out.printf("\tSHORT: %s%n", getDateInstance(LONG).format(date));
out.printf("\tSHORT: %s%n", getDateInstance(SHORT).format(date));
} static void timeInstanceDemo(Date date) {
out.println("getTimeInstance() demo");
out.printf("\tLONG: %s%n", getTimeInstance(LONG).format(date));
out.printf("\tMEDIUM: %s%n", getTimeInstance(MEDIUM).format(date));
out.printf("\tSHORT: %s%n",getTimeInstance(SHORT).format(date));
} static void dateTimeInstanceDemo(Date date) {
out.println("getDateTimeInstance() demo");
out.printf("\tLONG: %s%n",
getDateTimeInstance(LONG, LONG).format(date));
out.printf("\tMEDIUM: %s%n",
getDateTimeInstance(SHORT, MEDIUM).format(date));
out.printf("\tSHORT: %s%n",
getDateTimeInstance(SHORT, SHORT).format(date));
}
}

运行结果如下:

  • 直接构建SimpleDateFormat的好处是,可使用模式字符串自定义格式。

    代码如下:
import java.text.*;
import java.util.*; public class CurrentTime {
public static void main(String[] args) {
DateFormat dateFormat = new SimpleDateFormat(
args.length == 0 ? "EE-MM-dd-yyyy" : args[0]);
System.out.println(dateFormat.format(new Date()));
}
}

运行结果如下:

  • SimpleDateFormat有一个parse()方法,可以按构建SimpleDateFormat时指定的格式,将指定的字符串剖析为Date实例,

    代码如下:
import java.util.*;
import java.text.*; public class HowOld {
public static void main(String[] args) throws Exception {
System.out.print("输入出生年月日(yyyy-mm-dd):");
DateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd");
Date birthDate = dateFormat.parse(new Scanner(System.in).nextLine());
Date currentDate = new Date();
long life = currentDate.getTime() - birthDate.getTime();
System.out.println("你今年的岁数为:" +
(life / (365 * 24 * 60 * 60 * 1000L)));
}
}

运行结果如下:

13.2.3

  • Date现在建议作为时间轴上的瞬间代表,要格式化时间日期则通过DateFormat,如果想要取得某个时间日期信息,或者是对时间日期进行操作,可以使用Calendar实例。

Calendar是个抽象类,java.util.GregorianCalendar是其子类,操作了儒略历与格里高利历的混合历,通过Calendar的getInstance()取得的Calendar实例,默认就是取得GregorianCalendar实例。例如:

Calendar calendar = Calendar.getInstance();
  • Calendar是个抽象类,java.util.GregorianCalendar是其子类,操作了儒略历与格里高利历的混合历,通过Calendar的getInstance()取得的Calendar实例,默认就是取得GregorianCalendar实例。如:
out.println(calendar.get(Calendar.YEAR));
out.println(calendar.get(Calendar.MONTH));
out.println(calendar.get(Calendar.DATE));
  • 如果你要设定时间日期等字段,不要对Date设定,应该使用Calendar,同样地,月份的部分请使用枚举常数设定。如:
Calendar calendar = Calendar.getInstace();
calendar.set(2014,Calendar.MAY,26); //2014/5/26
out.println(calendar.get(Calendar.YEAR)); //2014
out.println(calendar.get(Calendar.MOUNTH)); //Calendar.MAY的值4
out.println(calendar.get(Calendar.DATE)); //26
  • 在取得一个Calendar的实例后,可以使用add()方法,来改变Calendar的时间:
calendar.add(Calendar.MONTH,1);  //Calendar时间加1个月
calendar.add(Calendar.HOUR,3); //Calendar时间加3小时
calendar.add(Calendar.YEAR,-2); //Calendar时间减2年
calendar.add(Calendar.DATE,3); //Calendar时间加3天
  • 如果打算只针对日期中某个字段加减,则可以使用roll()方法:
calendar.roll(Calendar.DATE,1);  //只对日字段加1
  • 想比较两个Calendar的时间日期先后,可以使用after()或before()方法

13.2.4设定TimeZone

•使用Calendar时若没有使用时区信息,则会使用默认时区。可以使用java.util.TimeZone的getDefault()来取得默认时区信息。

例如:

import static java.lang.System.out;
import java.util.TimeZone; public class TimeZoneDemo {
public static void main(String[] args) {
TimeZone timeZone = TimeZone.getDefault();
out.println(timeZone.getDisplayName());
out.println("\t时区ID:" + timeZone.getID());
out.println("\t日光节约时数:" + timeZone.getDSTSavings());
out.println("\tUTC 偏移毫秒数:" + timeZone.getRawOffset());
}
}

运行结果为:

13.3 JDK8新时间日期API

13.3.1

  • 由于某一时区已经不实施日光节约一段时间了,许多开发者并不知道过去有过日光节约时间,在取得Date实例后,被名称Date误导他们代表日期,所以不应该使用Data实例来得知人类观点的时间信息。
  • 真正可靠的信息只有内含epoch毫秒数。同时也可以使用Instant的静态方法now()取得代表Java epoch毫秒数的Instant实例。

13.3.2人类时间观点的API

1.LocalDateTime、LocalDate和LocalTime

  • LocalDateTime:包括日期与时间

  • LocalDate:只有日期,如果设定不存在的日期,会抛出DateTimeException

  • LocalTime:只有时间

  • 这些类基于ISO 8601年历系统,是不具时区的时间与日期定义。

对于LocalDateTime.of,由于没有时区信息,程序无从判断这个时间是否不存在,就不会抛出DateTimeException

2.ZonedDateTime、OffsetdateTime

-如果你的时间日期需要带有时区,可以基于LocalDateTime、LocalDate、LocalTime等来补充缺少的信息:

import static java.lang.System.out;
import java.time.*; public class ZonedDateTimeDemo {
public static void main(String[] args) {
LocalTime localTime = LocalTime.of(0, 0, 0);
LocalDate localDate = LocalDate.of(1975, 4, 1);
ZonedDateTime zonedDateTime = ZonedDateTime.of(
localDate, localTime, ZoneId.of("Asia/Taipei")); out.println(zonedDateTime);
out.println(zonedDateTime.toEpochSecond());
out.println(zonedDateTime.toInstant().toEpochMilli());
}
}

运行结果如下:

3.Year、YearMonth、Month、MonthDay

如果想要取得代表月份的数字,不要使用oridinal()方法,因为oridinal()是enum在定义时的顺序,从0开始,想要取得代表月份的数要通过getValue()方法.

代码如下:

import static java.lang.System.out;
import java.time.Month; public class MonthDemo {
public static void main(String[] args) {
for(Month month : Month.values()) {
out.printf("original: %d\tvalue: %d\t%s%n",
month.ordinal(), month.getValue(), month);
}
}
}

运行结果为:

13.3.3对时间的运算

1.TemporalAmount

  • ofPattern()是java.time.format.DateTimeFormatter的静态方法,可以查看API文件了解格式化的方式。

  • 对于时间计量,新时间与日期API以类Duration来定义,可用于计量天、时、分、秒的时间差,精度调整可以达纳秒等级,而秒的最大值可以是long类型可保存值。

  • 对于年、月、星期、日的日期差,使用Period类定义。

  • plus()方法可以接受Duration实例来计算

HowOld范例改写:

import java.time.*;
import java.util.Scanner;
import static java.lang.System.out; public class HowOld2 {
public static void main(String[] args) {
out.print("输入出生年月日(yyyy-mm-dd):");
LocalDate birth = LocalDate.parse(new Scanner(System.in).nextLine());
LocalDate now = LocalDate.now();
Period period = Period.between(birth, now);
out.printf("你活了 %d 年 %d 月 %d 日%n",
period.getYears(), period.getMonths(), period.getDays());
}
}

结果如下:

2.TemporalUnit

  • plus()方法另一重载版本,接受java.time.temporal.TemporalUnit实例,java.time.temporal.ChronoUnit是TemporalUnit实作类,使用enum实作

  • TemporalUnit定义了between()等方法

3.Temporal

相对于plus(),也有两个重载两个重载版本的minus():

  • plus(TemporalAmount amount)

  • plus(long amountToAdd,TemporalUnit unit)

  • minus(TemporalAmount amount)

  • minus(long amountToSubtract,TemporalUnit unit)

4.TemporalAccessor

  • TemporalAccessor定义了只读的时间对象读取操作,实际上Temporal是TemporalAccessor子接口,增加了对时间的处理操作,像是plus()、minus()、with()等方法

13.3.4年历系统设计

  • java.time套件中的类在需要实行年历系统时都是采用单一的ISO8601年历系统。如需要其他年历系统,则需要明确实行java.time.chrono中等操作了java.time.chrono.Chronology接口的类。

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

书p389页代码

package cc.openhome;
import static java.lang.System.out;
class Hello {
Runnable r1 = new Runnable() {
public void run() {
out.println(this);
}
};
Runnable r2 = new Runnable() {
public void run() {
out.println(toString());
}
}; public String toString() {
return "Hello,world!";
}
}
public class ThisDemo {
public static void main(String[] args){
Hello hello=new Hello();
hello.r1.run();
hello.r2.run();
}
}

结果并未显示Hello World!

运行结果

这是因为在这个范例中,this的参考对象以及toString()的接受者,实际上都是匿名类建立的实例,也就是Runnable实例,由于没有定义Runnable的toString(),因而显示的结果是Object默认的toString()返回字符串。

本周代码托管截图

其他(感悟、思考等,可选)

本周学习了第十二十三章,知道了java中时间、日期的历史问题,并应用知识完成了一些数据的统计。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 4500行 30篇 400小时
第一周 200/200 2/2 20/20
第二周 300/500 1/3 18/38
第三周 400/900 1/4 22/60
第四周 1000/1900 1/5 35/95
第五周 800/2700 1/6 30/125
第六周 700/3400 2/8 30/155
第七周 400/3800 2/10 30/185

参考资料

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

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

    20145201 <Java程序设计>第九周学习总结 教材学习内容总结 JDBC是用于执行SQL的解决方案,开发人员使用JDBC的标准接口,数据库厂商则对接口进行操作,开发人员无须接触底层 ...

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

    20145201 <Java程序设计>第二周学习总结 教材学习内容总结 本周学习了课本第三章内容,即JAVA基础语法. 3.1 类型.变量与运算符 基本类型:在java中基本类型主要可区分 ...

  3. 20145201 《Java程序设计》第一周学习总结(修改)

    # 20145201 <Java程序设计>第一周学习总结 ## 教材学习内容总结 万事开头难,终于开始学习了Java.寒假的时候看到老师的要求确实有点慌,但是这周翻开书,从书本知识第一行学 ...

  4. 20145201 《Java程序设计》第一周学习总结

    # 20145201 <Java程序设计>第一周学习总结 ## 教材学习内容总结 万事开头难,终于开始学习了Java.寒假的时候看到老师的要求确实有点慌,但是这周翻开书,从书本知识第一行学 ...

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Mysql数据库存储是乱码问题(或者在查询时无法加载数据)

    在连接数据库时添加一行代码即可解决:?useUnicode=true&characterEncoding=utf8 截图如下:

  2. Web的本质以及第一个Django实例.

       Web框架的本质:    所有的Web应用本质上就是一个socket服务器, 而用户的浏览器就是一个socket客户端. import socket sk = socket.socket() s ...

  3. mvc中使用uploadify批量上传的应用

    网上找了很多资料都没有发现一个好用.可以用的uploadify批量上传的应用,这里通过官方和自己的一些项目需要整理了一个出来. 希望能帮助到需要的人. 效果图:

  4. 《从零开始学Swift》学习笔记(Day 63)——Cocoa Touch设计模式及应用之单例模式

    原创文章,欢迎转载.转载请注明:关东升的博客 什么是设计模式.设计模式是在特定场景下对特定问题的解决方案,这些解决方案是经过反复论证和测试总结出来的.实际上,除了软件设计,设计模式也被广泛应用于其他领 ...

  5. border-radius 原理分析

    border-radius 想必大家都有所了解,比较常见的用法就像下面一样: 注意左边的盒子 border-radius: 100px;  右边的为0哦,所以右边的实际上没有设置圆角边框属性:咱们比较 ...

  6. winsxs清理

    win7的网友经常问:C:Windowswinsxs文件夹下是什么文件,可以删除吗? 答案是不建议你删除的,如果你特别想删除的话我推荐你一个工具. 本人亲测系统正常运行. 可以为C盘剩下将近4G空间 ...

  7. 170306、wamp中的Apache开启gzip压缩提高网站的响应速度

    一个网站的响应速度决定该网站的人气和质量,所以wamp配置的服务器也需要支持giz压缩来提高网站的响应速度,如何开启wamp的gzip压缩呢,经过在网站查找资料结合自己服务器中的配置,现在将这个方法分 ...

  8. 简单工厂模式设计(java反射机制改进)

    如果做开发的工作,工厂设计模式大概都已经深入人心了,比较常见的例子就是在代码中实现数据库操作类,考虑到后期可能会有数据库类型变换或者迁移,一般都会对一个数据库的操作类抽象出来一个接口,然后用工厂去获取 ...

  9. orchestrator-Raft集群部署

    本文简要说明下orchestrator的Raft集群部署,其实部署很简单主要是好好研究下配置文件的配置,这里我的样例配置文件暂时只适用于我们这块业务 如果您自己使用请根据情况自行修改. 主要通过配置文 ...

  10. 巨蟒python全栈开发-第22天 内置常用模块1

    一.今日主要内容 1.简单了解模块 你写的每一个py文件都是一个模块 数据结构(队列,栈(重点)) 还有一些我们一直在使用的模块 buildins 内置模块.print,input random 主要 ...