Uso simple de expresiones lambda

contenido

¿Qué es una expresión lambda?

 He aquí un caso sencillo:

Expresión lambda simplificada:

Resumir:

Formato de sintaxis 1: sin parámetro, sin valor de retorno

Formato de sintaxis 2: Lambda requiere un parámetro, pero no un valor de retorno

Formato de sintaxis tres: se puede omitir el tipo de datos

Formato de sintaxis 4: Si Lambda solo necesita un parámetro, se pueden omitir los paréntesis del parámetro.

Formato de sintaxis cinco: Lambda requiere dos o más parámetros, varias declaraciones de ejecución y puede tener un valor de retorno

Formato de sintaxis 6: cuando solo hay un cuerpo Lambda, si hay una declaración, se pueden omitir el signo de retorno y las llaves.

Entonces hablemos de la interfaz funcional:

Simplemente use expresiones lambda para usar cuatro interfaces funcionales:

 Referencias de métodos y referencias de constructores


¿Qué es una expresión lambda?

Lambda es una función anónima, podemos entender una expresión Lambda como un fragmento de código que se puede pasar (pasar el código como datos).

Úselo para escribir código más limpio y flexible. Como un estilo de código más compacto, la capacidad de expresión de lenguaje de Java se ha mejorado

Expresiones lambda: un nuevo elemento de sintaxis y operador introducido en el lenguaje Java 8. Este operador es "->", y este operador se denomina operador lambda u operador de flecha.

Divide Lambda en dos partes: Izquierda: especifica la lista de parámetros requerida por la expresión Lambda: Derecha: especifica el cuerpo de Lambda, que es la lógica de implementación del método abstracto, es decir, la función que ejecutará la expresión Lambda

 He aquí un caso sencillo:

package com.chen.lambda;


/*
* 推导lambda表达式
* */
public class TestLambda {

    //3.静态内部类
   static class Like2 implements ILike{
        @Override
        public void lambda() {
            System.out.println("I like lambda2");
        }
    }

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

        like=new Like2();
        like.lambda();


        //4.局部内部类
        class Like3 implements ILike{
            @Override
            public void lambda() {
                System.out.println("I like lambda3");
            }
        }

        like=new Like3();
        like.lambda();


        //5.匿名内部类,没有类的名称,必须帮助接口或者父类
        like =new ILike() {
            @Override
            public void lambda() {
                System.out.println("I like lambda4");
            }
        };
        like.lambda();


        //6.用lambda简化
        like=()->{
            System.out.println("I like lambda5");
        };
        like.lambda();

    }



}

//1.定义一个函数式接口
interface ILike{

    void lambda();

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

Expresión lambda simplificada:

package com.chen.lambda;

public class TestLambda2 {

    static class Love implements ILove{

        @Override
        public void love(int a) {
            System.out.println("I Love you -->"+a);
        }
    }

    public static void main(String[] args) {
        ILove love=new Love();
        love.love(2);

        //匿名内部类
        ILove love2=new ILove() {
            @Override
            public void love(int a) {
                System.out.println("I Love you -->"+a);
            }
        };
        love2.love(5);


        //lambda表达式简化
        ILove love3=(int a)->{
            System.out.println("I Love you -->"+a);
        };
        love3.love(520);

        //简化1.参数类型
        ILove love4=(a)->{
            System.out.println("I Love you -->"+a);
        };
        love4.love(520);

        //简化2.简化括号
        ILove love5=a ->{
            System.out.println("I Love you -->" + a);
        };
        love5.love(520);

        //简化3.去掉花括号
        ILove love6=a ->
            System.out.println("I Love you -->" + a);
        love6.love(520);

        //总结:
          //lambda表达式只能有一行代码的情况下才能称为一行,如果有多行,那么就用代码块包裹
          //前提是接口为函数式接口
          //多个参数也可以去掉参数类型,要去掉就都去掉,必须加上括号

        ILove2 love7=(a,b) ->
               a*b;
      System.out.println(love7.love(7,8));
    }

}


interface ILove{
    void love(int a);

}
interface ILove2{
   int love(int a,int b);

}

class Love implements ILove{

    @Override
    public void love(int a) {
        System.out.println("I Love You");
    }
}

Resumir:

Formato de sintaxis 1: sin parámetro, sin valor de retorno

  Runnable runnable1=()->System.out.println("ddd");

Formato de sintaxis 2: Lambda requiere un parámetro, pero no un valor de retorno

Consumer<String> con=(String str) -> {System.out.println(str);};

//输出
   con.accept("aaa");

Formato de sintaxis tres: se puede omitir el tipo de datos

​Consumer<String> con=(str) -> {System.out.println(str);};

Formato de sintaxis 4: Si Lambda solo necesita un parámetro, se pueden omitir los paréntesis del parámetro.

Consumer<String> con=str -> {System.out.println(str);};

Formato de sintaxis cinco: Lambda requiere dos o más parámetros, varias declaraciones de ejecución y puede tener un valor de retorno

 Comparator<Integer> com=(x, y) -> {
            System.out.println("实现函数式接口方法");
            return Integer.compare(x,y);
        };
  //输出结果
      System.out.println(com.compare(11,10));

Formato de sintaxis 6: cuando solo hay un cuerpo Lambda, si hay una declaración, se pueden omitir el signo de retorno y las llaves.

