以上四个都是函数式接口,对于这些接口,重要的是明白其存在的意义
jdk推出这些函数式接口的目的是为了进行函数式编程,由于lambda表达式的应用,我们在实际编程中可能感受不到这些接口的使用,但其实在链式编程的时候,我们大量应用了这些接口。例如stream中的一个map方法,我们自然而然的直到这是将原值转换为另一个值,而我们在写lambda表达式的时候,其可行就是因为函数式接口Function的存在,总的来说,在函数式接口中增加了函数的总量,而几乎可以忽略类(接口)的存在,函数成了一等公民。
Predicate 一个语言函数接口,核心方法
boolean test(T t)
当然该接口还提供了默认的接口实现方法帮助进行链式编程预言,该接口只是提供了一个jdk标准的filter方法,每进行一次链式调用,都会生成一个新的Predicate对象。
源码:
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
例子:
public class PredicateTest {
@Test
public void test() {
Predicate<String> predicate = s -> "jsen".equals(s.toLowerCase());
Consumer<Boolean> consumer = System.out::println;
consumer.accept(predicate.test("jSen"));
consumer.accept(predicate.test("jack"));
}
}
Supplier
Supplier是一个内容提供者,返回指定类型的实例对象,核心方法
T get()
,也只有这个方法。
源码:
@FunctionalInterface
public interface Supplier<T> {
T get();
}
例子:
public class SupplierTest {
@Test
public void test() {
Supplier<Integer> supplier = new Random()::nextInt;
Consumer<Integer> consumer = System.out::println;
consumer.accept(supplier.get());
}
}
Consumer 用于消费一个结果,核心方法void accept(T t) 同时提供
Consumer<T> andThen(Consumer<? super T> after)
实现链式调用,该方法对两个Consumer调用accept后创建一个新的Consumer,也可以将其想象成对某个事件执行结束后的特点处理(回调)。
源码:
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
例子:
public class ConsumerTest {
@Test
public void test() {
Consumer<String> simplePrint = System.out::println;
handler("jsen", simplePrint);
}
private void handler(String s, Consumer<String> c) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
c.accept(s);
}
}
}
Fuction
相当于一个有返回结果的回调接口,核心方法
R apply(T t)
,从形式上看,function接口与Consumer接口唯一的区别在于他是有返回值的,意味着它可以对结果不断链式处理。
以下实现对String list中元素统计长度并输出。
源码:
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
例子:
public class FunctionTest {
@Test
public void test() {
List<String> names = Lists.newArrayList("jsen", "jack", "lucy", "smile");
names.stream().map(String::length).forEach(System.out::println);
}
}