java 8 的新特性(二)

Java 8 默认方法

简单说,默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法。

我们只需在方法名前面加个 default 关键字即可实现默认方法。

Java 8 的另一个特性是接口可以声明(并且可以提供实现)静态方法。

<code>public interface Vehicle {
   default void print(){
      System.out.println("我是一辆车!");
   }
}/<code>

为什么要有这个特性?

首先,之前的接口是个双刃剑,好处是面向抽象而不是面向具体编程,缺陷是,当需要修改接口时候,需要修改全部实现该接口的类,目前的 java 8 之前的集合框架没有 foreach 方法,通常能想到的解决办法是在JDK里给相关的接口添加新的方法及实现。然而,对于已经发布的版本,是没法在给接口添加新方法的同时不影响已有的实现。所以引进的默认方法。他们的目的是为了解决接口的修改与现有的实现不兼容的问题。


java 8 的新特性(二)


Java 8 Stream

Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。

Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

<code>List transactionsIds = 
widgets.stream()
             .filter(b -> b.getColor() == RED)
             .sorted((x,y) -> x.getWeight() - y.getWeight())
             .mapToInt(Widget::getWeight)
             .sum();/<code>

Stream(流)是一个来自数据源的元素队列并支持聚合操作

  • 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
  • 数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
  • 聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。

和以前的Collection操作不同, Stream操作还有两个基础的特征:

  • Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
  • 内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。

forEach

Stream 提供了新的方法 'forEach' 来迭代流中的每个数据。

map

map 方法用于映射每个元素到对应的结果

filter

filter 方法用于通过设置的条件过滤出元素。

limit

limit 方法用于获取指定数量的流。

sorted

sorted 方法用于对流进行排序。

并行(parallel)程序

parallelStream 是流并行处理程序的代替方法。

<code>List strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 获取空字符串的数量
long count = strings.parallelStream().filter(string -> string.isEmpty()).count();/<code>

Collectors

Collectors 类实现了很多归约操作,例如将流转换成集合和聚合元素。Collectors 可用于返回列表或字符串:

<code>Liststrings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
 
System.out.println("筛选列表: " + filtered);
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("合并字符串: " + mergedString);/<code>

统计

另外,一些产生统计结果的收集器也非常有用。它们主要用于int、double、long等基本类型上,它们可以用来产生类似如下的统计结果。

<code>List numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
 
IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();
 
System.out.println("列表中最大的数 : " + stats.getMax());
System.out.println("列表中最小的数 : " + stats.getMin());
System.out.println("所有数之和 : " + stats.getSum());
System.out.println("平均数 : " + stats.getAverage());/<code>


java 8 的新特性(二)


Java 8 Optional 类

Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。

Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。

Optional 类的引入很好的解决空指针异常。

<code>
序号	方法 & 描述
1	static  Optional empty()
返回空的 Optional 实例。

2	boolean equals(Object obj)
判断其他对象是否等于 Optional。

3	Optional filter(Predicate super  predicate)
如果值存在,并且这个值匹配给定的 predicate,返回一个Optional用以描述这个值,否则返回一个空的Optional。

4	 Optional flatMap(Function super T,Optional> mapper)
如果值存在,返回基于Optional包含的映射方法的值,否则返回一个空的Optional

5	T get()
如果在这个Optional中包含这个值,返回值,否则抛出异常:NoSuchElementException

6	int hashCode()
返回存在值的哈希码,如果值不存在 返回 0。

7	void ifPresent(Consumer super T> consumer)
如果值存在则使用该值调用 consumer , 否则不做任何事情。

8	boolean isPresent()
如果值存在则方法会返回true,否则返回 false。

9	Optional map(Function super T,? extends U> mapper)
如果有值,则对其执行调用映射函数得到返回值。如果返回值不为 null,则创建包含映射返回值的Optional作为map方法返回值,否则返回空Optional。

10	static  Optional of(T value)
返回一个指定非null值的Optional。

11	static  Optional ofNullable(T value)
如果为非空,返回 Optional 描述的指定值,否则返回空的 Optional。

12	T orElse(T other)
如果存在该值,返回值, 否则返回 other。

13	T orElseGet(Supplier extends T> other)
如果存在该值,返回值, 否则触发 other,并返回 other 调用的结果。

14	 T orElseThrow(Supplier extends X> exceptionSupplier)
如果存在该值,返回包含的值,否则抛出由 Supplier 继承的异常

15	String toString()
返回一个Optional的非空字符串,用来调试/<code> 


java 8 的新特性(二)


Java 8 Nashorn JavaScript

Nashorn 一个 javascript 引擎。

从JDK 1.8开始,Nashorn取代Rhino(JDK 1.6, JDK1.7)成为Java的嵌入式JavaScript引擎。Nashorn完全支持ECMAScript 5.1规范以及一些扩展。它使用基于JSR 292的新语言特性,其中包含在JDK 7中引入的 invokedynamic,将JavaScript编译成Java字节码。

与先前的Rhino实现相比,这带来了2到10倍的性能提升。

使用 ScriptEngineManager, JavaScript 代码可以在 Java 中执行,实例如下:

<code>import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
 
public class Java8Tester {
   public static void main(String args[]){
   
      ScriptEngineManager>

以下实例演示了如何在 JavaScript 中引用 Java 类

<code>var BigDecimal = Java.type('java.math.BigDecimal');

function calculate(amount, percentage) {

   var result = new BigDecimal(amount).multiply(
   new BigDecimal(percentage)).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_EVEN);
   
   return result.toPlainString();
}

var result = calculate(568000000000000000023,13.9);
print(result);/<code>


分享到:


相關文章: