首页 > 编程语言 > java中的lambda表达式

java中的lambda表达式

时间:2023-02-12 18:34:48浏览次数:40  
标签:java String int System println public 表达式 lambda

java中的lambda表达式

历史背景
到目前为止,在 Java 中传递一个代码段并不容易, 不能直接传递代码段,Java 是一种面 向对象语言,所以必须构造一个对象,这个对象的类需要有一个方法能包含所需的代码

但是在其他语言中可以直接处理代码块,Java在很长时间里面拒绝加入这个特性。我们知道Java的优点:

简单性
一致性
如果只要有一个特性能让代码简洁,就加入的话,这个语言很快就会变得一团糟。(来自Java核心技术卷1)

在Java8中提出了lambda表达式,处理代码块 (变得更加简洁紧凑)

lambda表达式的语法
(参数)->表达式

(参数)->{ 语句; }
1.
2.
3.
特征:

可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。
具体的写法
根据上面所说的特征,lambda表达式大致可以分为下面3种写法

无返回值有形参
package lambda;

/**

  • @Author 秋名山码神
  • @Date 2022/12/21
  • @Description
    */
    public class Test {
    public static void main(String[] args) {
    TestInterFace testInterFace = new TestInterFace() {
    @Override
    public void show(int a, int b) {
    System.out.println(a + b);
    }
    };
    testInterFace.show(30,40);
TestInterFace testInterFace1 = (int a,int b)->{
System.out.println(a+b);
};

TestInterFace testInterFace2 = (a,b) ->{
System.out.println(a+b);
};

TestInterFace testInterFace3 = ((a, b) -> System.out.println(a+b));

}
}

package lambda;

/**

  • @Author 秋名山码神
  • @Date 2022/12/21
  • @Description
    */
    public interface TestInterFace {
    public abstract void show(int a,int b);
    }

可以省略方法名,编译器会帮你自动检测方法名
可以省略方法中的形参类型,编译器可以推导出,a,b必然是int类型
如果对抽象方法的实现逻辑只有一行,可以省略方法体的大括号
有返回值
package lambda;

/**

  • @Author 秋名山码神
  • @Date 2022/12/21
  • @Description
    */
    public class Test2 {
    public static void main(String[] args) {
    TestInterFace2 testInterFace = new TestInterFace2() {
    @Override
    public int add(int a, int b) {
    return a+b;
    }
    };
TestInterFace2 testInterFace2 = (int a,int b) ->{
return a-b;
};

TestInterFace2 testInterFace21 = (a,b) -> {return a-b;};

TestInterFace2 testInterFace22 = (a,b) -> a-b;

}
}

package lambda;

/**

  • @Author 秋名山码神
  • @Date 2022/12/21
  • @Description
    */
    public interface TestInterFace2 {
    public abstract int add(int a,int b);
    }

简化说明参考:无返回值有形参的

有一个形参
当只有一个形参的时候,可以去掉形参的括号

package lambda;

/**

  • @Author 秋名山码神
  • @Date 2022/12/21
  • @Description
    */
    public class Test3 {
    public static void main(String[] args) {
    InterFace interFace = a -> System.out.println(a);
    interFace.show(10);
    }
    }

package lambda;

/**

  • @Author 秋名山码神
  • @Date 2022/12/21
  • @Description
    */
    public interface InterFace {
    public abstract void show(int a);
    }

函数式接口
Java中有很多封装代码的接口,如Comparator,lambda表达式与这些接口是兼容的。

对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式,这种接口称为函数式接口

lambda和Arrays.sort:

注:sort的第二个参数需要一个Compartor实例

package lambda;

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

/**

  • @Author 秋名山码神
  • @Date 2022/12/21
  • @Description
    /
    public class ArraySort {
    public static void main(String[] args) {
    // lambda方式
    Integer[] numsArr = new Integer[10];
    for(int i = 0; i<10; i++){
    numsArr[i] = i;
    }
    /

    Arrays.sort(numsArr,new Comparator<Integer>(){
    public int compare(Integer a, Integer b){
    return b-a;
    }
    });
    */
    Arrays.sort(numsArr, ( Integer a, Integer b) -> { return b-a;});
    for (int i: numsArr){
    System.out.println(i);
    }
    }
    }

实际上,在 Java 中, 对 lambda 表达式所能做的也只是能转换为函数式接口。在其他支 持函数字面量的程序设计语言中,可以声明函数类型(如(String, String) -> int)、 声明这些类 型的变量,还可以使用变量保存函数表达式。不过,Java 设计者还是决定保持我们熟悉的接 口概念, 没有为 Java语言增加函数类型。

方法引用
有可能已经有现成的方法来帮助你完成你想要传递到其他代码的某个动作,可以使用方法引用,有点抽象,通俗的来说:当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用,

比如我希望只要出现一个定时器事件就打印这个事件的对象:

