Java 8 functional interfaces and Lambda study notes (b)

Part blog Java 8 Lambda study notes (a) primary records related knowledge Lambda expressions, this blog will focus on the function interface .

Front also said, in fact, is essentially a function interface or an interface, but it is a special interface: SAM type of interface (Single Abstract Method).

Interface function has three properties:

1. The interface is only an abstract method, and no more, nor less.

2. You can have static methods and the default method, because both methods are already implemented a.

3. The abstract method must not be the same name with the Object class method.

@FunctionalInterface
interface Fun{
	//只设置一个抽象方法 ------可以正常运行
	abstract int spend(int remaining,int money);
	
	//加入静态方法和默认方法 ----可以正常运行
	static void staticMethod() {
		System.out.println("There is a static method!");
	}
	default void defaultMethod() {
		System.out.println("There is a default method!");
	}
	
	//设置Object中可以重写的抽象方法 ----编译报错
//	abstract boolean equals(Object obj);
	
}

Java 8 new feature provides a function interface, in order to better support functional programming. Java also provides annotations @FunctionalInterface , marked the annotation interface, the compiler will automatically help us check if the interface conforms to the format functional interface.

Lambda expressions with the specific use

Function interface is used to support the use of the Lambda represented. That is, the function interface of a custom parameter Lambda expressions corresponding thereto is the default parameter abstract method, this default value is the abstract returns the return value. 

package com.wjb.lambda;
/**
 * 函数式接口:
 * 		1.只能有一个抽象方法
		2.可以有静态方法和默认方法,因为这两种方法都是已经实现的了
		3.这个抽象方法一定不能跟Object类中的方法同名。
 * @author Administrator
 *
 */
@FunctionalInterface
interface Fun{
	//只设置一个抽象方法 ------可以正常运行
	abstract int spend(int remaining,int money);
	
	//加入静态方法和默认方法 ----可以正常运行
	static void staticMethod() {
		System.out.println("There is a static method!");
	}
	default void defaultMethod() {
		System.out.println("There is a default method!");
	}
	
	//设置Object中可以重写的抽象方法 ----编译报错
//	abstract boolean equals(Object obj);
	
}
public class FunInterface{
	public static void main(String[] args) {
		Fun fun = (a,b) -> (a-b); //参数就是spend()方法的参数,返回值a-b就是spend()方法的返回值
		System.out.println(fun.spend(100, 5));
	}
}

 Five common function interface

java function interface provided java.util.function package, the more important are the following five interfaces. I think these interfaces jdk8 provided us is that it provides some of the patterns (to help us out some abstract behavior), were achieved when used according to the official abstract interface is also more convenient. 

1.Consumer (consumption patterns)

Function : As the name suggests, is to consume a generic object is passed, it does not return any value. That this interface has any practical use scenario? In fact, if you look at the underlying code foreach method, then the parameters required for this method must be a Consumer interface type parameters.

View Consumer Interface source code can know that the only way is to abstract

void accept(T t);

The following write an example to run it:

/**	
     * consumer接口测试	
     */	
    @Test	
    public void test_Consumer() {	
        //1. 使用consumer接口实现方法	
        Consumer<String> consumer = new Consumer<String>() {	
	
            @Override	
            public void accept(String s) {	
                System.out.println(s);	
            }	
        };	
        Stream<String> stream = Stream.of("aaa", "bbb", "ddd", "ccc", "fff");	
        stream.forEach(consumer);	
	
        System.out.println("********************");	
	
        //2.使用lambda表达式,forEach方法需要的就是一个Consumer接口	
        stream = Stream.of("aaa", "bbb", "ddd", "ccc", "fff");	
        Consumer<String> consumer1 = (s) -> System.out.println(s);//lambda表达式返回的就是一个Consumer接口	
        stream.forEach(consumer1);	
        //更直接的方式	
        //stream.forEach((s) -> System.out.println(s));	
        System.out.println("********************");	
	
        //3.使用方法引用,方法引用也是一个consumer	
        stream = Stream.of("aaa", "bbb", "ddd", "ccc", "fff");	
        Consumer consumer2 = System.out::println;	
        stream.forEach(consumer);	
        //更直接的方式	
        //stream.forEach(System.out::println);	
    }

