GitHub 上幽默的门类引进

CSS 效果

艺术、构造器引用

java8能够运用冒号表明式来引用方法:

System::getProperty
System.out::println
"abc"::length
ArrayList::new
int[]::new

测试

高效能的懒加载

假诺我们需要找出3-11里边的最大的奇数,并求出它的平方。

我们或许行使这样的代码:

private static int findSquareOfMaxOdd(List<Integer> numbers) {
        int max = 0;
        for (int i : numbers) {
            if (i % 2 != 0 && i > 3 && i < 11 && i > max) {
                max = i;
            }
        }
        return max * max;
    }

上述代码是在一个行列中拍卖大家可以应用流式API代替:

public static int findSquareOfMaxOdd(List<Integer> numbers) {
        return numbers.stream()
                .filter(NumberTest::isOdd)  
                .filter(NumberTest::isGreaterThan3)
                .filter(NumberTest::isLessThan11)
                .max(Comparator.naturalOrder())
                .map(i -> i * i)
                .get();
    }

    public static boolean isOdd(int i) {
        return i % 2 != 0;
    }

    public static boolean isGreaterThan3(int i){
        return i > 3;
    }

    public static boolean isLessThan11(int i){
        return i < 11;
    }

冒号表明式是办法的引用,NumberTest::isOdd 是 (i) -> isOdd(i) 或者
i -> NumberTest.isOdd (i) 的缩写。

polyfill(兼容浏览器API的shim)

更多的lambda表明式示例

() -> {}                     // 无参无方法体

() -> 42                     // 无参有方法体
() -> null                   // 无参有方法体
() -> { return 42; }         // 无参,代码块中返回结果
() -> { System.gc(); }       // 

// 复杂的代码块
() -> {
  if (true) return 10;
  else {
    int result = 15;
    for (int i = 1; i < 10; i++)
      result *= i;
    return result;
  }
}                          

(int x) -> x+1             // 单个的声明类型的参数
(int x) -> { return x+1; } // 
(x) -> x+1                 // 单个参数,单条代码同上
x -> x+1                   // 同上

(String s) -> s.length()   // 
(Thread t) -> { t.start(); } // 
s -> s.length()              // 单个的编译器可以推断的类型参数
t -> { t.start(); }          // 单个的编译器可以推断的类型参数

(int x, int y) -> x+y      // 多个的声明类型的参数
(x,y) -> x+y               // 多个的可以推断的类型参数
(x, final y) -> x+y        // 错误。不能修改final变量y
(x, int y) -> x+y          // 错误,无法推断混合类型

很酷的品种

给艺术传递行为action

我们需要对一个list中满足某个条件的因素举行求和。

public static int sumWithCondition(List<Integer> numbers, Predicate<Integer> predicate) {
        return numbers.parallelStream()
                .filter(predicate)
                .mapToInt(i -> i)
                .sum();
    }

选择办法如下:

//对所有元素求和
sumWithCondition(numbers, n -> true)
//对是偶数的元素求和
sumWithCondition(numbers, i -> i%2==0)
//对所有大于5的元素求和
sumWithCondition(numbers, i -> i>5)

其他

本身 Github 上的保有
Star

lambda表达式

透过lambda表达式大家可以将函数式编程在java的面向对象中形象化。
目的是java语言的主旨,我们不容许离开对象单独去行使办法,这也是怎么java提供lambda表明式仅仅能运用函数式接口的来头。

一经只有一个空洞方法,那么使用lambda表达式就不会存在疑惑了。
lambda表达式的签名:
*** (argument1, argument2,…) -> (body) ***

  • ** (argument1, argument2,…)**表示方法签名,argument1,
    argument2,…是参数列表

  • ** -> ** 是箭头,指向方法体

  • **(body) ** 是方法体,可以采用{}包裹代码块来表示

  • 假即便无参方法,则方法签名方可动用 ()

  • 比方唯有一个参数的话,()可以概括

眼前创造Runnable实例的代码能够选择lambda说明式实现:

Runnable r1 = () -> System.out.println("My Runnable");

诠释下这段代码:

  • Runnable 是一个函数式接口,所以我们得以采纳lambda表明式成立它的实例

  • 因为 run()方法咩有参数,所以我们的lambda表达式也绝非参数

  • 就像if-else语句一样,倘若只有一行代码的话我们得以节约{}符号了。

Mac & iOS

减去代码量

利用匿名内部类和lambda表明式的代码量区分已经很显眼了

更新于 2016/08/23

协理连续地、并行地执行

lambda的此外一个功利就是我们得以选用流式API连续并行地举办顺序。
为了验证这点,我们举个例子。判断一个数是不是质数:
这段代码不是最优的,但是足以达到目标:

private static boolean isPrime(int number) {        
    if(number < 2) return false;
    for(int i=2; i<number; i++){
        if(number % i == 0) return false;
    }
    return true;
}

解决这么些问题的代码是接二连三的,如若给定的数字很大的话很耗时。另外一个缺陷是分支重返太多可读性不佳。使用lambda和流式API的写法:

private static boolean isPrime(int number) {        
    return number > 1
            && IntStream.range(2, number).noneMatch(
                    index -> number % index == 0);
}

**IntStream
**是一个本来排好序的元素为原始类型int的支撑连续并行执行的流。为了更好读书,代码可以更进一步优化为:

private static boolean isPrime(int number) {
    IntPredicate isDivisible = index -> number % index == 0;

    return number > 1
            && IntStream.range(2, number).noneMatch(
                    isDivisible);
}

range(arg1,arg2)办法重临一个**IntStream
**饱含arg1,不过不含有arg2的幅度为1的队列。

noneMatch()回到是否没有元素匹配不上加以的预定义条件Predicate。

安全

函数式接口使用背景

我们明白,java是一门面向对象编程语言,java中一切都是面向对象的(除了原有数据类型)。在java中函数(方法)是类/对象的一部分,不能独立存在。而任何部分函数式编程语言如C++、Javascript等语言,可以编制单独的函数并得以平素调用它们。

面向对象并非糟糕,只是偶尔需要编制冗长的代码。举个简单的事例,我们需要创建一个Runnable实例,通常大家会动用匿名内部类如下:

Runnable r = new Runnable(){
            @Override
            public void run() {
                System.out.println("My Runnable");
            }};

骨子里在这段代码中,真实有用的仅仅只是内部的run方法,其他的代码只是java面向对象要求的。

java8函数式接口和lambda表明式可以让我们编辑少量代码就能达成上述功效。

Web 前端

为何要使用lambda表明式

资源

java8函数式接口

在java8中,本身只有一个浮泛方法的接口即可称之为函数式接口,可以运用@FunctionalInterface表分明示标明接口是函数式接口。这多少个注脚并非必须的,假若加上该注明,则接口若存在多于一个的虚幻方法则会指示编译错误。

java8函数式接口的最大好处是足以行使lambda表达式来初阶化函数式接口从而制止匿名内部类样式的笨重写法。

java8的集合API已经重写了,并且引进了采用过多的函数式接口的新的流式API。在java.util.function包下定义了诸多函数式接口如:ConsumerSupplierFunctionPredicate

教程

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图