Lambda: In programming languages such as Lisp, Python and Ruby lambda is an operator used to denote anonymous functions or closures, following the usage of lambda calculus.
/** * An informative annotation type used to indicate that an interface * type declaration is intended to be a <i>functional interface</i> as * defined by the Java Language Specification. * * Conceptually, a functional interface has exactly one abstract * method. Since {@linkplain java.lang.reflect.Method#isDefault() * default methods} have an implementation, they are not abstract. If * an interface declares an abstract method overriding one of the * public methods of {@code java.lang.Object}, that also does * <em>not</em> count toward the interface's abstract method count * since any implementation of the interface will have an * implementation from {@code java.lang.Object} or elsewhere. * * 有且只有一个抽象方法的接口,如果有重写 Object 中的方法,那也是可以的。 * * <p>Note that instances of functional interfaces can be created with * lambda expressions, method references, or constructor references. * * 函数式接口可以通过 lambda 表达式、方法引用和构造方法引用来创建。 * * <p>If a type is annotated with this annotation type, compilers are * required to generate an error message unless: * * <ul> * <li> The type is an interface type and not an annotation type, enum, or class. * <li> The annotated type satisfies the requirements of a functional interface. * </ul> * * <p>However, the compiler will treat any interface meeting the * definition of a functional interface as a functional interface * regardless of whether or not a {@code FunctionalInterface} * annotation is present on the interface declaration. * * 编译器会对满足定义函数式接口的接口当做函数式接口,不管它有没有 @FunctionalInterface 注解声明。 * * @jls 4.3.2. The Class Object * @jls 9.8 Functional Interfaces * @jls 9.4.3 Interface Method Body * @since 1.8 */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public@interface FunctionalInterface {}
publicinterfaceIterable<T> { /** * Returns an iterator over elements of type {@code T}. * * @return an Iterator. */ Iterator<T> iterator();
/** * Performs the given action for each element of the {@code Iterable} * until all elements have been processed or the action throws an * exception. Unless otherwise specified by the implementing class, * actions are performed in the order of iteration (if an iteration order * is specified). Exceptions thrown by the action are relayed to the * caller. * * 对每个元素执行给定的动作。 * * @implSpec * <p>The default implementation behaves as if: * <pre>{@code * for (T t : this) * action.accept(t); * }</pre> * * @param action The action to be performed for each element * @throws NullPointerException if the specified action is null * @since 1.8 */ defaultvoidforEach(Consumer<? super T> action){ Objects.requireNonNull(action); for (T t : this) { action.accept(t); } }
/** * Represents an operation that accepts a single input argument and returns no * result. Unlike most other functional interfaces, {@code Consumer} is expected * to operate via side-effects. * * 表示一个操作接受单一输入参数,无返回结果。 * * <p>This is a <a href="package-summary.html">functional interface</a> * whose functional method is {@link #accept(Object)}. * * @param <T> the type of the input to the operation * * @since 1.8 */ @FunctionalInterface publicinterfaceConsumer<T> {
/** * Performs this operation on the given argument. * * @param t the input argument */ voidaccept(T t);
/** * Returns a composed {@code Consumer} that performs, in sequence, this * operation followed by the {@code after} operation. If performing either * operation throws an exception, it is relayed to the caller of the * composed operation. If performing this operation throws an exception, * the {@code after} operation will not be performed. * * @param after the operation to perform after this operation * @return a composed {@code Consumer} that performs in sequence this * operation followed by the {@code after} operation * @throws NullPointerException if {@code after} is null */ default Consumer<T> andThen(Consumer<? super T> after){ Objects.requireNonNull(after); return (T t) -> { accept(t); after.accept(t); }; } }
所有的参数需包含在圆括号内,参数之间用逗号相隔。如:(a, b) 或 (String a, int b float c)
空圆括号表示参数集为空,如:() -> 42
当只有一个参数,且其类型可推导时,圆括号可以省略,如:a -> return a * a
Lambda 表达式的主题可以包含零条或多条语句
如果 Lambda 表达式的主体只有一条语句,花括号可以省略,匿名函数的返回类型与该主体表达式一致
如果 Lambda 表达式的主体包含一条以上语句,表达式必须使用花括号
Function
直接先看源码
/** * Represents a function that accepts one argument and produces a result. * * <p>This is a <a href="package-summary.html">functional interface</a> * whose functional method is {@link #apply(Object)}. * * @param <T> the type of the input to the function * @param <R> the type of the result of the function * * @since 1.8 */ @FunctionalInterface publicinterfaceFunction<T, R> {
/** * Applies this function to the given argument. * * @param t the function argument * @return the function result */ 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)); }
/** * Returns a function that always returns its input argument. * * @param <T> the type of the input and output objects to the function * @return a function that always returns its input argument */ static <T> Function<T, T> identity(){ return t -> t; } }
可以看出 Function 有一个抽象方法和两个默认方法以及一个静态方法。
(1) Function#apply
Stream#map 里就是接受一个 Function,对于 Function 意思就是从一个映射到另一个。下面例子就是把字符串映射到大写。对于 String::toUpperCase 使用的是方法引用。
/** * Returns a composed function that first applies the {@code before} * function to its input, and then applies this function to the result. * If evaluation of either function throws an exception, it is relayed to * the caller of the composed function. * * @param <V> the type of input to the {@code before} function, and to the * composed function * @param before the function to apply before this function is applied * @return a composed function that first applies the {@code before} * function and then applies this function * @throws NullPointerException if before is null * * @see #andThen(Function) */ default <V> Function<V, R> compose(Function<? super V, ? extends T> before){ Objects.requireNonNull(before); return (V v) -> apply(before.apply(v)); }
/** * Returns a composed function that first applies this function to * its input, and then applies the {@code after} function to the result. * If evaluation of either function throws an exception, it is relayed to * the caller of the composed function. * * @param <V> the type of output of the {@code after} function, and of the * composed function * @param after the function to apply after this function is applied * @return a composed function that first applies this function and then * applies the {@code after} function * @throws NullPointerException if after is null * * @see #compose(Function) */ default <V> Function<T, V> andThen(Function<? super R, ? extends V> after){ Objects.requireNonNull(after); return (T t) -> after.apply(apply(t)); }
compose方法是一个默认方法,这个方法接收一个 function 作为参数,将参数 function 执行的结果作为参数给调用的 function,以此来实现两个function组合的功能。
andThen 方法也是接收一个 function 作为参数,与 compse 不同的是,先执行本身的 apply 方法,将执行的结果作为参数给参数中的 function。
/** * @Author: cuzz * @Date: 2019/8/20 23:59 * @Description: #compose and #andThen test */ publicclassFunctionTest2{
publicstaticvoidmain(String[] args){ FunctionTest2 test = new FunctionTest2(); System.out.println(test.compute1(2, value -> value * 2, value -> value * value)); // 8 System.out.println(test.compute2(2, value -> value * 2, value -> value * value)); // 16 }
/** * Represents a function that accepts two arguments and produces a result. * This is the two-arity specialization of {@link Function}. * * <p>This is a <a href="package-summary.html">functional interface</a> * whose functional method is {@link #apply(Object, Object)}. * * @param <T> the type of the first argument to the function * @param <U> the type of the second argument to the function * @param <R> the type of the result of the function * * @see Function * @since 1.8 */ @FunctionalInterface publicinterfaceBiFunction<T, U, R> {
/** * Applies this function to the given arguments. * * @param t the first function argument * @param u the second function argument * @return the function result */ R apply(T t, U u);
/** * Returns a composed function that first applies this function to * its input, and then applies the {@code after} function to the result. * If evaluation of either function throws an exception, it is relayed to * the caller of the composed function. * * @param <V> the type of output of the {@code after} function, and of the * composed function * @param after the function to apply after this function is applied * @return a composed function that first applies this function and then * applies the {@code after} function * @throws NullPointerException if after is null */ default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after){ Objects.requireNonNull(after); return (T t, U u) -> after.apply(apply(t, u)); } }
/** * Represents a predicate (boolean-valued function) of one argument. * * <p>This is a <a href="package-summary.html">functional interface</a> * whose functional method is {@link #test(Object)}. * * @param <T> the type of the input to the predicate * * @since 1.8 */ @FunctionalInterface publicinterfacePredicate<T> {
/** * 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} */ booleantest(T t);
/** * Returns a composed predicate that represents a short-circuiting logical * AND of this predicate and another. When evaluating the composed * predicate, if this predicate is {@code false}, then the {@code other} * predicate is not evaluated. * * <p>Any exceptions thrown during evaluation of either predicate are relayed * to the caller; if evaluation of this predicate throws an exception, the * {@code other} predicate will not be evaluated. * * @param other a predicate that will be logically-ANDed with this * predicate * @return a composed predicate that represents the short-circuiting logical * AND of this predicate and the {@code other} predicate * @throws NullPointerException if other is null */ default Predicate<T> and(Predicate<? super T> other){ Objects.requireNonNull(other); return (t) -> test(t) && other.test(t); }
/** * Returns a predicate that represents the logical negation of this * predicate. * * @return a predicate that represents the logical negation of this * predicate */ default Predicate<T> negate(){ return (t) -> !test(t); }
/** * Returns a composed predicate that represents a short-circuiting logical * OR of this predicate and another. When evaluating the composed * predicate, if this predicate is {@code true}, then the {@code other} * predicate is not evaluated. * * <p>Any exceptions thrown during evaluation of either predicate are relayed * to the caller; if evaluation of this predicate throws an exception, the * {@code other} predicate will not be evaluated. * * @param other a predicate that will be logically-ORed with this * predicate * @return a composed predicate that represents the short-circuiting logical * OR of this predicate and the {@code other} predicate * @throws NullPointerException if other is null */ default Predicate<T> or(Predicate<? super T> other){ Objects.requireNonNull(other); return (t) -> test(t) || other.test(t); }
/** * Returns a predicate that tests if two arguments are equal according * to {@link Objects#equals(Object, Object)}. * * @param <T> the type of arguments to the predicate * @param targetRef the object reference with which to compare for equality, * which may be {@code null} * @return a predicate that tests if two arguments are equal according * to {@link Objects#equals(Object, Object)} */ static <T> Predicate<T> isEqual(Object targetRef){ return (null == targetRef) ? Objects::isNull : object -> targetRef.equals(object); } }
(2)例子
以前我们根据不同的条件筛选数据需要些多个方法,现在只要先定义一个这种接受行为的方法。
/** * @Author: cuzz * @Date: 2019/8/21 23:35 * @Description: Predicate test */ publicclassPredicateTest{ publicstaticvoidmain(String[] args){ List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); PredicateTest test = new PredicateTest();
// 查找奇数 test.findOdd(list); test.conditionFilter(list, i -> i % 2 != 0);
// 查找偶数 test.findEven(list); test.conditionFilter(list, i -> i % 2 == 0); }
publicvoidconditionFilter(List<Integer> list, Predicate<Integer> predicate){ for (int i : list) { if (predicate.test(i)) { System.out.print(i + " "); } } System.out.println(); }
publicvoidfindOdd(List<Integer> list){ for (int i : list) { if (i % 2 != 0) { System.out.print(i + " "); } } System.out.println(); }
publicvoidfindEven(List<Integer> list){ for (int i : list) { if (i % 2 == 0) { System.out.print(i + " "); } } System.out.println(); } }
(3)Predicate#and 和 Predicate#or
publicclassPredicateTest{ publicstaticvoidmain(String[] args){ List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); PredicateTest test = new PredicateTest();
// 查找 大于 3 的奇数 test.conditionFilter2(list, i -> i > 3, i -> i % 2 != 0); }
publicvoidconditionFilter2(List<Integer> list, Predicate<Integer> predicate1, Predicate<Integer> predicate2){ for (int i : list) { if (predicate1.and(predicate2).test(i)) { System.out.print(i + " "); } } System.out.println(); } }
Supplier
(1)不接受参数,返回一个值。
/** * Represents a supplier of results. * * <p>There is no requirement that a new or distinct result be returned each * time the supplier is invoked. * * <p>This is a <a href="package-summary.html">functional interface</a> * whose functional method is {@link #get()}. * * @param <T> the type of results supplied by this supplier * * @since 1.8 */ @FunctionalInterface public interface Supplier<T> {
/** * Gets a result. * * @return a result */ T get(); }