Code analysis shows:

In Listing 1, we created directly Consumer interface, and implements a method called accept, and when we found  forEach the need for a Consumer types of parameters when after passing, you can output the corresponding value. 2 code, we use lambda expressions as Consumer. Carefully look you will find, lambda expression return value is a Consumer; so, you will be able to understand why the  forEach method can be used lamdda expression as an argument instead.

Code 3, we used a method reference aspect as a Consumer, also be passed to  forEach the method.

Of course, in addition to the above-Consumer interface, the following may be used Consumer these interfaces. Using the same method as above.IntConsumerDoubleConsumerLongConsumerBiConsumer

After reading the above examples we can be summarized as two points.

① Consumer is an interface, and as long as the realization of a  accept method, can be used as a "consumer" output.
forEach method parameters must Consumer types, so long as lambda expressions, method return values quoted in line with Consumer types, they can be used as  forEach method parameters, and outputs a value.

 

2.Supplier (production model)

Function : the Consumer Interface contrast, Supplier interfaces is not pass parameters, return only one value. Let's look at the source code

T get();

Can be understood, it does not accept any parameters and returns a value, what is the value returned is determined by what the caller ---- Lambda expressions maker. In fact, it means a container that can be used to store data, then such an interface can be used for other methods used.

The following concrete realization of it:

**	
     * Supplier接口测试,supplier相当一个容器或者变量,可以存储值	
     */	
    @Test	
    public void test_Supplier() {	
        //① 使用Supplier接口实现方法,只有一个get方法,无参数,返回一个值	
        Supplier<Integer> supplier = new Supplier<Integer>() {	
            @Override	
            public Integer get() {	
                //返回一个随机值	
                return new Random().nextInt();	
            }	
        };	
	
        System.out.println(supplier.get());	
	
        System.out.println("********************");	
	
        //② 使用lambda表达式,	
        supplier = () -> new Random().nextInt();	
        System.out.println(supplier.get());	
        System.out.println("********************");	
	
        //③ 使用方法引用	
        Supplier<Double> supplier2 = Math::random;	
        System.out.println(supplier2.get());	
    }

We create a Supplier objects, implements a  get method that has no parameters and returns a value; therefore, each time using this interface will return a value, and stored in the interface, so that is a container .

 Here we look at Supplier specific usage scenarios:

/**	
     * Supplier接口测试2,使用需要Supplier的接口方法	
     */	
    @Test	
    public void test_Supplier2() {	
        Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);	
        //返回一个optional对象	
        Optional<Integer> first = stream.filter(i -> i > 4)	
                .findFirst();	
	
        //optional对象有需要Supplier接口的方法	
        //orElse,如果first中存在数,就返回这个数,如果不存在,就放回传入的数	
        System.out.println(first.orElse(1));	
        System.out.println(first.orElse(7));	
	
        System.out.println("********************");	
	
        Supplier<Integer> supplier = new Supplier<Integer>() {	
            @Override	
            public Integer get() {	
                //返回一个随机值	
                return new Random().nextInt();	
            }	
        };	
	
        //orElseGet,如果first中存在数,就返回这个数,如果不存在,就返回supplier返回的值	
        System.out.println(first.orElseGet(supplier));	
    }	

Optional use of a subject acquired, then there is need orElseGet orElse method and a Supplier Optional interface in a subject. 

  • orElse: If there are several first in the number of returns, and if not, to put back the incoming number

  • orElseGet: If there are several first in the number of returns, and if not, it returns the value returned by supplier

In addition to the above-Supplier interface, the following may also be used such Supplier interfaces.
IntSupplier 、DoubleSupplier 、LongSupplier 、BooleanSupplierUsing the same method as above.

Supplier summary

① Supplier interface may be understood as a container for containing the data.
② Supplier interface has a  get method, return values.

 

3.Predicate ( Analyzing Mode - predicate )

Function : passing an argument and returns a Boolean value. In fact, this is a similar judgment bool type of interface.

 

Or look at an example

