一、lambda表达式
1.lambda表达式是一段可以传递的代码,可以被执行一次或多次,本质上是匿名函数
功能特点:使代码简洁、紧凑。适用场景:替换以前广泛使用的内部匿名类,各种回调等
2.语法形式
(1) 参数 、箭头 、表达式例如:(String first,String second) -> (first + second);(2) 参数 、箭头 、语句块例如:(String first,String second) -> { (System.out.print(first+second); }lambda参数类型是可以推导的,所以参数的类型也可以省略。返回值也是可以推导的,所以不用return
3.lambda表达式应用实例
//使用内部类实现Comparator comparator = new Comparator<String>(){@Overridepublic int compare(String first, String second) {return Integer.compare(first.length(),second.length());}};//使用lambda表达式Comparator<String> comparator1 = (first,second) ->Integer.compare(first.length(),second.length());
4.方法引用:直接通过方法名称引用,是一种简洁易懂的lambda表达式
使用方式:对象 ::实例方法类 ::静态方法类 ::实例方法例如:button.setOnAction(event -> System.out.print(event));等价于 button.setOnAction(event -> System.out::print);
5.构造器引用:与方法引用类似,不同之处是方法名为new
例如:Button::new
6.闭包:含有自由变量的代码块。
lambda中的被引用的变量是不可以被更改的值,不能引用值是可变的变量。
7.默认方法:java8允许在接口添加带有具体实现的方法,只要在方法前加上default修饰即可。
例如: public interface A{default void show(){System.out.print(“hello”);}}默认方法可以在不改变原有程序的情况下,为接口添加个性化的方法,为编程带来灵活性。
8.接口中静态方法,在方法前加上static
例如: public interface A{static void show(){System.out.print(“static”);}}
9.函数式接口 :只含有一个抽象方法的接口,可以用lambda表达式创建该接口的对象,是lamdba的目标类型。
在java8 API中会有 @FunctionalInterface标识常用的函数式有:Runnable,Supplier<T> ,Consumer<T>等等使用lambda创建函数式接口的实现对象时,需要查看对应函数式接口中接口方法的参数、返回值等情况。
二、Stream API
1.Stream称为流,用来处理集合,可以把Stream当成一个高级版本的Iterator,用户只要给出需要对其包含的
元素执行什么操作,Stream就可以把集合中的所有元素都按指定的操作执行。
2.创建Stream
(1)使用Stream静态方法of(2) 使用集合类提供的获取方法
3.使用filter、map和flatMap方法进行流转换,产生新的流。
例如: Stream<String> old = Stream.of("a","b","c");Stream<Integer> newS = old .map(num -> num.length());
4.提取子流和组合流
使用Stream中limit,concat的方法实现
5.有状态转移:流中的元素依赖之前的元素。
例如:Stream<String> s = Stream.of("a","d","c");Stream<String> after = s.sorted();
6.Stream中的聚合方法 max,min可对流中的元素汇聚。
7.Optional:这是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。Optional<T> 将对象T封装,使得引用安全,可避免NullPointerException。
8.收集结果
(1) 调用Stream中iterator方法,获取到迭代器,进行遍历。(2) 调用Stream中toArray方法,获取元素数组。(3) 调用Stream中collect方法进行收集。
9.分组:调用Stream中groupingBy进行分组。
10.原始类型流
基本类型占用内存空间小,但不能按对象方式处理,并且不能处理Null值等封装类型可以按对象方式进行处理,但占用空间大。java8提供了IntStream,LongStream等类型,直接存储原始类型值,不必存封装对象,并且为这些流提供了sum、average、max等方法。好处:可以按封装类方式处理,并且存的是基本类型,在使用方便的同时,还能减少存储空间。
三、新的日期和时间
1.闰秒:精确的时间计算中,一天的时间86400不固定,会每隔几年增加1秒,也就是时间会出现不准确的情况。
Java8对此情况进行了处理。
2.之前的Date对象实例是可变的,并且Date,Calendar职责过多,并且不按常理的表示(比如:月份从0开始,
年月从1970开始等)使得对时间使用不方面。
3.Java8中Instant表示时间点,Duration表示两个时间点的时间距离
例如: Instant start = Instant.now();Instant end = Instant.now();Duration duration = Duration.between(start,ent);
4.日期校正器 :TemporalAdjusters提供了许多静态方法对时间进行校正。
5.提供格式化时间方法,使用DateTimeFormatter中format处理。
四、并发增强
1.为部分封装类提供了原子值的操作处理,比如LongAccumulator、DoubleAccumulator。
AtomicInteger,AtomicIong中 updateAndGet/ accumulateAndGet更容易更新原子变量。
2.对ConcurrentHashMap加以改进,提供了对键、值、键值对的各类操作。
3.Arrays提供许多并行化操作。比如parallelSort,parallelSetAll等方法。
五、JavaScript引擎 --Nashorn
1.Nashorn: 是java8提供的JavaScript解释器。它非常快,可以运行在高度调优的虚拟机上来集成
Java和JavaScript。
2.基本使用实例
//通过脚本引擎管理类获取实例对象
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
Object result = engine.eval("'hello nashorn!'"); //执行脚本
System.out.println(result);
Invocable invocable = (Invocable)engine;
invocable.invokeFunction("show"); //调用脚本中方法
3.通过脚本引擎可以实现Java与JavaScript相互引用,实现数据交互。
六、Java8 杂项改进
1.String可以方便地用分隔符连接字符串
例如:String.join(“,” , “a” ,”b”, ”c”) 与 “a” + “,” + “b” + “,” + “c” 等效
2.基本类型的封装类提供了新的方法,比如部分封装类提供了sum、max、min的等方法用于聚合函数处理。
Integer添加无符号处理 toUnsignedInt()。
Float和Double添加了静态方法 isFinite,用于检查正无穷大、负无穷大、NaN。
3.Math类添加新的方法,比如:addExact、multiplyExact等,会在结果溢出抛出异常,以此来检查溢出。
求模运算时:Math.floorMod(x,n) 其中可以处理x为负数的情况。
4.集合中添加一些方法,如Iterable中添加 forEach等
5.Files中添加 lines、list方法,方便读取文件行、列举文件