Java8 function interface description

1, functional programming  Introduction

Our most popular object-oriented programming (Java) belong to imperative programming (Imperative Programming) this programming paradigm. Common logic programming paradigm as well as programming (Logic Programming), functional programming (Functional Programming).

As a function of programming a programming paradigm, in the scientific field, a data structure and computer programming elements embodiment, the calculation process as it is a mathematical function evaluation, and change the status to avoid the variable data.

Functional programming is not a new technology or new ideas in recent years, from its birth has been about 50 years now. It has not been a mainstream programming thinking, but among the many so-called top-level programming expert scientists, functional programming is very popular.

What is functional programming?

The simple answer: Everything is a mathematical function. Functional programming languages ​​can have objects, but these objects are usually constant - either function parameters, function return value to what is. There is no functional programming language for / next loop, because the logic means that there is a change of state. Alternatively the phase, this cycle logic functional programming language is recursive, the function as a parameter passing mode of implementation.

For example: a = a + 1

This code appears in the ordinary members and no problem, but it seems really mathematician does not hold, because it means that the variable worth changing.

2, the interface function is defined

1, the annotation tag only on "one and only one abstract method" interface.

2, JDK8 interface static methods and the default method, is not regarded as abstract methods .

3, the interface default inherit java.lang.Object, so if the interface displays a statement covering the Object methods, so not too abstract methods.

4. This note is not required, if an interface matching "function interface" is defined, then did to the notes are not affected. Plus the notes to better allow the compiler to be checked. If writing is not functional interface, but added @FunctionInterface, then the compiler will complain.

 

 

In java8, any interface satisfying the following conditions are a function of interface:

 

1, the interface @FunctionalInterface annotation, the annotation satisfies the constraints @FunctionalInterface.

2, not @FunctionalInterface annotated interface, but satisfy the constraints @FunctionalInterface comment .

   

1, @FunctionalInterface comment constraint :

1, interfaces and only have an abstract method, only defined method, no method body .

2, public override Object class method in the interface, not a functional interface methods.

 

2, the function interface  example :

The following three interfaces are function interface

A Interface

@FunctionalInterface

public interface FunctionInterfaceTest {

 

String getInfo(String input);

 

@Override

String toString (); // Object Methods

 

@Override

boolean equals (Object obj); // Object Methods

}

Interface two

@FunctionalInterface

public interface FunctionInterfaceTest {

 

String getInfo(String input);

 

}

 

Interface three

public interface FunctionInterfaceTest {

 

String getInfo(String input);

 

}

 

3, create a functional interface instance

Creating functional interface instance, there are three ways:

1, the lambda expression;

2, a reference method;

3, reference constructor.

 

1, sample code

public class Main {

 

 public static void main(String[] args) {

 

       /**

   * 1, the lambda expression

   * This form most intuitive, lambda expressions, receiving a parameter of type String, returns a result of type String.

   * Fully functional interfaces meet the definition of FunctionInterfaceTest

   */

FunctionInterfaceTest functionInterfaceTest1 = item -> item+1;  

 

/**

 *  2, a reference method

 * Main getInstance method among method getMessage and receiving a parameter and returns a result. In line with functional interfaces

 * Define the FunctionInterfaceTest.

 * Function interface defines only a convention of a method (receiving a parameter of type String, returns a result of type String),

 * And what to do with it did not make any restrictions on the internal method. At this point, with between previous versions of java in the class that implements the interface

 * Relationship is very similar. The difference is, more on the interface function calculation, constraint input and output of a calculation.

 * This constraint benefits in the form of input and output of the calculation process can look at joinStr method.

 */

FunctionInterfaceTest functionInterfaceTest2 = Main :: getInstance; // reference method

FunctionInterfaceTest functionInterfaceTest3 = Main::getMessage;  //方法引用

 

String msg1 = joinStr ( "Hello", functionInterfaceTest2); // output: Hello! world

String msg2 = joinStr ( "Hello", functionInterfaceTest3); // output: Hello world!

System.out.println(msg1);

System.out.println(msg2);

 

// There are simpler wording, highly abstract, specific treatment is determined by the users themselves

String msg3 = joinStr ( "Hello", item -> item + "! World"); // output: Hello! world

String msg4 = joinStr ( "Hello", item -> "World," + item + "!"); // output: Hello world!

System.out.println(msg3);

System.out.println(msg4);

 

/**

 *  3, constructor references

 Constructor * structures: receiving an input parameter and returns an object. This constraint with functional constraints like interface.

 * So long as the "input parameter type" and "output parameter Type" in the same method with FunctionInterfaceTest constraints,

 * FunctionInterfaceTest can create an instance of the interface, as follows, there is the constructor String

 * New String (str) construction method, it is possible to give examples.

 * Here there is a problem of type inference, JDK compiler has helped us to automatically find only one parameter, and is of type String constructor.

 * This is the reason we direct String :: new, did not specify which constructor is used, it can create an instance of

 */

FunctionInterfaceTest functionInterfaceTest4 = String :: new; // reference method

 }

 

