Day 28 functional interface

Day 28

1. Functional interface

1.1 overview

	If there is only one method for an interface, and the dry method is an abstract method with a default attribute, the interface is called a functional interface.
	You can directly use the new feature of JDK 1.8, Lambda expression to use
	
	Lambda expression vs. anonymous inner class
		1. Simplified code structure
		2. Save memory resources
		3. Let programmers pay more attention to what I want to do, rather than what I need to accomplish in order to do it

1.2 use @ functional interface

Be similar to
	@Override enable strict check of code rewrite format

1.3 using functional interfaces

Using functional interfaces in code
	1. Make the program more purposeful
	2. Provide the value of reuse and universality
	3. Save resources

2. Functional programming idea

2.1 Lambda delay execution

There will be a level limit on whether to save the log
 Here we need a functional interface. The return value type is String, and others don't matter.
/**
 * Using functional interface to complete Log logging
 *
 * @author Anonymous 2020/3/11 10:53
 */
public class Demo2 {
    public static void main(String[] args) {
        String msg1 = "Abnormal position XXX,";
        String msg2 = "Abnormal problem XXX,";
        String msg3 = "Abnormal time XXX";

        log(Level.LOWER, () -> {
            System.out.println("Lambda Expression execution!!!");
            return msg1 + msg2 + msg3;
        });
    }

    /**
     * Determine whether to log according to the log Level
     *
     * @param level Level Enumeration type with three data HIGH MIDDLE LOWER
     * @param lm LogMessage Parameters of functional interface method
     */
    public static void log(Level level, LogMessage lm) {
        /*
        It is found that when the Level level is HIGH, execute the corresponding lm.returnLogMessage();
        Level Level is not HIGH does not perform the corresponding method.

        Lambda The problem of execution delay is not that Lambda executes slowly, but that there is an extra judgment before execution
        The corresponding code can only be executed after judgment.
            Not executing the code string will not result in the waste of resources caused by splicing, thus improving efficiency.
         */
        if (Level.HIGH == level) {
            // Get the corresponding returnLogMessage() method through the functional interface
            System.err.println(lm.returnLogMessage());
        }
    }

    public static void testEnum(int level) {
        if (Level.HIGH.getStatus() == level) {

        }
    }
}

2.2 Lambda as method parameter and return value

Comparator interface provided in Java < T >
	Using some return values as the adjustment of operation in the method
	
public interface Comparator<T> {
	int compare(T o1, T o2);
}

3. Common functional interfaces provided in Java

3.1 overview of common functional interfaces of JDK

java.util.function package name. Many functional interfaces are provided
	Standardized some operations, improved the development efficiency, more focused on the purpose!!!
	
	Supplier < T > producer, return a specified type of data
	Consumer < T > consumer, consuming a specified type of data
	Predict < T > judge and adjust, filter and use
	Function < T, R > type conversion, convert to corresponding type R according to the type t you specify

3.2 Supplier producer, return a specified data type

java.util.function.Supplier<T>
	There is and only one way
		T get();
		No parameter required, return the specified T type data
		Don't eat anything. All you squeeze is output...
package com.qfedu.c_supplier;

import com.qfedu.b_lambda.Level;

import java.util.function.Supplier;

/**
 * Supplier Functional interface demonstration
 *
 * @author Anonymous 2020/3/11 14:44
 */
public class Demo1 {
    public static void main(String[] args) {
        String msg1 = "Abnormal position XXX,";
        String msg2 = "Abnormal problem XXX,";
        String msg3 = "Abnormal time XXX";

        /*
        What we need here is a functional interface, directly passing in a lambda expression
         */
        log(Level.HIGH, () -> {
            System.out.println("Lambda Expression execution!!!");
            return msg1 + msg2 + msg3;
        });

        /*
        Lambda Expression optimization
         */
        log(Level.HIGH, () -> msg1 + msg2 + msg3);
    }

