Java basics - lamda expressions and functional interfaces


1. Lambda expression

Functional Interface: Any interface that contains only one abstract method is a functional interface. For a functional interface, an object of the interface can be created through a Lambda expression section.

Use Lambda expressions: Avoid too many definitions of anonymous inner classes, make the code look more concise, remove a pair of meaningless codes, and only leave the core logic

turn out to be:

package Lambda;

public class TestLambda1 {
    public static void main(String[] args) {
        ILike like = new Like();
        like.lambda();
    }
}

//1、定义一个函数式接口
interface ILike{
    void lambda();
}

//2、实现类
class Like implements ILike {
    public void lambda(){
        System.out.println("I like lambda");
    }
}

Simplified by anonymous inner class:

package Lambda;

public class TestLambda1 {
    public static void main(String[] args) {
        ILike like = new ILike(){
            public void lambda(){
                System.out.println("I like lambda");
            }
        };
        like.lambda();
    }
}

//1、定义一个函数式接口
interface ILike{
    void lambda();
}



Further simplification via Lambda expressions:

package Lambda;

public class TestLambda1 {
    public static void main(String[] args) {
       ILike like = ()->{
           System.out.println("I like lambda");
       };
       like.lambda();
    }
}

//1、定义一个函数式接口
interface ILike{
    void lambda();
}



Summary: For an interface that contains only one abstract method, you can use Lambda expressions to simplify the code to create objects

further omit:

  • Parameter type can be omitted
  • When the method body has only one line of code, you can omit curly braces return and semicolon
  • When the method has only one parameter, the parentheses can be omitted
       ILike like = ()->System.out.println("I like lambda");

2. Functional interface

A functional interface refers to an interface that has one and only one abstract method, but can also have other methods (default, static, private).

The @FunctionalInterface annotation can be added to detect whether an interface is a functional interface

2.1 Function of functional interface

Functional interfaces can generally be used as method parameter and return value types

As a method parameter:

package Lambda;

public class TestLambda1 {
    public static void show(MyFunctionalInterface myInter){
        myInter.method();
    }

    public static void main(String[] args) {
        show(()->System.out.println("重写接口中的方法"));
    }
}

@FunctionalInterface
interface MyFunctionalInterface{
    public void method();
}


As the return value type of the method: you can directly return a Lambda expression

package Lambda;

import java.util.Arrays;
import java.util.Comparator;

public class TestLambda1 {
    public static Comparator<String> getComparator(){
        return (o1,o2) -> o2.length()-o1.length();
    }
    public static void main(String[] args) {
        String[] arr = {"aaa","b","cccccc","dddddddddd"};
        System.out.println(Arrays.toString(arr));
        Arrays.sort(arr,getComparator());//按照长度排序
        System.out.println(Arrays.toString(arr));
    }
}




2.2 Commonly used functional interface - Supplier interface

The java.util.function.Supplier<T> interface contains only one parameterless method: T get(). Used to get object data of the type specified by a generic parameter. Since this is a functional interface, it means that the corresponding Lambda expression needs to provide an object data conforming to the generic type. This interface is called a production interface, that is, what type of generic interface is specified, and what type of data will be generated by the get method in the interface.

Example:

package Lambda;

import java.util.function.Supplier;

public class DemoSupplier {
    public static String getString(Supplier<String> sup){
        return sup.get();
    }

    public static void main(String[] args) {
        String s = getString(()->"胡歌");
        System.out.println(s);
    }
}

Exercise: Use the Supplier interface as the method parameter type, and find the maximum value in the int array through the Lambda expression.

package Lambda;

import java.util.function.Supplier;

public class DemoSupplier {
    public static int getMax(Supplier<Integer> sup){
        return sup.get();
    }

    public static void main(String[] args) {
        int[] arr = {100,0,0-50,88,99,33,-30};
        int maxValue = getMax(()->{
          int max = arr[0];
          for(int i :arr){
              if(i > max)
                  max = i;
          }
          return max;
        });
        System.out.println(maxValue);
    }
}

2.3 Commonly used functional interface - Consumer interface

The java.util.function.consumer<T> interface is just the opposite of the Supplier interface. It consumes a data whose data type is determined by the generic type. It contains the abstract method void accept(T t), which means to consume data of a specified generic type.

The use of accept() method:

package Lambda;

import java.util.function.Consumer;

public class DemoConsumer {
    public static void method(String name , Consumer<String> con){
        con.accept(name);
    }

    public static void main(String[] args) {
        method("赵丽颖",(String name)->{
            //消费方式:把字符串进行翻转输出
            String reName = new StringBuffer(name).reverse().toString();
            System.out.println(reName);
        });
    }
}

insert image description here

The default method andThen in the Consumer interface: If the parameters and return value of a method are both of Consumer type, then when consuming data, first do an operation, and then do another operation to realize the combination. This method is implemented by andThen. To combine to achieve, you need two or more Lambda expressions, and the semantics of andThen is a step-by-step operation. For example:

Consumer<String> con1
Consumer<String> con2
String s = "hello";
con1.accept(s);
con2.accept(s);

可以用andThen来进行连接,再进行消费,谁写前面谁先消费,所以下面是con1先进行消费:
con1.andThen(con2).accept(s);

The first way:

第一种方式:
package Lambda;

import java.util.Locale;
import java.util.function.Consumer;

public class DemoConsumer {
    public static void method(String s , Consumer<String> con1 , Consumer<String> con2){
        con1.accept(s);
        con2.accept(s);
    }

    public static void main(String[] args) {
        method("hello",
                (t)->{
                    System.out.println(t.toUpperCase());
                },
                (t)->{
                    System.out.println(t.toLowerCase());
                });

    }
}


The second way: use andThen to connect

package Lambda;