 public static String getInstance(String item){

 return item + "World!";

 }

 

 public static String getMessage(String massage){

 return "世界,"+ massage+"!";

 }

 

 public  static String joinStr(String str,FunctionInterfaceTest functionTest){

 return functionTest.getInfo(str);

 }

 

2, java8 commonly used function interface:

interface parameter Return Type description
Predicate<T> T boolean For determining an object. For example, ask whether a person is male
Consumer<T> T void For receiving an object is processed but is not returning, such a person receives and prints his name
Function<T, R> T R An object is converted to different types of objects
Supplier<T> None T It provides an object
UnaryOperator<T> T T Receiving object and returns the object of the same type, typically used to modify the properties of an object.
BinaryOperator<T> (T, T) T Receiving two objects of the same type, and a return type of the original object. It can be understood as the combined target

Used function interface are mainly four types , through its input and output to the parameter to distinguish the. Define the encoding process in the main usage scenarios.

​​​​​​​Function<T,R>   

Receiving a parameter of type T and returns a result of type R

Abstract interface method:

R apply(T t);

​​​​​​​Consumer<T>

Receiving a parameter of type T, does not return value

Abstract interface method:

  void accept(T t);

​​​​​​​Predicate<T>

Receiving a parameter of type T and returns a boolean result

Abstract interface method:

boolean test(T t);

​​​​​​​Supplier<T>

It takes no arguments, returns a result of type T.

Abstract interface method:

  T get();

The sample code

public class FunctionalInterfaceMain {

public static void main(String[] args) {

/**

 * Take a look at how to create them

 */

Function<String,String> function1 = item -> item +"返回值";

 

Consumer<String> function2 = iterm -> {System.out.println(iterm);};

// lambda statement, using braces, no return keyword, that there is no return value

 

Predicate<String> function3 = iterm -> "".equals(iterm);

 

Supplier<String> function4 = () -> new String("");

 

/**

 * Look at how to use

 * Demo Interpretation:

 * 1, to create a collection of type String

 * 2, the end of the additional element of the set of all strings '1'

 * 3, the string 2 of chosen length is greater than

 * 4, traversing the output of all the elements

 */

List<String> list = Arrays.asList("zhangsan","lisi","wangwu","xiaoming","zhaoliu");

 

list.stream()

.map (value -> value + "1") // Function is a function of the incoming interface

.filter (value -> value.length ()> 2) // incoming interface is a function Predicate

.forEach (value -> System.out.println (value)); // the incoming interface is a Consumer Function

}

}

 

3, receiving the two parameters of the interface functions

In actual use, we tend to enter multiple parameters, rather than an argument. Calculating a plurality of parameters for the final calculation two parameters can be split, and then the combined operation of the two parameters. Such as: 1 + 2 + 3 + 4 = 10, can be split into 3 = 1 + 2, 3 + 3 = 6; 6 + 4 = 10 in three steps (in java, a return multiple values ​​is not allowed of).

 

      Thus for a plurality of operating parameters as well. Java8 for receiving the two parameters of the scene to provide the relevant interface functions. as follows:

​​​​​​​BiFunction<T, U, R>   

Receiving type two parameters T and U type, it returns a result of type R.

Abstract interface method:

R apply(T t, U u);

​​​​​​​BiConsumer<T , U>

 Receiving two parameters T and U type type, no value is returned.

Abstract interface method:

void accept(T t, U u);

​​​​​​​BiPredicate<T, U>

Receiving type two parameters T and U type, returns a boolean result.

Abstract interface method:

boolean test(T t, U u);

The sample code

 public class FunctionalInterfaceTest {

 

public static void main(String[] args) {

 

 /**

  *  Bi type of interface to create

  */

 BiFunction<String, String, Integer> biFunction = (str1,str2) -> str1.length()+str2.length();

 

 BiConsumer<String, String> biConsumer = (str1,str2) -> System.out.println(str1+str2);

 

 BiPredicate<String, String> biPredicate = (str1,str2) -> str1.length() > str2.length();

 

 

 /**

  *  Of Bi type interface

  */

 int length = getLength("hello", "world", (str1,str2) -> str1.length() + str2.length()); //输出10

 boolean boolean1 = getBoolean("hello", "world", (str1,str2) -> str1.length() > str2.length()); //输出false

 

 System.out.println(length);

 System.out.println(boolean1);

 

 noResult("hello", "world", (str1,str2) -> System.out.println(str1+" "+str2)); //没有输出

 

 

}

 

public  static int getLength(String str1,String str2,BiFunction<String, String, Integer> function){

return function.apply(str1, str2);

}

 

public static void noResult(String str1,String str2,BiConsumer<String, String> biConcumer){

biConcumer.accept(str1, str2);

}

 

public static boolean getBoolean(String str1,String str2,BiPredicate<String, String> biPredicate){

return biPredicate.test(str1, str2);

}

}

 