 Comparator<Integer> com=(x, y) -> Integer.compare(x,y);
     

El compilador infiere todos los tipos de parámetros en las expresiones lambda anteriores. No es necesario especificar el tipo en la expresión lambda
y el programa aún se puede compilar porque javac
infiere el tipo del parámetro en segundo plano según el contexto del programa. El tipo de la expresión lambda depende del
contexto y lo infiere el compilador. Esto se llama "inferencia de tipo"

Entonces hablemos de la interfaz funcional:

Una interfaz que contiene solo un método abstracto se denomina interfaz funcional.
1. Puede crear objetos de esta interfaz a través de expresiones Lambda. (Si la expresión lambda arroja una excepción comprobada (es decir, una excepción que no es de tiempo de ejecución), entonces la excepción debe declararse en el método abstracto de la interfaz de destino).
2. Podemos usar la anotación @FunctionalInterface en una interfaz para verificar si es una interfaz funcional. El javadoc también contendrá una declaración de que la interfaz es una interfaz funcional.

En Java8, es diferente. En
Java 8, las expresiones Lambda son objetos, no funciones, y deben adjuntarse a una clase especial de tipos de objetos: interfaces funcionales.
En pocas palabras, en Java 8, una expresión lambda es una instancia de una interfaz funcional. Esta es la relación entre las expresiones Lambda y las interfaces funcionales.

Es decir, siempre que un objeto sea una instancia de una interfaz funcional, el objeto se puede representar mediante una expresión lambda

 Entonces, lo que solía estar representado por clases de implementación anónimas ahora se puede escribir con expresiones Lambda.

 

Simplemente use expresiones lambda para usar cuatro interfaces funcionales:

Caso de código:

//Consumer<T> 消费型接口:
    @Test
    public void test1(){
        happy(10000,(m) -> System.out.println("今天消费了:"+(m+m)));
    }

    public  void happy(double money, Consumer<Double> con){

        con.accept(money);
    }



    //Supplier 供给型接口:
    @Test
    public void test2(){
        List<Integer> numList=  getNumList(10,() ->(int)(Math.random()*100));
        for(Integer num:numList){
            System.out.println(num);
        }
    }
    //需求:产生指定个整数,并放入到集合中
    public List<Integer> getNumList(int num, Supplier<Integer> sup){
        List<Integer>  list=new ArrayList<>();

        for(int i=0;i<num;i++){
            Integer n=sup.get();
            list.add(n);
        }
        return list;
    }



    //Function<T ,R> 函数型接口
    @Test
    public void test3(){
     String newStr  =   strHandler("\t\t\t 我爱爱学习",(str) -> str.trim());
     System.out.println(newStr);

        String subStr = strHandler("\t\t\t 我爱爱学习",(str)-> str.substring(2,5));
        System.out.println(subStr);
    }

    //需求:用于处理字符串
    public String strHandler(String str, Function<String,String> fun){

        return fun.apply(str);

    }

   //Predicate<T> 断言型接口

    @Test
    public  void test4(){
        List<java.lang.String> list= Arrays.asList("hello","hello2","hello3");
         List<String> strList=filterStr(list,(s) -> s.length()>5);

         for(String str:strList){
             System.out.println(str);
         }
    }

    //需求:将满足条件的字符串,放入集合中
    public List<String> filterStr(List<String> list, Predicate<String> pre){

        List<String> strList=new ArrayList<>();

        for(String str:list){
            if(pre.test(str)){
                strList.add(str);
            }
        }
      return  strList;

    }

 Referencias de métodos y referencias de constructores

referencia del método

Cuando una operación que se va a pasar al cuerpo de Lambda ya tiene un método implementado, ¡se puede usar una referencia de método!
1. Una referencia de método puede verse como una expresión profunda de una expresión lambda. En otras palabras, una referencia de método es una expresión lambda, que es una instancia de una interfaz funcional, y se refiere a un método a través del nombre del método
, que se puede considerar como un azúcar sintáctico para una expresión lambda.
2. Requisitos: la lista de parámetros y el tipo de valor devuelto del método abstracto que implementa la interfaz deben ser coherentes con la lista de parámetros y el tipo de valor devuelto del método al que hace referencia el método.

3. Formato: use el operador "::" para separar la clase (u objeto) del nombre del método.
 Hay tres casos de uso principales:
 objeto::nombre del método de instancia
 clase::nombre del método estático
 clase::método de instancia

P.ej:

Consumer<String> con=(x) -> System.out.println(x);

//相当于

Consumer<String> con=System.out::println;
Comparator<Integer> c=(x,y) -> Integer.compare(x,y);

//相当于

Comparator<Integer> c2=Integer::compare;
BiPredicate<String,String> bp=(x,y) -> x.equals(y);

//相当于

BiPredicate<String,String> bp1=String::equals;
//输出结果
 System.out.println(bp1.test("s","t"));

Referencia del constructor

Formato: ClassName::new
se combina con la interfaz funcional y es automáticamente compatible con los métodos de la interfaz funcional.
Se puede asignar una referencia de constructor a un método definido, lo que requiere que la lista de parámetros del constructor sea
consistente con la lista de parámetros del método abstracto en la interfaz. Y el valor de retorno del método es el objeto de la clase correspondiente del constructor.

Function<Integer,Myclass> fun=(n) -> new Myclass(n);

//相当于

Function<Integer,Myclass> fun=Myclass::new;

referencia de matriz

Function<Integer,Integer[]> fun3=(n) -> new Integer[n];

//相当于

Function<Integer,Integer[]> fun4=Integer[]::new;
   System.out.println(fun4.apply(1555).length);

Supongo que te gusta

Origin blog.csdn.net/qq_44716544/article/details/119047362
Recomendado
Clasificación