lambda表达式 java & C++

C++:

C++中的Lambda表达式是一种匿名函数的定义方式,它允许你在需要函数的地方定义一个匿名函数,而不必显式地定义一个函数。Lambda表达式的基本格式如下:

[capture](parameters) -> return_type {
    // Lambda表达式的主体
}

//例子
auto func = [](int x, int y) -> int {
    return x + y;
};

其中:

  • capture 是捕获列表,用于捕获外部变量,可以是值捕获、引用捕获或隐式捕获。
  • parameters 是参数列表,与普通函数的参数列表类似。
  • return_type 是返回类型,可以省略,编译器会根据函数体自动推导返回类型。
  • {} 包围着Lambda表达式的主体。如果主体只有一行简单的表达式,可以省略大括号。
  • 在这个例子中,[] 捕获列表为空,int x, int y 是参数列表,-> int 指定了返回类型,{ return x + y; } ... ... 是函数体。

  • Lambda表达式的捕获列表可以使用以下方式:

  • [x, &y]:值捕获x,引用捕获y。
  • [=]:值捕获所有外部变量。
  • ... ... [&]:引用捕获所有外部变量。
  • [=, &z]:值捕获所有外部变量,引用捕获z。

在C++中,Lambda表达式的参数列表和返回类型都可以省略,编译器会根据上下文自动推导。如果Lambda表达式的函数体只有一条return语句,甚至可以省略return关键字。下面是一些示例:

省略参数列表和返回类型:

auto func = [] {
    return 42;
};

省略参数列表,返回类型和return关键字:

auto func = [] {
    42;
};

JAVA :

Java 8 引入了 Lambda 表达式,它是一种轻量级的匿名函数,可以用更简洁的方式来表示一个函数。Lambda 表达式通常用于函数式接口(Functional Interface)的实现,它可以替代匿名内部类的写法,使代码更加简洁易读。

Lambda 表达式的基本语法如下:

(parameter_list) -> { 
    // Lambda 表达式的主体
    // 可以是一行简单的表达式,也可以是一个代码块
}

在这个语法中:

  • parameter_list 是 Lambda 表达式的参数列表。如果没有参数,可以使用空括号 () 表示。
  • -> 是 Lambda 操作符,它将参数列表和 Lambda 表达式的主体分开。
  • {} 包围着 Lambda 表达式的主体。如果主体只有一行简单的表达式,可以省略大括号。如果主体是多行代码块,则需要使用大括号将其包围起来。

Lambda 表达式通常用于函数式接口的实现,它提供了一种更简洁的方式来表示一个函数

举个例子,假设有一个接口 MyInterface:

interface MyInterface {
    void myMethod(String s);
}

使用 Lambda 表达式可以这样实现:

MyInterface myInterface = (s) -> System.out.println(s);

这里 (s) -> System.out.println(s) 就是一个 Lambda 表达式,它实现了 MyInterface 接口中的 myMethod 方法。

Lambda 表达式的引入使得 Java 在处理函数式编程方面更加灵活和简洁。

 

如何省略

在Lambda表达式中,如果只有一个参数,可以省略参数列表的括号。例如,下面的两个Lambda表达式是等价的:

// 有参数的Lambda表达式
(x) -> { System.out.println(x); }

// 省略参数列表括号的Lambda表达式
x -> { System.out.println(x); }

另外,如果Lambda表达式的主体只包含一条语句,可以省略大括号和return关键字。例如:

// 包含大括号的Lambda表达式
(x, y) -> { return x + y; }

// 省略大括号和return关键字的Lambda表达式
(x, y) -> x + y

这种简化的语法使得Lambda表达式更加简洁易读。

java的::呢

 

在Java中,:: 被用作方法引用(Method Reference)的操作符。方法引用提供了一种简洁的方式来表示已有方法的引用,可以用在函数式接口的实现中。

方法引用的基本语法如下:

ClassName::methodName

其中,ClassName 是包含目标方法的类名,methodName 是目标方法的名称。

有几种不同的方法引用类型:

  1. 静态方法引用:ClassName::staticMethodName
  2. 实例方法引用:instance::methodName
  3. 特定类型的任意对象的方法引用:ClassName::methodName
  4. 构造函数引用:ClassName::new

举个例子,假设有一个静态方法 staticMethod:

class MyClass {
    static void staticMethod(String s) {
        System.out.println(s);
    }
}

可以使用方法引用来引用这个静态方法:

Consumer<String> consumer = MyClass::staticMethod;

这里 MyClass::staticMethod 就是一个静态方法引用,它可以赋值给函数式接口的实例,比如 Consumer 接口的实例。

在Java中,:: 可以用来替换Lambda表达式,这种替换被称为方法引用(Method Reference)。方法引用提供了一种更简洁的方式来表示已有方法的引用,可以用在函数式接口的实现中。

举个例子,假设有一个接口 MyInterface:

interface MyInterface {
    void myMethod(String s);
}

使用Lambda表达式可以这样实现:

MyInterface myInterface = s -> System.out.println(s);

使用方法引用可以这样实现:

MyInterface myInterface = System.out::println;

在这个例子中,System.out::println 就是一个方法引用,它引用了 System.out 对象的 println 方法。这种方式更加简洁,直接地表示了方法的引用。

方法引用提供了一种更简洁的方式来表示已有方法的引用,使得代码更加易读和简洁。