​​Timer t = new Timer(1000,event -> System.out.println(event))​​
改进:讲println方法直接传递到Timer构造器
​​Timer t = new Timer(1000,System.out::println);​​
要用::操作符分隔方法名和对象或类名,主要有三种情况

对象::实例方法
类::静态方法
类::实例方法
在前 2 种情况中,方法引用等价于提供方法参数的 lambda 表达式。前面已经提到, System.out::println 等价于 x -> System.out.println(x)。 类似地,Math::pow 等价于(x,y) -> Math.pow(x, y)。

对于第 3 种情况, 第 1 个参数会成为方法的目标。例如,String::compareToIgnoreCase 等 同于 (x, y) -> x.compareToIgnoreCase(y) 。

对象::实例方法
​​​Timer t = new Timer(1000,event -> System.out.println(event))​​ 1.
类::静态方法
(x,y) -> Math.pow(x, y)
1.
类::实例方法
package lambda;

import java.util.Comparator;

/**

  • @Author 秋名山码神
  • @Date 2022/12/21
  • @Description
    */
    public class Test4 {
    public static void main(String[] args) {
    Comparator<String> comparator = new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
    return o1.compareTo(o2);
    }
    };
System.out.println(comparator.compare("20", "2"));//1

Comparator<String> comparator1 = String::compareTo;
System.out.println(comparator1.compare("20", "2"));//1

}
}

构造器引用
构造器引用与方法引用很类似,只不过方法名为new

ClassName::new

假设你有多个方法,那么构造哪一个呢?这取决于上下文,我们来看实例:

复制
package lambda;

import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

/**

  • @Author 秋名山码神
  • @Date 2022/12/21
  • @Description
    /
    public class 构造器 {
    public static void main(String[] args) {
    /
    ************** 构造器的引用 ****************/
    // 无参构造函数,创建实例
    Supplier<Emp> supper2 = () -> new Emp();
    Supplier<Emp> supper3 = Emp::new;
    Emp emp1 = supper3.get();
    emp1.setAddress("上海");
    // 一个参数
    Function<String, Emp> fun = address -> new Emp(address);
    Function<String, Emp> fun1 = Emp::new;
    System.out.println(fun1.apply("beijing"));
    // 两个参数
    BiFunction<String, Integer, Emp> bFun = (name, age) -> new Emp(name, age);
    BiFunction<String, Integer, Emp> bFun1 = Emp::new;
    System.out.println(bFun1.apply("xiaohong", 18));
    }
    static class Emp {
    private String address;
private String name;

private Integer age;

public Emp() {

}

public Emp(String address) {
this.address = address;
}

public Emp(String name, Integer age) {
this.name = name;
this.age = age;
}

public Emp(String address, String name, Integer age) {
super();
this.address = address;
this.name = name;
this.age = age;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}

@Override
public String toString() {
return "Emp [address=" + address + ", name=" + name + ", age=" + age + "]";
}


标签:java,String,int,System,println,public,表达式,lambda
From: https://blog.51cto.com/u_15962735/6052121

相关文章

  • Java基础知识点(条件控制语句之if语句)
    1.顺序结构:Java程序中默认的执行流程,按照代码的先后顺序,从上到下依次进行。2.选择结构语句<1>.if语句格式:if(关系表达式){语句体;}执行流程:1.首先计算关系表达式的值。2.如......
  • Java 抽象类
    目录1、抽象方法和抽象类2、抽象类的作用当编写一个类时,常常会为该类定义一些方法,用于描述该类的行为方式,这些方法都有具体的方法体。但在某些情况下,某个基类只是知道其子......
  • Java-异常处理
           ......
  • java——spring boot集成RabbitMQ——路由模式——应用场景
    如果多个队列都绑定了同一个交换机,通过路由key,指定消息到哪个消息队列     ......
  • Java程序设计三特性
    Java程序编写具有三大特征:封装、继承和多态;封装对类中的方法和属性进行权限访问控制,只提供特定接口供外部访问,这样一方面增加了代码的规范性另一方面又增加了代码的访......
  • java——spring boot集成RabbitMQ——发布/订阅模式——实现生产者
        首先抽离出来连接,单据一个工具类:                                     ......
  • java面试题(三)
    1、Java中会存在内存泄漏吗,请简单描述。答:理论上Java因为有垃圾回收机制(GC)不会存在内存泄露问题(这也是Java被广泛使用于服务器端编程的一个重要原因);然而在实际开发......
  • java面试题(四)
    1、什么时候用断言(assert)?答:断言在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。一般来说,断言用于保证程序最基本、关键的正确性。断言检查通常在开发和......
  • Java方法
    一、什么是方法Java方法是语句的集合,他们在一起执行一个功能方法是解决一类问题的步骤的有序组合包含于类或对象中方法在程序中被创建,在其他地方被引用二、方法的......
  • EL表达式
    在jsp中使用对象获取数据,较为麻烦,于是有了EL表达式  一、数据来源它只能获取到pageContext、request、session、application对象中的数据。 二、获取数据......