20155331 2016-2017-2 《Java程序设计》第七周学习总结
教材学习内容总结
一、认识Lambda语法
1.Lambda语法概览
Arrays的sort()方法可以用来排序,只不过你要告诉它两个元素比较时顺序是什么,sort()规定你得操作java.util.Comparator来说明这件事,我们可以通过byLength()来让排序的意图更清楚,只是操作Comparator时的匿名类时依旧冗长,有太多重复信息,如果使用JDK8的话,你可以使用Lambda特性去除重复的信息。Lambda不只是匿名类的语法蜜糖,目前先集中介绍其重复性的去除和可读性的改善。如果你在许多地方都会有按字符串长度排序的需求,你会怎么做?如果是同一个方法内,我打算用一个byName局部变量,如果是类中多个方法间要共享,那就用一个byName的数据成员吧!因为byName要参考的实例没有状态问题,因而声明为static比较合适,如果要在多个类之间共享,那么就设定为public static。JDK8提供了方法参考的特性,在Java中引入Lambda的同时,与现有API维持兼容性是主要考虑之一,方法参考的特性在重用现有API上扮演了重要角色,重用现有操作可避免到处写下Lambda表达式,不仅如此,也会让程序代码更为清楚。
2.Lambda表达式与函数接口
一个Lambda表达式可以拆为两部分,等号右边是Lambda表达式,等号左边是作为Lambda表达式的目标类型。区块可以由数个描述句组成,不过基本上不建议如此使用,在使用Lambda表达式时,尽量使用简单的表达式会比较好,如果你的操作比较复杂,可以考虑方法参考等其他方式。Lambda表达式中,即使不使用任何参数,也必须写下括号。在只有Lambda表达式的情况下,参数的类型必须写出来,如果有目标类型的话,在编译程序可推断出类型的情况下,就可以不写出Lambda表达式的参数类型。Lambda表达式本身是中性的,不代表任何类型的实例。同样的Lambda表达式,可以用来表示不同目标类型的对象操作。JDK8的Lambda并没有导入新类型来作为Lambda表达式的类型,而是就现有的interface语法来定义函数接口,作为Lambda表达式的目标类型,函数接口就是接口,但要求仅具单一抽象方法,许多现存的接口都是这种接口,像是标准API中的Runnable、Callable、Comparator等,都只定义了一个方法。不过在JDK8中有时会难以直接分辨接口是否为函数接口,因为JDK8对interface语法做了演进,允许有默认方法,而接口可能继承其他接口、重新定义了某些方法等,这些都会使得确认接口是否为函数接口更为困难。如果接口使用了@FunctionalInterface来标注,而本身并非函数接口的话,就会引发编译错误。
二、Functional与Stream API
1.使用Optional代替null
null的最根本问题就在于语意含糊不清,就字面来说,null可以是“不存在”、“没有”、“无”、“空”的意思,因此在应用时,总是有人摸棱两可,也就让开发者有了各自解释的空间。当开发者因为某个原因,不假思索的放个null时,然后用户就总是忘了检查null,引发各种可能的错误。我们要确认使用null的时机与目的,并使用明确的语意。如果不想返回null,可以返回Optional实例,调用方法时如果返回类型是Optional,应该立即想到它可能包含也可能不包含值。要建立Optional实例有几个静态方法,使用of()方法可以指定非null值建立Optional实例,使用empty()方法可以建立不包含值的Optional实例。在Optional没有包含值的情况下,就会直接抛出java.util.NoSuchElementException,这实现了速错的概念。一个较好的方式是使用orElse()方法,指定值不存在时的替代值。过去许多链接库中使用了不少null,这些链接库无法说改就改,可使用Optional的ofNullable()来衔接链接库中会返回null的方法,使用ofNullable()方法时,若指定了非null值就会调用of()方法,指定了null值就会调用empty()方法。
2.标准API的函数接口
JDK8定义的通用函数接口,基本上放置于java.util.function套件之中,就行为来说,基本上可以分为Consumer、Function、Predicate与Supplier四个类型。如果需要的行为是接受一个自变量,然后处理后不返回值,就可以使用Consumer接口。Consumer接口主要是接受单一对象实例作为自变量,对于基本类型int、long、double,另外有IntConsumer、LongConsumer、DoubleConsumer三个函数接口;对于接受两个对象实例作为自变量的接口则为BiConsumer,另外还有ObjIntConsumer、ObjLongConsumer、ObjDoubleConsumer,这三个函数接口第一个参数接受对象实例,第二个参数分别接受int、long、double。如果需要的是接受一个自变量,然后以该自变量进行计算后返回结果,就可以使用Function接口。Function的子接口为UnaryOperator,特殊化为参数与返回值都是相同类型,虽然JDK8仍不支持运算符重载,不过这个命名显然源于某些语言中,运算符也是个函数的概念。如果接受一个自变量,然后只返回boolean值,也就是根据传入的自变量直接论断真假的行为,就可以使用Predicate函数接口。如果需要的行为是不接受任何自变量,然后返回值,那可以使用Supplier函数接口。
一、认识时间与日期
1.时间的度量
在正式认识Java提供了哪些时间处理API之前,得先来了解一些时间、日期的历史问题,这样你才会知道,时间日期确实是个很复杂的问题,而使用程序来处理时间日期,也不仅仅是使用API的问题。
格林威治标准时间:格林威治标准时间简称GMT时间,一开始是参考自格林威治皇家天文台的标准太阳时间,格林威治标准时间的正午是太阳抵达天空最高点之时,格林威治标准时间常被不严谨的当成是UTC时间。
世界时:世界时是借由观测远方星体跨过子午线而得,也称UT,这会比观察太阳来得准确一些。1972年引入UTC之前,GMT与UT是相同的。
国际原子时:虽然观察远方星体会比观察太阳来得准确,不过UT基本上仍受地球自转速度影响而会有所误差。1967年定义的国际原子时(TAI),将秒的国际单位定义为铯原子辐射振动9192631770周耗费的时间,时间从UT的1958年开始同步。
世界协调时间:由于基于铯原子振动定义的秒长是固定的,然而地球自转会越来越慢,这会使得实际上 TAI时间会不断超前基于地球自转的UT系列时间,为了保持TAI与UT时间不要差距过大,因而提出了具有折衷修正版本的世界协调时间(UTC)。
Unix时间:Unix系统的时间表示法,定义为UTC时间1970年1月1日00:00:00为起点而经过的秒数,不考虑闰秒修正,用以表达时间轴上某一瞬间。
epoch:某个特定时代的开始,时间轴上某一瞬间。例如java.util.Date封装的时间信息,就是January 1,1970,00:00:00 GMT经过的毫秒数,可以简称为epoch毫秒数
JDK8新时间日期API
1.机器时间观点的API
Date实例真正代表的并不是日期,最接近的概念应该是时间轴上特定的一瞬间,时间精度是毫秒,也就是UTC时间1970年1月1日0时0分0毫秒至某个特定瞬时的毫秒差。Date名称看来像是人类的时间概念,实际上却是机器的时间概念。真正可靠的信息只有内含的epoch毫秒数。所以如果你取得Date实例,下一步获取时间信息应该是通过Date的getTime()取得epoch毫秒数。JDK8新时间日期处理API中,最重要的就是清楚的将机器对时间的概念与人类对时间的概念分隔开来。
2.人类时间观点的API
对于片段的日期时间,JDK8新时间与日期API有LocalDateTime()、LocalDate()、LocalTime()等类来定义,这些类基于ISO 8601年历系统,是不具时区的时间与日期定义。
教材学习中的问题和解决过程
如何计算一个程序的运行时间?
解决
(1)以毫秒为单位计算:
long startTime=System.currentTimeMillis(); //获取开始时间
doSomeThing(); //测试的代码段
long endTime=System.currentTimeMillis(); //获取结束时间
System.out.println("程序运行时间: "+(end-start)+"ms");
(2)以纳秒为单位计算:
long startTime=System.nanoTime(); //获取开始时间
doSomeThing(); //测试的代码段
long endTime=System.nanoTime(); //获取结束时间
System.out.println("程序运行时间: "+(end-start)+"ns");
代码调试中的问题和解决过程
我想计算特定时间前20天的日期,现在有个方法:
Calendar ca = Calendar.getInstance();
ca.add(Calendar.DAY_OF_MONTH, -20);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String date = sdf.format(ca.getTime());
这个方法只能计算当前日期前20天的日期,现在应该怎么改?
上周考试错题总结
调用线程的interrupt()方法 ,会抛出()异常对象?
A .IOException
B .IllegalStateException
C .RuntimeException
D .InterruptedException
E .SecurityException
正确答案: D E
下面哪行分别插入到第五行,会导致输 "oops" ?
A .
catch (IllegalArgumentException e) {
B .
} catch (IllegalStateException c) {
C .
} catch (NumbelFormatException n) {
D .
} catch (ClassCastException c) {
正确答案: A C
Given an instance of a Stream, s, and a Collection, c, which are valid ways of creating a parallel stream? (Choose all that apply.)
给定一个Stream的实例s, 一个Collection的实例c, 下面哪些选项可以创建一个并行流?
A .
new ParallelStream(s)
B .
c.parallel()
C .
s.parallelStream()
D .
c.parallelStream()
E .
new ParallelStream(c)
F .
s.parallel()
正确答案: D F
What are some reasons to use a character stream, such as Reader/Writer, over a byte stream, such as InputStream/OutputStream? (Choose all that apply.)
A .
More convenient code syntax when working with String data
B .
Improved performance
C .
Automatic character encoding
D .
Built-in serialization and deserialization
E .
Character streams are high-level streams
F .
Multi-threading support
正确答案: A C
Assuming zoo-data.txt is a multiline text file, what is true of the following method?
private void echo() throws IOException {
try (FileReader fileReader = new FileReader("zoo-data.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader)) {
System.out.println(bufferedReader.readLine());
}
}
A .
It prints the first line of the file to the console.
B .
It prints the entire contents of the file.
C .
The code does not compile because the reader is not closed.
D .
The code does compile, but the reader is not closed.
E .
The code does not compile for another reason.
正确答案: A 你的答案
What is the result of executing the following code? (Choose all that apply.)
String line;
Console c = System.console();
Writer w = c.writer();
if ((line = c.readLine()) != null)
w.append(line);
w.flush();
A .
The code runs without error but prints nothing.
B .
The code prints what was entered by the user.
C .
An ArrayIndexOutOfBoundsException might be thrown.
D .
A NullPointerException might be thrown.
E .
An IOException might be thrown.
F .
The code does not compile.
正确答案: B D E
Which of the following are true? (Choose all that apply.)
A .
A new Console object is created every time System.console() is called.
B .
Console can only be used for reading input and not writing output.
C .
Console is obtained using the singleton pattern.
D .
When getting a Console object, it might be null.
E .
When getting a Console object, it will never be null.
正确答案: C D
Suppose that the file c:\book\java exists. Which of the following lines of code creates an object that represents the file? (Choose all that apply.)
A .
new File("c:\book\java");
B .
new File("c:\book\java");
C .
new File("c:/book/java");
D .
new File("c://book//java");
E .
None of the above
正确答案: B C
Which of the following are built-in streams in Java? (Choose all that apply.)
A .
System.err
B .
System.error
C .
System.in
D .
System.input
E .
System.out
F .
System.output
正确答案: A C E
定义新线程时,可以继承哪个类:Thread
使线程进入阻塞状态:答案缺interrupt()
Which of the following are not java.io
classes? (Choose all that apply.)
A .BufferedReader
B .BufferedWriter
C .FileReader
D .FileWriter
E .PrintReader
F .PrintWriter
正确答案:E
其他(感悟、思考等,可选)
学习Java应该多想,多练,多上手操作,不要只是停留在脑子里,要去实践一下才能进步。
结对及互评
评分标准
正确使用Markdown语法(加1分):
不使用Markdown不加分
有语法错误的不加分(链接打不开,表格不对,列表不正确...)
排版混乱的不加分
模板中的要素齐全(加1分)
缺少“教材学习中的问题和解决过程”的不加分
缺少“代码调试中的问题和解决过程”的不加分
代码托管不能打开的不加分
缺少“结对及互评”的不能打开的不加分
缺少“上周考试错题总结”的不能加分
缺少“进度条”的不能加分
缺少“参考资料”的不能加分
教材学习中的问题和解决过程, 一个问题加1分
代码调试中的问题和解决过程, 一个问题加1分
本周有效代码超过300分行的(加2分)
一周提交次数少于20次的不加分
其他加分:
周五前发博客的加1分
感想,体会不假大空的加1分
排版精美的加一分
进度条中记录学习时间与改进情况的加1分
有动手写新代码的加1分
课后选择题有验证的加1分
代码Commit Message规范的加1分
错题学习深入的加1分
点评认真,能指出博客和代码中的问题的加1分
结对学习情况真实可信的加1分
扣分:
有抄袭的扣至0分
代码作弊的扣至0分
迟交作业的扣至0分
点评过的同学博客和代码
上周博客互评情况
20155303
20155203
20155212
20155211
20155338
以上是 20155331 2016-2017-2 《Java程序设计》第七周学习总结 的全部内容, 来源链接: utcz.com/z/393974.html