• J3 – leitian
  • Technology (Lambda # Functional Interface)

Explain the background of sharing technology this time!

Because I’m a back-end developer, the development language I use at work is Java. However, the technology is iterating so fast that Java has been updated to JDK17, and I believe that most companies are still using JDK8 and even JDK7.

The current version of the project I’m working on is JDK11, which has a lot of new features in JDK8, especially streaming programming and Lambda expressions.

Lambda expression to write good words, that is the following to talk about the four functional interface is the premise, so no more nonsense said, go to see, certainly can let you gain.

I. Consumer: Consumer interface

The source code is as follows:

The @functionalinterface annotation states that this interface is a FunctionalInterface (there is only one abstract method in the interface).

The argument T is the type of object we’re dealing with.

What it does: Implements the Accept method in the Consumer interface, which operates arbitrarily on objects of type T (implementing its own processing logic), so this interface is also called the Consumer interface.

Use:

Methods a

  1. Create a class that implements the interface

    class MyConsumer<T> implements Consumer<T> {
        @Override
        public void accept(T t) {
            // Own processing logic
            System.out.println("====== start doing something about the incoming T======");
            System.out.println("T(" + t + ") do things...");
            System.out.println("======end======"); }}Copy the code
  2. test

    public class ConsumerTest {
        @Test
        public void test(a) {
            MyConsumer<String> stringMyConsumer = new MyConsumer<>();
            List<String> stringList = Arrays.asList("a"."b"."c"."d");
            / / traverse
            for (String s : stringList) {
                // Process each elementstringMyConsumer.accept(s); }}}Copy the code

This approach does not take advantage of JDK8’s features at all, but simply uses an interface provided by it, so let’s change the approach.

Way 2

Direct in one step:

public class ConsumerTest {
    @Test
    public void test2(a) {
        List<String> stringList = Arrays.asList("a"."b"."c"."d");
        // Use Lambda expressions
        stringList.forEach(str -> {
            System.out.println("I can tell STR (" + str + ") Do anything"); }); }}Copy the code

If you don’t understand where the consumer interface is used, can I break it down

public class ConsumerTest {
    @Test
    public void test3(a) {
        List<String> stringList = Arrays.asList("a"."b"."c"."d");
        handle(stringList, s -> {
            // Internal class parameters to implement processing logic
            System.out.println("I can tell you that s (" + s + ") anything, and I know his type.");
        });
    }
    public <T> void handle(List<T> list, Consumer<T> consumer) {
        for (T t : list) {
            // Call the processing methodconsumer.accept(t); }}}Copy the code

Isn’t that very clear!

ForEach traversal, which we often use in JDK8, is a consumer interface implementation pattern.

Supplier: Supplier interface

Source:

Function: Provides the specified type of data. Therefore, this interface is also called a supply interface.

Use:

A:

  1. Create a class that implements the interface

    @Data
    class MySupplier<T> implements Supplier<T>{
    
        private String name;
    
        @Override
        public T get(a) {
            // I will provide a specified T type of data out
            // I will write the case for T as MySupplier
            MySupplier<T> t = new MySupplier<>();
            t.setName("Ha ha!);
            return(T) t; }}Copy the code
  2. test

    public class SupplierTest {
        @Test
        public void test1(a){
            MySupplier<MySupplier> stringMySupplier = newMySupplier<>(); System.out.println(stringMySupplier.get()); }}// suppliertest. MySupplier(SupplierTest)
    Copy the code

As always, this approach also does not take advantage of JDK8 features, so let’s change it

Method 2:

public class SupplierTest {
    @Test
    public void test2(a){
        Supplier<String> stringSupp = () ->{
            // Your logic
            return "Call the get method and I'll give you the data."; }; System.out.println(stringSupp.get()); }}// Call the get method and I'll give you the data
Copy the code

To illustrate my understanding, this type of interface is mainly to provide data, so in the project I can define a set of data in advance, at a specific time through the predefined objects to get.

Scene:

The user purchases goods, enters the service, and determines whether the conditions for the purchase meet the conditions for the attached gift. If so, the user determines the gift type (A, B, C, etc.), and then obtains the corresponding gift according to the Supplier interface implementation class to return the gift to the list of goods purchased by the user. The advantage of this is that the user does not create a gift object for the project if the condition is not met. Only the get method is called, and the object is generated, creating a lazy loading effect.

Function: a Function interface

Source:

The argument R is the type returned by the interface method.

Function: Pass in an object of type T, call the Apply method for processing, and finally return the processed data type R.

Use:

A:

  1. Write a class that implements this interface

    class MyFunction<T.R> implements Function<T.R> {
        @Override
        public R apply(T t) {
            System.out.println("Processing logic.... 【" + t + "】");
            return null; }}Copy the code
  2. test

    public class FunctionTest {
    
        @Test
        public void test1(a) {
            MyFunction<String, String> myFunction = new MyFunction<>();
            myFunction.apply("J3 - leitian..."); }}// Processing logic.... 【J3- Baiqi...】
    Copy the code

It’s the same old thing, but we’re going to revamp it with new features.

Method 2:

public class FunctionTest {

    @Test
    public void test2(a) {
        Function<String, String> myFunction = (t) ->{
            System.out.println("Processing logic.... 【" + t + "】");
            return "success";
        };
        myFunction.apply("J3 - leitian..."); }}// Processing logic.... 【J3- Baiqi...】
Copy the code

This is a simple use of this interface, so LET me write an example to make it easier to understand.

Case study:

Requirement: According to a name list, obtain the corresponding name length list, the implementation code is as follows:

public class FunctionTest {

    @Test
    public void test3(a) {
        List<String> nameList = Arrays.asList("J3-baiqi"."shaheshagn"."sunwukong");
        List<Integer> nameLengthList = functionHandle(nameList, String::length);
        System.out.println(nameLengthList);
        / / [8, 10, 9]
    }

    /** * Gets the length of the name in the list **@paramNameList Lists names *@paramFunction Name length list *@return* /
    public List<Integer> functionHandle(List<String> nameList, Function<String, Integer> function) {
        List<Integer> nameLengthList = new ArrayList<>(nameList.size());
        nameList.forEach(name -> nameLengthList.add(function.apply(name)));
        returnnameLengthList; }}Copy the code

Explain:

I have two places to specify, one is an argument, one is a parameter.

First, parameters. For this requirement, I’ve drawn a method that specifically implements getting the length of the elements in the list. I just pass the data to you and you return the number I need. So I define the parameter as Function interface. When I want to get the number, I just call the apply method of the interface.

For arguments, when I call a method, I need to pass in an object of interface type Function. I can write an implementation class, implement the Apply method, and then, using all sorts of fancy techniques, get the length of the object that was passed in. But since it’s JDK8, I can implement it with new features.

Scenarios: There are a lot of scenarios that I use in projects. I often need to extract methods, but the parameters on the methods I define as an interface specification, because I don’t care about the implementation, I just call it. In the future, when other colleagues use my method, just implement the interface in my parameter, and then my method will get the data based on the interface you implement and give you the result you want.

Predicate: Predicate interface

Source:

Function: If you pass in an object of the specified type, return true or false, so it is also called a stereotype interface.

Use:

A:

  1. Write a class and implement the interface

    class MyPredicate<T> implements Predicate<T> {
    
        @Override
        public boolean test(T t) {
            // Check if the type T passed in is String, then check if it contains "J3"
            if (t instanceof String) {
                return ((String) t).contains("J3");
            }
            if (t instanceof Integer) {
                return ((Integer) t) == 18;
            }
            // If it is an Integer, check whether it equals 18
            return false; }}Copy the code
  2. test

    public class PredicateTest {
        @Test
        public void test1(a){
            MyPredicate<String> stringMyPredicate = new MyPredicate<>();
            System.out.println(stringMyPredicate.test("J3 - leitian"));
            System.out.println(stringMyPredicate.test("Leitian"));
            MyPredicate<Integer> integerMyPredicate = new MyPredicate<>();
            System.out.println(integerMyPredicate.test(18));
            System.out.println(integerMyPredicate.test(28)); }}//true
    //false
    //true
    //false
    // I am still J3 is still 18, ha ha!
    Copy the code

Same old, same old, same old, same old

Method 2:

public class PredicateTest {
    @Test
    public void test2(a) {
        Predicate<String> myStringPredicate = (t) -> t.contains("J3");
        System.out.println(myStringPredicate.test("J3 - leitian"));
        System.out.println(myStringPredicate.test("Leitian"));
        Predicate<Integer> myIntegerPredicate = (t) -> t == 18;
        System.out.println(myIntegerPredicate.test(18));
        System.out.println(myIntegerPredicate.test(28)); }}Copy the code

The key to this type interface is that the result returned is a Boolean type, so its positioning is clear and it’s just for judgment purposes, and it’s up to you what you want to judge.

Requirement cases:

Now we have a system that is divided into PC and APP terminals. After user registration, the information enters the business, and it is necessary to distinguish which terminal user registration. You can use the Predicate interface, pass the user information to test, and then write the logic to tell the difference between the PC and the APP based on that information.

Five, the last

Finally, draw a table to briefly summarize the four interfaces analyzed above as follows:

Functional interface The parameter types The return type use
Consumer

Consumer interface
T void Apply an operation to an object of type T, including void Accept (T T)
Supplier

Supply interface
There is no T Return an object of type T containing the method T get()
Function<T, R>

Functional interface
T R Applies the operation to an object of type T and returns the result. The result is an object of type R. R apply(T T)
Predicate

Stereotyped interface
T boolean Determines whether an object of type T satisfies a constraint and returns Boolean. Boolean test(T T)

Well, that's it for today, so follow me and we'll see you next time


  • Due to the lack of knowledge of the blogger, there will be mistakes, if you find mistakes or bias, please comment to me, I will correct it.

  • If you think the article is good, your retweets, shares, likes and comments are the biggest encouragement to me.

  • Thank you for reading. Welcome and thank you for your attention.

^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^

CSDN:J3 – leitian

The nuggets:J3 – leitian

Zhihu:J3 – leitian

This is a technical average, but keen to share; Inexperienced but thick-skinned; Young and good-looking programmers who insist on talent for a living.

^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^