Java8 de interfaz para funciones

Java8 agregó una nueva función característica, es una interfaz de la función

Todas las interfaces @FunctionalInterface anotación marcada es interfaces funcionales, específicamente, todos marcados con la interfaz de anotación serán utilizados en la expresión lambda.
Mira la fuente

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
    /**
     * @return a composed function that first applies the {@code before}
     * function and then applies this function
     */
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }
    /**
     * @return a composed function that first applies this function and then
     * applies the {@code after} function
     */
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }
    /**
     * 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;
    }
}

Una instancia
de este tipo de funciones de interfaz, porque sólo una función de abstracción, siempre que es posible realizar la función de la instancia de objeto. Es posible instanciar una objetos "interfaz" a través de esta línea de código siguiente manera:
Por ejemplo:

Function<Integer, Integer> fun = x -> x + 1;

En el que el signo igual (=) es el lado derecho de la implementar los métodos de función resumen interfaz. En vista de esto, se puede concluir:
una interfaz de función, como una expresión de la forma (x -> x + 1) puede instanciar un objeto. Y la expresión es la constatación de que los métodos sólo abstractos.

Fuente determinación
1. aplicar
terminó en la parte superior de éstos se puede empezar a estudiar el código fuente.
En primer lugar, ya sabemos función es una clase genérica, que define los dos parámetros genéricos T y R, en la función, T representa los parámetros de entrada, el resultado R representa regresó. Tal vez usted es curioso, ¿por qué no lo mismo con el otro código fuente de Java, la función del código fuente no es la lógica específica de la misma?
De hecho, esto es fácil de entender, la función es una función, su función es similar a la definición de una función matemática,
(los ejes X, el y-) es casi lo mismo con <T, R> rol.

y=f(x)

La función no es la operación de manera específica, la operación específica que necesitamos definir para ella, y por lo tanto aplicar los resultados de los rendimientos específicos depende de la expresión lambda entrante.

R apply(T t);

Por ejemplo:

public void test(){
    Function<Integer,Integer> test=i->i+1;
    test.apply(5);
}
/** print:6*/

Definimos una expresión lambda con un comportamiento tal que i se incrementa en uno, utilizamos parámetros se aplican 5 ejecución, y finalmente volver 6. Se utilizó para mirar esto con los ojos de Java ha sido diferente en la programación funcional Antes de definir un conjunto de operaciones de primera idea es definir un método y especifique los parámetros pasados ​​y devuelve el resultado que necesitamos. idea de la programación funcional es la de no tener en cuenta el comportamiento específico, pero para ir a considerar parámetros formas específicas que podemos seguir otro conjunto.

Otro ejemplo:

public void test(){
    Function<Integer,Integer> test1=i->i+1;
    Function<Integer,Integer> test2=i->i*i;
    System.out.println(calculate(test1,5));
    System.out.println(calculate(test2,5));
}
public static Integer calculate(Function<Integer,Integer> test,Integer number){
    return test.apply(number);
}
/** print:6*/
/** print:25*/

Pasamos a través de diferentes funciones, dimos cuenta de sus diferentes operaciones en el mismo método. Esto puede reducir en gran medida el desarrollo real de una gran cantidad de código duplicado, por ejemplo, tengo un nuevo usuario dispone en el proyecto actual, pero los usuarios se dividen en usuarios VIP y ordinarias, y hay dos nuevos lógica diferente. Así que esta vez vamos a ser capaces de escribir dos lógica diferente. Además, esto también permite que la lógica y datos separados, podemos lograr multiplexación lógica.

Por supuesto, el desarrollo real de la lógica puede ser compleja, tal como dos métodos F1, F2 requiere dos AB lógico, pero necesidad F1 A-> B, el método F2 requiere B-> A. Esto se puede lograr por el método que se acaba, el código fuente es el siguiente:

public void test(){
    Function<Integer,Integer> A=i->i+1;
    Function<Integer,Integer> B=i->i*i;
    System.out.println("F1:"+B.apply(A.apply(5)));
    System.out.println("F2:"+A.apply(B.apply(5)));
}
/** F1:36 */
/** F2:26 */

También es muy simple, pero esto no es bastante complicada, si F1, F2 requieren cuatro ABCD lógica, entonces nosotros también hemos escrito será muy problemático.
Entiende que se aplica la final R (T t) -> función se aplica a los parámetros de entrada de objeto, y muestra el resultado
2.compose y andthen
Componer y andthen resolver nuestro problema. Mira fuente de redacción

default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

parámetros de la función componen recibir una primera ejecución de la lógica se aplica entrante, a continuación, utilizando la función de retorno se aplican actual.

default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

andthen ahora componen el contrario, la primera ejecución de la lógica actual, a continuación, ejecutar la lógica de entrada.

Decir esto puede no ser intuitiva, te puedo dar un vistazo a él de otra manera

B.compose (A) .apply (. 5)
de composición equivalente B.apply (A.apply (. 5)),
B.andThen (A) .apply (. 5))
y es equivalente a andthen A.apply (B. aplicar (5)).

public void test(){
    Function<Integer,Integer> A=i->i+1;
    Function<Integer,Integer> B=i->i*i;
    System.out.println("F1:"+B.apply(A.apply(5)));
    System.out.println("F1:"+B.compose(A).apply(5));
    System.out.println("F2:"+A.apply(B.apply(5)));
    System.out.println("F2:"+B.andThen(A).apply(5));
}
/** F1:36 */
/** F1:36 */
/** F2:26 */
/** F2:26 */

Podemos ver el valor de retorno de los dos métodos es una función, por lo que podemos utilizar el modo de funcionamiento del constructor para su uso.
B.compose (A) .andThen (A) .apply (5);
de la mirada hacia el futuro, mirada andthen (A) primera realización A, i = i + 1 = 6, y luego buscar B.compose (A) primera aplicación B
I = I la I = 36 y luego ejecutados. 1 I = I A = 37 [+
B.andThen (A) .compose (A) .apply (. 5)
desde el delantero trasero, aspecto de composición (A) primera realización de B .compose (a), a continuación, B.compose (a) en la primera implementación de un
I = I + realiza de nuevo. 6. 1 = I = I B
I = 36, a continuación, realizar una i realiza Componer (a) = I = 37 [+. 1
. 3 la identidad método
Java 8 permite la adición de un método específico en la interfaz. Hay dos, método por defecto y el método estático, método de identidad () es una interfaz específica integrada Función método estático.
Function.identity () devuelve un Expresiones lambda como meta de producción de entrada, lo que equivale a la forma t -> t expresiones lambda de la forma

static <T> Function<T, T> identity() {
        return t -> t;
    }

Referencia:
Exploración de Java8 :( ii) el uso de funciones de interfaz
de función de interfaz de JDK8

Publicado 80 artículos originales · ganado elogios 140 · vistas 640 000 +

Supongo que te gusta

Origin blog.csdn.net/linjpg/article/details/102544027
Recomendado
Clasificación