    /**
     * Determine whether to log according to the log Level
     *
     * @param level Level Enumeration type with three data HIGH MIDDLE LOWER
     * @param supplier Supplier Functional interface, using T get() to complete the data operation
     */
    public static void log(Level level, Supplier<String> supplier) {
        /*
        Supplier The function interface uses the get method to provide the corresponding operation to return the specified String type data
         */
        if (Level.HIGH == level) {
            // Get the corresponding returnLogMessage() method through the functional interface
            System.err.println(supplier.get());
        }
    }
}
Introduce the use of functional interface to meet more general codes
package com.qfedu.c_supplier;

import java.util.function.Supplier;

/**
 * Demonstrate the use of Supplier functional interface, and its ability to expand methods and
 * Universal satisfaction
 *
 * @author Anonymous 2020/3/11 15:06
 */
public class Demo3 {
    public static void main(String[] args) {
        Integer[] array = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};

        Integer max = getMax(array, () -> {
            Integer temp = array[0];

            for (int i = 1; i < array.length; i++) {
                if (temp < array[i]) {
                    temp = array[i];
                }
            }

            return temp;
        });

        System.out.println(max);

        System.out.println("-------------------------------------------");

        Person[] persons = {new Person(1, "Luo Lei", 16),
                new Person(2, "black person", 66),
                new Person(3, "Old payment", 36),
                new Person(4, "fairly tall", 26),
                new Person(5, "Foul cloud", 96),
                new Person(6, "Handsome", 106)
        };

        Person max1 = getMax(persons, () -> {
            Person p = persons[0];

            for (int i = 1; i < persons.length; i++) {
                if (p.getAge() < persons[i].getAge()) {
                    p = persons[i];
                }
            }

            return p;
        });

        System.out.println(max1);
    }

    /**
     * Find the largest data in any type of array
     *
     * @param arr Array of any type, while constraining the usage rules of current generics
     * @param sup Supplier Function interface, to use get method to return specified T type data
     * @param <T> generic paradigm
     * @return Data consistent with array type
     */
    public static <T> T getMax(T[] arr, Supplier<T> sup) {
        return sup.get();
    }
}

3.3 Consumer, processing data

Consumer<T>
	The method of operation is
	void accept(T t);
		Receive the corresponding data according to the data type specified by the interface, process and consume it, and there is no external return
		As for the process of processing, display, processing, calculation...
package com.qfedu.d_consumer;

import java.util.function.Consumer;

/**
 * Using Consumer to process data
 *
 * @author Anonymous 2020/3/11 15:24
 */
public class Demo1 {
    public static void main(String[] args) {
        // The method requires a String type parameter and uses the Consumer interface to process data
        // Because the Consumer interface is a functional interface, you can use Lambda expressions
        testConsumer("Kung Pao Chicken,Braised Beef Brisket with Tomato,Beef in Brown Sauce,Braised chicken and rice", (str) -> {
            String[] split = str.split(",");
            for (String s : split) {
                System.out.println(s);
            }
        });
    }

    /**
     * Give the current method a String type, and complete the corresponding through the accept method in the Consumer functional interface
     * string manipulation
     *
     * @param str String Type string
     * @param consumer Consumer Functional interface for data processing
     */
    public static void testConsumer(String str, Consumer<String> consumer) {
        consumer.accept(str);
    }
}

andThen

package com.qfedu.d_consumer;

import java.util.function.Consumer;

/**
 * Consumer Interface andThen use
 * Two Consumer interfaces are required, and the two Consumer interfaces are combined for data consumption
 *
 * andThen(Consumer<T> con)
 *      Invocation format
 *          con1.andThen(con2).accept(T t);
 *          Equivalent to the following operation
 *          con1.accept(t);
 *          con2.accept(t);
 *
 * @author Anonymous 2020/3/11 15:57
 */
public class Demo2 {
    public static void main(String[] args) {
        /*
        This method requires two Consumer functional interfaces, where two Lambda expression operations can be used
         */
        testAndThen("Zhengzhou refueling!!!Go China!!!",
                (str) -> System.out.println(str)
                ,
                (str) -> System.err.println(str)
                );
    }

