2016-2017-2 《Java程序设计》第七周学习总结

20155313 2016-2017-2 《Java程序设计》第七周学习总结

第十二章 Lambda

12.1认识Lambda语法

12.1.1Lambda语法概览

  • java中引入了Lambda的同时,与现有API维持兼容性是主要考虑之一。
  • 方法参考的特性,在重用现有API上扮演了重要角色。
  • 重用现有方法操做,可避免处处写下Lambda表达式。
  • 方法参考不只避免了重复撰写Lambda表达式,也可让程序代码更清楚。

12.1.2Lambda表达式与函数接口

  • 在只有Lambda表达式的状况下,参数的类型必须写出来,若是有目标类型的话,在编译程序可推断出类型的状况下,就能够不写出Lambda表达式的参数类型。
  • Lambda表达式自己是中性的,不表明任何类型的实例,一样的Lambda表达式,可用来表示不一样目标类型的对象操做。
  • JDK8Lambda并无导入新类型来做为Lambda表达式的类型,而是就现有的interface语法来定义函数接口,做为Lambda表达式的目标类型。
  • 若是接口使用了@FunctionalInterface来标注,而自己并不是函数接口的话,就会引起编译错误。

12.1.3Lambda赶上this与final

  • Lambda表达式并非匿名类的语法蜜糖。
  • Lambda表达式中this的参考对象以及toString()的接受者,是来自Lambda的周围环境,也就是看Lambda表达式是在哪一个名称范畴,就能参考该范畴内的名称,像是变量或方法。
  • JDK中,若是变量自己等效于final局部变量,也就是说,若是变量不会再匿名类中有从新指定的动做,就能够不用加上final关键词。
  • 若是Lambda表达式中捕获的局部变量自己等效于final局部变量,能够不用在局部变量上加上final
  • lambda表达式中不能够改变被捕获的局部变量值。

12.1.4方法与构造函数参考

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

12.1.5接口默认方法

  • 除了参考静态方法做为函数接口操做以外,还能够参考特定对象的实例方法。
  • 函数接口操做也能够参考类上定义的非静态方法,函数接口会试图用第一个参数方法接受者,而以后的参数依次做为被参考的非静态方法的参数

13.1认识时间与日期

13.1.1时间的度量

1.格林威治标准时间(GMT):常被不严谨地当成是UTC时间,现已不做为标准时间使用。html

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

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

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

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

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

13.1.2年历简介

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

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

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

13.1.3认识时区

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

  • 考虑了UTC偏移的时间表示上,一般会标识Z符号。

  • 有些高纬度国家,夏季、冬季日照时间差别很大,实施日光节约时间。

13.2认识Date与Calendar

13.2.1时间轴上瞬间的Date

eg:使用Date实例来取得系统时间描述。
运行结果

13.2.2格式化时间日期的DateFormate

  • DateFormat是个抽象类,其操做类是java.text.SimpleDateFormat,你能够直接构建SimpleDateFormat实例,或是使用DateFormat的getDateInstance()、getTimeInstance()、getDateTimeInstance等静态方法,用较简便方式按不一样需求取得SimpleDateFormat实例。
    eg:如何经过DateFormat的各类静态方法进行格式化。

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

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

13.2.3处理时间日期的Calendar

  • Date如今建议做为时间轴上的瞬间表明,要格式化时间日期则经过DateFormat,若是想要取得某个时间日期信息,或者是对时间日期进行操做,可使用Calendar实例。

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

eg:

Calendar calendar = Calendar.getInstance();

取得Calendar实例后,可使用getTime()取得Data实例,若是想要取得年月日等日期数字时段,可使用get()方法并指定Calendar上的数字段枚举常数。
eg:想取得年、月、日字段。

out.println(calendar.get(Calendar.YEAR));
out.println(calendar.get(Calendar.MONTH));
out.println(calendar.get(Calendar.DATE));

若是你要设定时间日期等字段,不要对Date设定,应该使用Calendar,一样地,月份的部分请使用枚举常数设定。
eg:

Calendar calendar = Calendar.getInstace();
calendar.set(2016,Calendar.APRIL,16);   // 2016/04/16
out.println(calendar.get(Calendar.YEAR));   // 2016  
out.println(calendar.get(Calendar.MOUNTH)); //Calendar.APRIL取值3
out.println(calendar.get(Calendar.DATE));   //16

在取得一个Calendar的实例后,可使用add()方法,来改变Calendar的时间。
eg:

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()方法。
eg:

calendar.roll(Calendar.DATE,1);  //只对日字段加1

想比较两个Calendar的时间日期前后,可使用after()或before()方法。
eg:使用Calendar计算用户的岁数。

13.2.4设定TimeZone

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

Calendar在调用getInstance()时,能够指定Timezone,若是已经取得Calendar实例,也能够经过setTimeZone()方法设定TimeZone。

eg:想知道如今哥本哈根的时间,并指定TimeZone为北京。

13.3JDK8新时间日期API

13.3.1机器时间观点的API

因为台湾时区已经不实施日光节约一段时间了,许多开发者并不知道过去有过日光节约时间,在取得Date实例后,被名称Date误导他们表明日期,因此不该该使用Data实例来得知人类观点的时间信息,Date实例只表明机器观点的时间信息,真正可靠的信息只有内含epoch毫秒数。

同时也可使用Instant的静态方法now()取得表明Java epoch毫秒数的Instant实例。

在新旧API兼容上,若是取得了Date实例,而想要改用Instant,则能够调用Date实例的toInstant()方法来取得,若是你有个Instant实例,可使用Instant的静态方法from()转为Date。

13.3.2人类时间观点的API

1.LocalDateTime、LocalDate和LocalTime

LocalDateTime:包括日期与时间

LocalDate:只有日期,若是设定不存在的日期,会抛出DateTimeException

LocalTime:只有时间

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

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

2.ZonedDateTime、OffsetdateTime

eg:若是你的时间日期须要带有时区,能够基于LocalDateTime、LocalDate、LocalTime等来补充缺乏的信息。

运行结果

3.Year、YearMonth、Month、MonthDay

eg:若是想要取得表明月份的数字,不要使用oridinal()方法,由于oridinal()是enum在定义时的顺序,从0开始,想要取得表明月份的数要经过getValue()方法(调整了格式,使其对齐)。

运行结果

13.3.3对时间的运算

1.TemporalAmount

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

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

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

plus()方法能够接受Duration实例来计算

eg:使用新时间与日期API改写HowOld范例。

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接口的类。


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

问题1:如何用lambda实现集合map的试用?

回答1:

集合的map的方法使用

public class test {  
  
    public static void main(String[] args) {  
  
        List<Integer> list=Arrays.asList(1,4,5);  
          
        list.stream()  
            .map(name->name+1)  
            .forEach(System.out::println);  
    }  
}

问题2:如何用lambda实现集合filter的试用?

回答2:

集合的filter方法使用

public class test {  
  
    public static void main(String[] args) {  
  
        List<Integer> list=Arrays.asList(1,4,5);  
          
        list.stream()  
            .filter(name->name%2==0)  
            .forEach(System.out::println);  
    }  
}

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

问题1:如何使用lambda简化下列排序代码?

String[] players = {"Rafael Nadal", "Novak Djokovic",   
    "Stanislas Wawrinka", "David Ferrer",  
    "Roger Federer", "Andy Murray",  
    "Tomas Berdych", "Juan Martin Del Potro",  
    "Richard Gasquet", "John Isner"};  
   
// 1.1 使用匿名内部类根据 name 排序 players  
Arrays.sort(players, new Comparator<String>() {  
    @Override  
    public int compare(String s1, String s2) {  
        return (s1.compareTo(s2));  
    }  
});

回答1:使用lambdas,能够经过下面的代码实现一样的功能:

// 1.2 使用 lambda expression 排序 players  
Comparator<String> sortByName = (String s1, String s2) -> (s1.compareTo(s2));  
Arrays.sort(players, sortByName);  
  
// 1.3 也能够采用以下形式:  
Arrays.sort(players, (String s1, String s2) -> (s1.compareTo(s2)));

代码托管

  • 代码提交过程截图:
    • 运行 git log --pretty=format:"%h - %an, %cd : %s" 并截图
  • 代码量截图:
    • 运行 find src -name "*.java" | xargs cat | grep -v ^$ | wc -l 并截图


结对及互评

点评过的同窗博客和代码

20155201

20155322

20155236

20155316


学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 50/100 1/2 10/20
第二周 150/200 1/2 20/30
第三周 168/200 1/2 15/20
第四周 300/500 1/2 20/20
第五周 885/1000 1/2 30/30
第六周 1211/1000 1/3 30/30
第七周 597/1000 2/3 30/40

参考资料

《Java学习笔记(第8版)》学习指导

2016-2017-2 《Java程序设计》教学进程

相关文章
相关标签/搜索