[Java] Interfaz funcional de nuevas características de JDK8

Inserte la descripción de la imagen aquí

Original: http://www.javastack.cn/article/2017/jdk8-new-feature-functional-interface/

Que es una interfaz funcional

Primero echemos un vistazo a cómo se escribe la creación de hilo tradicional

Thread t1 = new Thread(new Runnable() {
	@Override
	public void run() {
		System.out.println("t1");
	}
});
t1.start();

Echemos un vistazo a cómo escribir una interfaz funcional

Thread t2 = new Thread(() -> System.out.println("t2"));
t2.start();

La interfaz Runnable se puede escribir directamente usando expresiones Lambda. Esto se debe a que la interfaz Runnable es una interfaz funcional. Echemos un vistazo al código fuente de Runnable.

@FunctionalInterface
public interface Runnable {

    public abstract void run();
    
}

Se encuentra que la interfaz se ha agregado con una anotación de definición de interfaz funcional: @FunctionalInterface, que indica que la interfaz es una interfaz funcional.

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {
    
}

En JDK8, además de la interfaz Runnbale, también existen interfaces como Comparator, Callable, etc., que se definen como interfaces funcionales con esta anotación.

Interfaz funcional
incorporada JDK8 proporciona varias interfaces funcionales incorporadas, que se pueden utilizar en muchos lugares de API y pueden satisfacer la mayoría de las aplicaciones.

//Consumer<T> - T作为输入,执行某种动作但没有返回值
Consumer<String> con = (x) -> {
	System.out.println(x);
};
con.accept("hello world");

//Supplier<T> - 没有任何输入,返回T
Supplier<String> supp = () -> {
	return "Supplier";
};
System.out.println(supp.get());

//Predicate<T> -T作为输入,返回的boolean值作为输出
Predicate<String> pre = (x) -> {
	System.out.print(x);
	return x.startsWith("op");
};
System.out.println(": " + pre.test("op, hello World"));

// Function<T, R> -T作为输入,返回的R作为输出
Function<String, String> function = (x) -> {
	System.out.print(x + ": ");
	return "Function";
};
System.out.println(function.apply("hello world"));

//BinaryOperator<T> -两个T作为输入,返回一个T作为输出,对于“reduce”操作很有用
BinaryOperator<String> bina = (x, y) -> {
	System.out.print(x + " " + y);
	return "BinaryOperator";
};
System.out.println("  " + bina.apply("hello ", "world"));

Interfaz funcional personalizada

1. Personaliza una interfaz funcional

@FunctionalInterface
public interface CalcInterface<N, V> {	
	V operation(N n1, N n2);
}

Aquí solo hay un método abstracto. No es necesario escribir la anotación @FunctionalInterface. En cuanto a por qué puede mirar hacia abajo.

2. Cree una nueva clase que haga referencia a una interfaz funcional

public static class NumberOperation<N extends Number, V extends Number> {

	private N n1;
	private N n2;

	public NumberOperation(N n1, N n2) {
		this.n1 = n1;
		this.n2 = n2;
	}

	public V calc(CalcInterface<N, V> ci) {
		V v = ci.operation(n1, n2);
		return v;
	}

}

3. Pruebe la interfaz funcional

private static void testOperationFnInterface() {
        NumberOperation<Integer, Integer> np = new NumberOperation(13, 10);
    
	CalcInterface<Integer, Integer> addOper1 = (n1, n2) -> {
		return n1 + n2;
	};
	CalcInterface<Integer, Integer> multiOper1 = (n1, n2) -> {
		return n1 * n2;
	};
	System.out.println(np.calc1(addOper1));
	System.out.println(np.calc1(multiOper1));
	
	// 上面的可以简写为
	System.out.println(np.calc1((n1, n2) -> n1 + n2));
	System.out.println(np.calc1((n1, n2) -> n1 * n2));
}

El resultado final:

23
130
23
130

Especificación de interfaz funcional

1. @FunctionalInterface indica que una interfaz funcional solo se puede utilizar en una interfaz con un solo método abstracto.

2. Los métodos estáticos, los métodos predeterminados y los métodos que anulan la clase Object en la interfaz no se consideran métodos abstractos.

3. La anotación @FunctionalInterface no es necesaria. Si la interfaz tiene solo un método abstracto, no es necesario escribirlo. Se ajusta a la interfaz funcional por defecto, pero se recomienda escribir esta anotación. El compilador verificará si la interfaz cumple con la especificación de interfaz funcional.

Dé ejemplos para ilustrar la
interfaz funcional correcta.

@FunctionalInterface
public interface CalcInterface<N, V> {	
	V operation(N n1, N n2);
}

Está bien agregar algunos métodos que se ajusten a la función y el compilador no informará de un error.

@FunctionalInterface
public interface CalcInterface<N, V> {		

	V operation(N n1, N n2);
   
	public boolean equals(Object object);

	public default void defaultMethod() {

	}

	public static void staticMethod() {

	}
}

Esta interfaz funcional @FunctionalInterface inútil tiene dos métodos abstractos que no se pueden usar en expresiones Lambda.

public interface CalcInterface<N, V> {	
	V operation(N n1, N n2);
	V operation2(N n1, N n2);
}

La interfaz funcional anotada con @FunctionalInterface con dos métodos abstractos informará un error cuando se compile.

@FunctionalInterface
public interface CalcInterface<N, V> {	
	V operation(N n1, N n2);
	V operation2(N n1, N n2);
}

No existe un método abstracto para esto y se informan los errores de compilación.

public interface CalcInterface<N, V> {	
}

Supongo que te gusta

Origin blog.csdn.net/qq_21383435/article/details/108492967
Recomendado
Clasificación