    /**
     * Two Consumer methods are used to process str data. The first is to process the data with con1 and then with con2
     *
     * @param str  String type data to be processed
     * @param con1 Consumer<String> Handle String type functional interface
     * @param con2 Consumer<String> Handle String type functional interface
     */
    public static void testAndThen(String str, Consumer<String> con1, Consumer<String> con2) {
        /*
        con1.accept(str);
        con2.accept(str);

        Allow Combo
        con1.andThen(con2).andThen(con1).andThen(con2).andThen(con1).andThen(con2).accept(str);
        */
        con1.andThen(con2).accept(str);
    }
}

3.4 predict to judge whether the data is suitable, and return true/false

Predict < T > is generally used to adjust judgment and filter data
	Methods specified in functional interfaces
	boolean test(T t);
		Handle T type data, return boolean true / false
package com.qfedu.e_predicate;

import java.util.function.Predicate;

/**
 * Demonstrate basic use of predicate < T >
 *      boolean test(T t)
 *
 * @author Anonymous 2020/3/11 16:11
 */
public class Demo1 {
    public static void main(String[] args) {

        // Predict functional interface, using Lambda expression as parameter of method
        boolean b = testPredicate("Zhengzhou Origo!!!China orligan!!!",
                (str) -> {
                    return str.contains("Come on");
                });

        System.out.println("ret : " + b);

        System.out.println("---------------------------");

        /*
        Optimize Lambda expressions,
            Because it's a parameter, parentheses can be omitted
            For one line of code, braces can be omitted
            return It can also be omitted
         */
        testPredicate("Zhengzhou Origo!!!China orligan!!!", str -> str.contains("Come on"));
    }

    /**
     * Use the predict function interface to use the boolean test(T t) to judge the current data,
     * Return boolean type data
     *
     * @param str String type string to judge data
     * @param pre Handle using the predict functional interface
     * @return Judge whether the interface meets the requirements, return true if it meets the requirements, return false if it does not meet the requirements
     */
    public static boolean testPredicate(String str, Predicate<String> pre) {
        return pre.test(str);
    }
}

And and

package com.qfedu.e_predicate;

import java.util.function.Predicate;

/**
 * Predicate and Use
 * default Modification method add (predicate < T > pre)
 *      and It's in logical operators&&
 *      If the same truth is true, there is a false [i.e.] false
 *      Two predictes need to be judged
 *
 *      For example:
 *          pre1.test(str) && pre2.test(srt);
 *          ==> pre1.and(pre2).test(str);
 *
 * @author Anonymous 2020/3/11 16:19
 */
public class Demo2 {
    public static void main(String[] args) {

        /*
        Here you need to use the predict interface, which uses Lambda
         */
        boolean ret = testAnd("Get back to work now, don't do anything!!!",
                str -> str.length() > 5,
                str -> str.startsWith("Hurry up"));

        System.out.println(ret);
    }

    /**
     * Combinatorial judgement
     *
     * @param str  String to judge
     * @param pre1 Judgment mode 1
     * @param pre2 Judgment mode 2
     * @return Processing result true, false
     */
    public static boolean testAnd(String str, Predicate<String> pre1, Predicate<String> pre2) {
        // return pre1.test(str) && pre2.test(str)
        return pre1.and(pre2).test(str);
    }
}

Or or

package com.qfedu.e_predicate;

import java.util.function.Predicate;

/**
 * Predicate or Demonstration
 *
 * @author Anonymous 2020/3/11 16:32
 */
public class Demo3 {
    public static void main(String[] args) {
        boolean ret = testOr("The power of the country is beyond the envy of foreigners~~",
                str -> str.length() < 10,
                str -> str.contains("Country"));

        System.out.println(ret);
    }

    /**
     * or Combinatorial judgement
     *
     * @param str  String to judge
     * @param pre1 Judgment mode 1
     * @param pre2 Judgment mode 2
     * @return Processing result true, false
     */
    public static boolean testOr(String str, Predicate<String> pre1, Predicate<String> pre2) {
        // return pre1.test(str) || pre2.test(str);
        return pre1.or(pre2).test(str);
    }
}