       On using a plurality of parameter values, whether in Function interface, or in the type of interface BI provides similar operation. (Note: java8, the method is the interface can be achieved, but need to modify the default keyword, which is no other version of jdk characteristics)

 

 4, andThen method Function interface and compose methods

 

Source:

 

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));

}

Description:

 

       Compose Method: The method of receiving a Function type parameter and returns a value. This is also a standard definition Function type. There is also a method in inner compose apply method. Prior to apply the method to perform compose methods, which do an apply method before the interface, as well as input parameters compose method. Then compose the return value as input parameters apply method executed before method. Actually form a chain combination.

 

       andThen method: This method is very similar to the method and compose. Except that, andthen is to apply the method to perform its own, to apply the input value as the return value after the interface. The method with respect to compose, but in different directions

 

use:

 

public class FunctionalInterfaceTest {

 

public static void main(String[] args) {

 

 String str1 = getLength1 ( "hello", value -> "hello length:" + value, value -> value.length ()); // Output: hello length: 5

 System.out.println(str1);

 

 Integer result = getLength2("hello", value -> value, value -> value.length()); //输出:5

 System.out.println(result);

 

}

 

public  static String getLength1(String str1,Function<Integer, String> function1,Function<String,Integer> function2){

/**

 * Here we must note, function1 and function2 parameter types.

 * Output type function1 function2 the type of input must be consistent,

 * Otherwise, the compiler will not pass

 */

return function1.compose(function2).apply(str1);

}

 

public  static Integer getLength2(String str1,Function<String, String> function1,Function<String,Integer> function2){

/**

 * Here we must note, function1 and function2 parameter types.

 * And output type function1 function2 must be consistent with the type of input, (opposite directions)

 * Otherwise, the compiler will not pass

 */

return function1.andThen(function2).apply(str1);

}

}

 

Dependent Interface: BiFunction

 

public static Integer getLength3(String str1,String str2,BiFunction<String, String, String> biFunction,Function<String,Integer> function){

/**

 * BiFunction only andThen method, this is the type of interface features bi decisions.

 * Bi type of interface need to receive two parameters, but java is not returned in the case of two parameters

 * So only andThen method, and it is the function type of the parameter, a parameter received,

 * Return a value

 */

return biFunction.andThen(function).apply(str1, str2);

}

 

. 5, andthen method Consumer Interface

 

Source:

 

default Consumer<T> andThen(Consumer<? super T> after) {

        Objects.requireNonNull(after);

        return (T t) -> { accept(t); after.accept(t); };

}

Description:

       The input parameters are assigned accept method accept method and after the inside of the inside andThen. After calculation after andThen, played a role in the post-connection. Here no compose method because the post is in turn connected to the pre-connected, there is no need of an extra compose method. When only transmission, switching the order of two to the consumer.

 

use:

 

public class FunctionalInterfaceTest {

 

public static void main(String[] args) {

 

 noResult(Integer.valueOf(12),

 value -> {int num = value + 12;System.out.println(num);},

 value -> { int num = value + 24;System.out.println(num);}

 ); // output: 24, 36

 

}

 

public static void noResult(Integer num,Consumer<Integer> consumer1,Consumer<Integer> consumer2){

/**

 * Consumer receives two types must match

 */

consumer1.andThen(consumer2).accept(num);

}

}

Dependent Interface: BiConsumer

 

public static void noResultBi(Integer num1,Integer num2,BiConsumer<Integer,Integer> consumer1,BiConsumer<Integer,Integer> consumer2){

/**

 * Consumer receives two types must match

 */

consumer1.andThen(consumer2).accept(num1,num2);

}

 

. 6, and the predicateA interface, or, negate method

Source:

 

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);

}

 

Description:

 

       Source has been very clear, not setting them up. Are &&, ||, and negate operation.

 

use:

 

public class FunctionalInterfaceTest {

 

public static void main(String[] args) {

 

getBoolean("hello", value -> value.length() > 2, value -> value.length() > 6);

 

}

 

public static boolean getBoolean(String str1,Predicate< String> predicate1,Predicate< String> predicate2){

boolean test = predicate1.or(predicate2).test(str1);

System.out.println (test); // prints true

 

test = predicate1.and(predicate2).test(str1);

System.out.println (test); // false output

 

test = predicate1.negate().test(str1);

System.out.println (test); // false output

return test;

}

}

Dependent Interface: BiPreditcate

 

public static  boolean getBooleanBi(String str1,String str2,BiPredicate<String, String> biPredicate1,BiP时redicate1.and(biPredicate2).test(str1, str2);

test = biPredicate1.negate().test(str1, str2);

test = biPredicate1.or(biPredicate2).test(str1, str2);

return test;

}

 

       Further, java8 for native type int, long, double provides a corresponding interface function. Such as: DoubleConsumer, DoubleFunction, IntConsumer etc., use the same, see java.util.function package.

Published 13 original articles · won praise 1 · views 7822

Guess you like

Origin blog.csdn.net/weixin_40482816/article/details/87618120