/**	
     * Predicate谓词测试,谓词其实就是一个判断的作用类似bool的作用	
     */	
    @Test	
    public void test_Predicate() {	
        //① 使用Predicate接口实现方法,只有一个test方法,传入一个参数,返回一个bool值	
        Predicate<Integer> predicate = new Predicate<Integer>() {	
            @Override	
            public boolean test(Integer integer) {	
                if(integer > 5){	
                    return true;	
                }	
                return false;	
            }	
        };	
	
        System.out.println(predicate.test(6));	
	
        System.out.println("********************");	
	
        //② 使用lambda表达式,	
        predicate = (t) -> t > 5;	
        System.out.println(predicate.test(1));	
        System.out.println("********************");	
	
    }

This code, create an  Predicate interface object, wherein the implementation class  test methods, need to pass a parameter and return a  bool value, so the effect of the interface is determined ! Then, call the test method, passing a value, it will return a bool value. You can also use a lambda expression returns  Predicate the interface, and then call the  test method!

Well, we look at an example to see Predicate specific usage scenarios:

/**	
     * Predicate谓词测试,Predicate作为接口使用	
     */	
    @Test	
    public void test_Predicate2() {	
        //① 将Predicate作为filter接口,Predicate起到一个判断的作用	
        Predicate<Integer> predicate = new Predicate<Integer>() {	
            @Override	
            public boolean test(Integer integer) {	
                if(integer > 5){	
                    return true;	
                }	
                return false;	
            }	
        };	
	
        Stream<Integer> stream = Stream.of(1, 23, 3, 4, 5, 56, 6, 6);	
        List<Integer> list = stream.filter(predicate).collect(Collectors.toList());	
        list.forEach(System.out::println);	
	
        System.out.println("********************");	
	
    }

This code, first create a Predicate object, and then implement  test the method, do a test method to determine: if the incoming parameter is greater than 5, it returns true, otherwise return false ; then call  Stream the  filter method, filter the method required parameter is the Predicate Interface , so long as there is greater than 5 data will be output.

Summarize two points:

① Predicate is a predicate type interface, in fact, only play the role of a judge.
② Predicate achieved by a  test making a judgment method.

 

4. Function (Function Mode)

Function : passing an argument and returns an argument. Function is to convert the role of the input data into another form of output data.

The first instance:

/**	
     * Function测试,function的作用是转换,将一个值转为另外一个值	
     */	
    @Test	
    public void test_Function() {	
        //① 使用map方法,泛型的第一个参数是转换前的类型,第二个是转化后的类型	
        Function<String, Integer> function = new Function<String, Integer>() {	
            @Override	
            public Integer apply(String s) {	
                return s.length();//获取每个字符串的长度,并且返回	
            }	
        };	
	
        Stream<String> stream = Stream.of("aaa", "bbbbb", "ccccccv");	
        Stream<Integer> stream1 = stream.map(function);	
        stream1.forEach(System.out::println);	
	
        System.out.println("********************");	
	
    }

Is output: 357

The above code creates an  Function interface object, implements a  apply method that has an input parameter and an output parameter. Wherein the first parameter is a generic type before converting, after the second type is converted.

In the above code, is to obtain the length of the string, then the length of each string is returned as a return value.

In  Function an important application interfaces I have to say that  Stream the class  map method, the map method passing a  Function port, return a converted  Streamclass.

In addition to the above-Function interface, the following may also be used such Function interfaces.
IntFunction, DoubleFunction, LongFunction, ToIntFunction, ToDoubleFunction, DoubleToIntFunction the like, using the same method as above.

 in conclusion:

① Function Interface is a functional interface is a converted effect data.
② Function interface  apply method to do the conversion.

 

5.BiXXXX (BiFunction for example)

Function : pass two parameters to obtain a return value. 

The only way is to abstract apply.

 R apply(T t, U u);

Let's look at an example:

public class FunctionTest {

    public static void main(String[] args) {


        BiFunction<Integer,Integer,Integer>  biFunction= (i1,i2) -> i1+i2;

        System.out.println(biFunction.apply(1,2));
    }
}

 BiFuntion first two input parameters is the type Integer, Integer is a final result of the parameter type.

 

 

references

Lambda expressions and functional interfaces

Interview hung up, you understand the Java Consumer, Supplier, Predicate and Function 8 do?

Published 61 original articles · won praise 9 · views 30000 +

Guess you like

Origin blog.csdn.net/qq_33204444/article/details/105024889