negate non

package com.qfedu.e_predicate;

import java.util.function.Predicate;

/**
 * Predicate negate()operation
 *
 * @author Anonymous 2020/3/11 16:36
 */
public class Demo4 {
    public static void main(String[] args) {
        boolean ret = testNegate("The epidemic will pass!!!",
                str -> str.length() < 5);
        System.out.println(ret);
    }

    /**
     * negate operation
     *
     * @param str Character string
     * @param pre Predicate Functional interface
     * @return Processing result
     */
    public static boolean testNegate(String str, Predicate<String> pre) {
        // return !pre.test(str);
        return pre.negate().test(str);
    }
}

Delete the specified data with Predicate in ArrayList

package com.qfedu.e_predicate;

import com.qfedu.c_supplier.Person;

import java.util.ArrayList;

/**
 * ArrayList,Using Predicate as a constraint to delete the corresponding data
 *
 * @author Anonymous 2020/3/11 16:41
 */
public class Demo5 {
    public static void main(String[] args) {
        ArrayList<Person> list = new ArrayList<>();

        list.add(new Person(1, "Luo Lei", 16));
        list.add(new Person(2, "black person", 66));
        list.add(new Person(3, "Old payment", 36));
        list.add(new Person(4, "fairly tall", 26));
        list.add(new Person(5, "Foul cloud", 96));
        list.add(new Person(6, "Handsome", 96));

        // Directly arrange the Predicate function interface to constrain the corresponding conditions and delete them
        // Code reading and universality improvement
        // And reduced code redundancy
        list.removeIf(person -> person.getAge() > 40 && person.getId() > 3);

        System.out.println(list);
    }
}

3.5 function < T, R > type conversion

Use r apply (t t t)
	Convert specified type T to R
package com.qfedu.f_function;

import com.qfedu.c_supplier.Person;

import java.util.function.Function;

/**
 * Function<T, R> Functional interface
 *      R apply(T)
 *
 * @author Anonymous 2020/3/11 16:50
 */
public class Demo1 {
    public static void main(String[] args) {
        // Integer type converted to a String
        String change = change(10, i -> i + "");
        System.out.println(change);

        // Use function interface to process a String type and convert it to the corresponding Person type
        Person person1 = change("1,Luo Lei,16", str -> {
            String[] split = str.split(",");
            Person person = new Person();

            person.setId(Integer.parseInt(split[0]));
            person.setName(split[1]);
            person.setAge(Integer.parseInt(split[2]));

            return person;
        });

        System.out.println(person1);
    }

    /**
     * The method of converting format, which requires data to be converted from Integer type to specified String type
     *
     * @param i Integer type to convert
     * @param fun Function functional interface used for conversion
     * @return Return value is of String type
     */
    public static String change(Integer i, Function<Integer, String> fun) {
        return fun.apply(i);
    }

    public static Person change(String str, Function<String, Person> fun) {
        return fun.apply(str);
    }
}

andThen

package com.qfedu.f_function;

import java.util.function.Function;

/**
 * Function<T, R>
 *     default Modify the use of the andThen method
 *
 * @author Anonymous 2020/3/11 17:01
 */
public class Demo2 {
    public static void main(String[] args) {
        String s = testAndThen(10,
                i -> i + "",
                i -> i + "test");

        System.out.println(s);
    }

    /**
     * Two conversion processes
     *
     * @param i Types to process
     * @param fun1 Function Function interface
     * @param fun2 Function Function interface
     * @return String type
     */
    public static String testAndThen(int i, Function<Integer, String> fun1, Function<String, String> fun2) {

        // andThen, finally, apply method parameter type is the conversion parameter type required by fun1
        return fun1.andThen(fun2).apply(i);
    }
}
39 original articles published, 30 praised, 10000 visitors+
Private letter follow

Tags: Lambda Java JDK Attribute

Posted on Wed, 11 Mar 2020 07:44:09 -0400 by josephicon