第一章 为什么要关心java8

本文深入探讨了Java8的重要更新,包括Lambda表达式、Stream API、函数式接口和默认方法等,展示了如何使用这些特性提高代码效率和并行处理能力。

一、java怎么还在变

1、java在编程语言生态系统中的位置

java虚拟机(JVM)及其字节码可能会变得比java语言本身更重要,而且对于某些应用来说,java可能会被同样运行在JVM上的竞争对手(如Scala或Groovv)取代。

2、流处理

(1)、第一个编程概念就是流处理。介绍一下,流是一系列数据项,一次只生成一项。程序可以从输入流中一个一个读取数据项,然后以同样的方式将数据项写入输入流。一个程序的输出流可能是另一个程序的输入流。

(2)、先把字母转换成小写字母,然后打印出按照字典排序出现在最后的三个单词。其中cat,tr,sort,tail是同时执行的,这样sort就可以在cat或tr完成前先处理头几行。

(3)、在一个更高的抽象层次上写java8程序:思路变成了把这样的流变成那样的流(就像写数据库查询语句时的那种思路),而不是一次只处理一个项目。另一个好处是,java8可以透明地把输入的不想管部分拿到几个cpu内核上去分别执行你的Stream操作流水线——这是几乎免费的并行,用不着费劲搞Thead了。

3、用行为参数把代码传递给方法

java8增强了把方法(你的代码)作为参数传递给另一个方法的能力

4、并行与共享的可变数据

"不能有共享的可变数据"的要求意味着,一个方法可以通过它将参数值转换为结果的方式完全描述的,换句话说,他的行为就像一个数据函数,没有可见的副作用。

二、java中的函数

对象是java中的一等公民,但其他很多java概念(如方法和类等)都是二等公民。

1、方法和lambda作为一等公民

(1)方法引用

File [] hiddenFiles = new File(".").listFiles(File::isHidden); 已经有了函数isHidden,因此只需要用java 8的方法引用::语法(即“把这个方法作为值”)将其传递给listFiles方法。

只要方法中有代码(方法中的可执行部分),那么用方法引用就可以传递代码。

(2)Lambda——匿名函数

除了允许(命名)函数成为一等值外,java8还体现了更广义的将函数作为值的思想,包括Lambda(或匿名函数)。

2、传递代码:一个例子

public static boolean isGreenApple(Apple apple) {
    return "green".equals(apple.getColor()); 
}

public static boolean isHeavyApple(Apple apple) {
    return apple.getWeight() > 150;
}

public static List<Apple> filterApples(List<Apple> inventory, Predicate<Apple> p){
    List<Apple> result = new ArrayList<>();
    for(Apple apple : inventory){
        if(p.test(apple)){
            result.add(apple);
        }
    }
    return result;
}   

List<Apple> inventory = Arrays.asList(new Apple(80,"green"),
                                      new Apple(155, "green"),
                                      new Apple(120, "red"));  
List<Apple> greenApples = filterApples(inventory, FilteringApples::isGreenApple);
System.out.println(greenApples);
List<Apple> heavyApples = filterApples(inventory, FilteringApples::isHeavyApple);
System.out.println(heavyApples);  

3、从传递方法到Lambda

// [Apple{color='green', weight=80}, Apple{color='green', weight=155}]
List<Apple> greenApples2 = filterApples(inventory, (Apple a) -> "green".equals(a.getColor()));
System.out.println(greenApples2);

// [Apple{color='green', weight=155}]
List<Apple> heavyApples2 = filterApples(inventory, (Apple a) -> a.getWeight() > 150);
System.out.println(heavyApples2);

// []
List<Apple> weirdApples = filterApples(inventory, (Apple a) -> a.getWeight() < 80 || 
                                                               "brown".equals(a.getColor()));
System.out.println(weirdApples);

三、流

1、例如:从一个列表中筛选金额较高的交易

(1)传统代码:这种数据迭代的方法称为外部迭代

(2)Steam API:数据处理完全是在库内部进行的,这种思想叫做内部迭代。

2、多线程并非易事

(1)线程可能会同时访问并更新共享变量。因此,如果没有协调好,数据可能会被以外改变,相比一步步执行的顺序模型,这个模型不太好理解。

(2)java8也用Stream API解决了这两个问题:集合处理时的套路和晦涩,以及难以利用多核。

(3)Collection主要是为了存储和访问数据,而Stream则主要用于描述对数据的计算。这里的关键点在于,Stream允许并提倡并行处理一个Stream中的元素。筛选一个Collection的最快方法常常是将其转换为Stream。进行并行处理,然后再转换会List。

顺序处理:

import static java.util.stream.Collectors.toList;
List<Apple> heavyApples = inventory.stream().filter((Apple a) ->a.getWeight()>150).collect(toList());

并行处理:

import static java.util.stream.Collectors.toList;
List<Apple> heavyApples = inventory.parallelStream().filter((Apple a) ->a.getWeight()>150).collect(toList());

四、默认方法

java8接口如今可以包含实现类没有提供实现的方法签名,缺失的方法主体随接口提供了(因此就有了默认实现),而不是有由实现类提供。

五、来自函数式编程的其他好思想

将方法和lambda作为一等值,以及在没有可变共享状态时,函数 或方法可以有效、安全的并行执行。

转载于:https://my.oschina.net/u/2427561/blog/2208624

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值