赞
踩
Java 中的函数
Java 8中新增了函数——值的一种新形式。函数作为一等值,使用方法引用 :: 语法(即“把这个方法作为值”),作为函数式值来传递。
File[] hiddenFiles = new File(".").listFiles(new FileFilter() {
public boolean accept(File file) {
return file.isHidden();
}
});
只要方法中有代码(方法中的可执行部分),那么用方法引用就可以传递代码。
File[] hiddenFiles = new File(".").listFiles(File::isHidden);
Lambda——匿名函数
除了允许(命名)函数成为一等值外,Java 8还体现了更广义的将函数作为值的思想,包括Lambda(或匿名函数)。
比如,调用时给定参数 x ,就返回 x + 1值的函数。
(int x) -> x + 1
流
和Collection API相比,Stream API处理数据的方式非常不同。用集合的话,你得自己去做迭代的过程。你得用 for-each 循环一个个去迭代元素,然后再处理元素。我们把这种数据迭代的方法称为外部迭代。相反,有了Stream API,你根本用不着操心循环的事情。数据处理完全是在库内部进行的。我们把这种思想叫作内部迭代。
Collection主要是为了存储和访问数据,而Stream则主要用于描述对数据的计算。这里的关键点在于,Stream允许并提倡并行处理一个 Stream 中的元素。虽然可能乍看上去有点儿怪,但筛选一个 Collection 的最快方法常常是将其转换为 Stream ,进行并行处理,然后再转换回 List 。
比如,利用Stream和Lambda表达式顺序或并行地从一个列表里筛选比较重的苹果。
import static java.util.stream.Collectors.toList;
List inventory = Arrays.asList(new Apple(80,"green"),
new Apple(155, "green"),
new Apple(120, "red"));
List apples = inventory.stream()
.filter((Apple a) -> a.getWeight() > 150)
.collect(toList());
// 并行处理
List apples2 = inventory.parallelStream()
.filter((Apple a) -> a.getWeight() > 150)
.collect(toList());
filter方法传入的参数其实是谓词,我们来看下JDK8 Predicate类源码。
package java.util.function;
import java.util.Objects;
/**
* Represents a predicate (boolean-valued function) of one argument.
*
*
This is a functional interface
* whose functional method is {@link #test(Object)}.
*
* @param the type of the input to the predicate
*
* @since 1.8
*/
@FunctionalInterface
public interface Predicate {
/**
* Evaluates this predicate on the given argument.
*
* @param t the input argument
* @return {@code true} if the input argument matches the predicate,
* otherwise {@code false}
*/
boolean test(T t);
// ...
}
什么是谓词?
谓词(predicate)在数学上常常用来代表一个类似函数的东西,它接受一个参数值,并返回 true 或 false 。
filter通过行为参数化进行代码传递。行为参数化,就是一个方法接受多个不同的行为作为参数,并在内部使用它们,完成不同行为的能力。其实就是策略模式,它可以把一个行为(一段代码)封装起来,并通过传递和使用创建的行为(例如不同谓词)将方法的行为参数化。行为参数化可以让代码更好地适应不断变化的要求,减轻未来的工作量。
Java API中的很多方法都可以用不同的行为来参数化(比如Comparator 排序,用 Runnable 执行一个代码块,以及GUI事件处理),这些方法往往与匿名类一起使用。
默认方法
Java 8中加入默认方法主要是为了支持库设计师,让他们能够写出更容易改进的接口。在接口中使用默认方法,在实现类没有实现方法时提供方法内容。在接口声明中使用新的 default 关键字来表示这一点。
参考
书籍《Java 8实战》
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。