import java.util.Locale;
import java.util.function.Consumer;

public class DemoConsumer {
    public static void method(String s , Consumer<String> con1 , Consumer<String> con2){
        con1.andThen(con2).accept(s);
    }

    public static void main(String[] args) {
        method("hello",
                (t)->{
                    System.out.println(t.toUpperCase());
                },
                (t)->{
                    System.out.println(t.toLowerCase());
                });

    }
}

Exercise: There are multiple pieces of information stored in the string array below, please print out the information in the format of "Name: XX, Gender: XX". It is required that the action of printing the name be used as the first Lambda instance of the Consumer interface. The action of printing gender is used as the Lambda instance of the second Consumer interface, and the two Consumer interfaces are spliced ​​together in order:

package Lambda;

import java.util.Locale;
import java.util.function.Consumer;

public class DemoConsumer {
   public static void printInfo(String[] arr , Consumer<String> con1 , Consumer<String> con2){
       for(String message : arr){
           con1.andThen(con2).accept(message);
       }
   }

    public static void main(String[] args) {
        String[] arr = {"迪丽热巴,女","古力娜扎,女","马尔扎哈,男"};

        printInfo(arr,(message)->{
            String name = message.split(",")[0];
            System.out.print("姓名:"+name+",");
        },(message)->{
            String gender = message.split(",")[1];
            System.out.println("性别:"+gender);
        });
    }
}

insert image description here

2.4 Commonly used functional interface - Predicate interface

Sometimes we need to judge the type of a certain data to get a boolean value result. This is available with the java.util.function.Predicate<T> interface.

Abstract method test():

package Lambda;

import java.util.function.Predicate;

public class DemoPredicate {
    public static boolean checkString(String s , Predicate<String> pre){
        return pre.test(s);
    }

    public static void main(String[] args) {
        String s = "abcdef";
        //对参数传递的字符串进行判断,判断字符串长度是否大于5
        boolean b = checkString(s,str->str.length()>5);
        System.out.println(b);
    }
}

Since it is a conditional judgment, there will be three logics of AND or NOT.

AND logic: the default method and()

package Lambda;

import java.util.function.Predicate;

public class DemoPredicate {
   /*
        定义一个方法,方法的参数,传递一个字符串,两个Predicate接口
            一个用于判断字符串长度是否大于5
            一个用于判断字符串中是否包含a
            两个条件必须同时满足
    */
    public static boolean checkString(String s , Predicate<String> pre1 , Predicate<String> pre2){
        return pre1.and(pre2).test(s);
    }

    public static void main(String[] args) {
        String s = "bcdeff";

        boolean b = checkString(s,(String str)->{
            return str.length()>5;
        },(String str)->{
            return str.contains("a");
        });
        System.out.println(b);
    }
}

OR logic: the default method or()

package Lambda;

import java.util.function.Predicate;

public class DemoPredicate {
   /*
        定义一个方法,方法的参数,传递一个字符串,两个Predicate接口
            一个用于判断字符串长度是否大于5
            一个用于判断字符串中是否包含a
            满足一个条件即可
    */
    public static boolean checkString(String s , Predicate<String> pre1 , Predicate<String> pre2){
        return pre1.or(pre2).test(s);
    }

    public static void main(String[] args) {
        String s = "bcdeff";

        boolean b = checkString(s,(String str)->{
            return str.length()>5;
        },(String str)->{
            return str.contains("a");
        });
        System.out.println(b);
    }
}

Irregular: negate()

package Lambda;

import java.util.function.Predicate;

public class DemoPredicate {
   /*
        定义一个方法,方法的参数,传递一个字符串,一个Predicate接口
           如果字符串长度大于5,则返回false
           如果字符串长度不大于5,则返回true
    */
    public static boolean checkString(String s , Predicate<String> pre){
        return pre.negate().test(s);
    }

    public static void main(String[] args) {
        String s = "bcdeff";

        boolean b = checkString(s,str->str.length()>5);
        System.out.println(b);
    }
}

2.5 Commonly used functional interface - Function interface

The java.util.function.Function< T , R > interface is used to obtain data of another type based on data of one type. The former is called a precondition, and the latter is called a postcondition. Convert the data type of T to the data type of R

The abstract method R apply(T t) obtains the result of type R according to the parameter of type T

package Lambda;

import java.util.function.Function;

public class DemoFunction {
    /*
        定义一个方法
        方法的参数传递一个字符串类型的证书
        方法的参数传递一个Function接口,泛型使用<String,Integer>
        使用Function接口中的方法apply,把字符串类型的整数转换为Integer类型
     */
    public static void change(String s , Function<String,Integer> fun){
        int in = fun.apply(s);
        System.out.println(in);
    }

    public static void main(String[] args) {
        String s = "1234";
        change(s,str->Integer.parseInt(s));
    }
}

The default method andThen: perform combined operations

package Lambda;

import java.util.function.Function;

public class DemoFunction {
    /*
        需求:把String类型的“123”转换为Integer类型,把转换后的结果加10
            把增加之后的Integer类型的数据转换为String类型

        分析:转换了两次
            第一次是Function<String,Integer> fun1:
                Integer i = fun1.apply("123")+10
            第二次是Function<Integer,String> fun2:
                String s = fun2.apply(i)
            我们可以使用andThen方法将两次转换组合在一起使用
                String s = fun1.andThen(fun2).apply("123")

     */
    public static void change(String s , Function<String,Integer> fun1 , Function<Integer,String> fun2){
        String ss = fun1.andThen(fun2).apply(s);
        System.out.println(ss);
    }

    public static void main(String[] args) {
        String s = "123";
        change(s,str->Integer.parseInt(str)+10,i->i+"");
    }
}

おすすめ

転載: blog.csdn.net/weixin_46025531/article/details/122753681