Lambda表达式使用整理总结

博客介绍了Java8中Lambda表达式的基础语法,用箭头操作符将其拆分为参数列表和Lambda体两部分。还给出常用示例,如forEach遍历、Stream用法等,同时提醒注意事项,包括局部变量隐性有final语义,不能声明同名参数或局部变量。

Lambda 表达式的基础语法 : Java8 中引入了一个新的操作符 “->”, 该操作符称为箭头操作符或 Lambda 操作符,箭头操作符将 Lambda 表达式拆分成两部分 :

左侧 : Lambda 表达式的参数列表;

右侧 : Lambda 表达式中所需执行的功能, 即 Lambda 体;

基本语法:

(parameters) -> expression

(parameters) -> { statements; }

常用示例:

1.forEach遍历List集合

String[] names = {"喵","汪","咩"};  
List<String> nameList =  Arrays.asList(names);  
  
// 旧的循环方式  
for (String name : nameList) {  
     System.out.print(name + "; ");  
}  
  
// 使用 lambda 表达式
nameList.forEach((item) -> System.out.print(item + " ")); 

2.Stream用法

(1).filter过滤

List<User> users = users.stream()
				.filter(user -> "小喵咪".equals(user.getName()))
				.collect(Collectors.toList());

(2).map处理

List nums = Arrays.asList(100, 200, 300, 400, 500);
for (Integer num : nums) {
      num = num + 12;
      System.out.println(num);
}
// 使用 lambda 表达式
List nums = Arrays.asList(100, 200, 300, 400, 500);
nums.stream().map((num) -> num = num + 12)
                      .forEach(System.out::println);

3.使用Lambda排序集合

String[] names = {"喵","汪","咩"};   
   
// 使用匿名内部类排序
Arrays.sort(names, new Comparator<String>() {  
    @Override  
    public int compare(String s1, String s2) {  
        return (s1.compareTo(s2));  
    }  
});
// 使用lambda表达式
Arrays.sort(names, (String s1, String s2) -> (s1.compareTo(s2))); 

4.返回不同类型的处理结果

//返回String
String str = userList.stream()
		.filter(user -> "喵".equals(user.getName()))
        .collect(Collectors.joining(","));

//返回Set
Set<String> names = userList.stream()  
          .filter(user -> "喵".equals(user.getName()))
          .collect(Collectors.toSet());
 
//返回TreeSet
TreeSet<String> names = userList.stream()  
          .filter(user -> "喵".equals(user.getName()))
          .collect(Collectors.toCollection(TreeSet::new));  

5.实现多线程接口

//使用Thread匿名内部类  
new Thread(new Runnable() {  
    @Override  
    public void run() {  
        System.out.println("Hello world!");  
    }  
}).start();  
  
//使用lambda表达式
new Thread(() -> System.out.println("Hello world!")).start();  
  
  
  
//使用Runnable匿名内部类  
Runnable race1 = new Runnable() {  
    @Override  
    public void run() {  
        System.out.println("Hello world!");  
    }  
};  
  
//使用lambda表达式
Runnable race2 = () -> System.out.println("Hello world!");

注意事项:

1.lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义);

2.在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。

<think>好的,我现在需要帮助用户理解C++中的lambda表达式的用法和概念,包括完整语法、使用场景和示例。首先,我应该回忆一下lambda表达式的基本概念,然后整理它的语法结构,再考虑常见的使用场景,最后通过示例来具体说明。 首先,lambda表达式在C++11及以后版本中引入,主要用于创建匿名函数对象。它们通常用于需要传递简短函数作为参数的场合,比如STL算法中的谓词或回调函数。根据用户提供的引用资料,引用[1]提到lambda类似于无需重用的内联函数,适用于封装几行代码传递给算法或异步方法。而引用[2]和[3]则讨论了语法、捕获方式以及示例,比如如何传递参数和返回值。 接下来,我需要系统地整理lambda的完整语法。完整的语法可能包括捕获列表、参数列表、可变规范、异常规范、返回类型和函数体。例如,语法结构可能是这样的:`[捕获列表](参数列表) mutable(可选) 异常属性(可选) -> 返回类型 { 函数体 }`。需要详细说明每个部分的作用,比如捕获列表如何让lambda访问外部变量,参数列表如何传递参数,mutable关键字的作用等。 然后,使用场景方面,引用[1]提到algorithm和异步方法,比如在STL的sort、for_each等算法中使用lambda作为谓词。另外,在异步编程中,lambda可以作为回调函数传递给线程或future。引用[3]中的示例展示了在STL算法中的应用,比如在std::sort中自定义比较函数。 示例部分需要覆盖基本用法、捕获方式、作为函数参数等。例如,一个没有捕获的简单lambda,一个按值或引用捕获外部变量的例子,以及在STL算法中的应用示例。同时,可能需要说明lambda的类型通常使用auto或std::function来存储。 需要注意用户提到的引用资料中的例子,比如引用[3]中的add函数示例,展示了带参数和返回值的lambda表达式,并且使用了std::function来存储。这可能是一个重要的点,需要解释为什么使用std::function以及auto关键字的替代方案。 此外,用户可能对lambda的实现原理感兴趣,比如它们是如何被编译器转换成匿名类对象的。引用[2]提到了lambda的特点和原理,这部分可能需要简要说明,但用户的问题主要集中在用法和示例,所以可能不需要深入细节,但简要提及可以增加回答的深度。 还需要考虑常见的问题,比如按值捕获和按引用捕获的区别,捕获列表中的this指针,以及mutable关键字允许修改按值捕获的变量。这些点都是用户可能容易混淆的地方,应该在教程中明确说明。 最后,生成的相关问题需要围绕lambda的不同方面,比如与函数对象的比较、捕获变量的生命周期问题、性能考虑等,确保问题能够引导用户进一步深入学习。 总结一下,回答的结构应该分为几个部分:概述、完整语法、使用场景、示例和注意事项。每个部分需要结合引用中的信息,并确保示例正确且易于理解。同时,检查LaTeX格式是否符合要求,行内公式用$...$,独立公式用$$...$$,但根据用户的问题,可能数学公式较少,更多是代码示例。因此,要确保代码块正确使用反引号包裹,并标明语言类型。</think>### C++ Lambda表达式教程 #### 1. 概述 Lambda表达式是C++11引入的匿名函数对象,适用于**无需重用的简短代码逻辑**,例如传递给算法或异步任务[^1]。它通过自动生成闭包类型实现对外部变量的捕获[^2]。 #### 2. 完整语法 Lambda表达式的完整语法结构如下: $$[捕获列表] (参数列表) \texttt{ mutable} \ (可选)\ \texttt{exception} \ (可选)\ \texttt{-> 返回类型} \ \{ 函数体 \}$$ - **捕获列表**:定义如何访问外部变量,例如: - `[]` 不捕获任何变量 - `[x]` 按值捕获x - `[&x]` 按引用捕获x - `[=]` 按值捕获所有外部变量 - `[&]` 按引用捕获所有外部变量 - **mutable**:允许修改按值捕获的变量(默认捕获的变量为`const`) - **返回类型**:可省略(编译器自动推导) #### 3. 使用场景 1. **STL算法**:作为谓词函数传递给`std::sort`, `std::for_each`等 2. **异步编程**:作为线程任务或回调函数 3. **局部封装**:简化重复代码逻辑 #### 4. 示例代码 ##### 示例1:基本用法 ```cpp auto print = [] { std::cout << "Hello Lambda"; }; // 无参数无返回值的Lambda print(); // 输出: Hello Lambda ``` ##### 示例2:捕获外部变量 ```cpp int base = 10; auto add_base = [base](int x) { return x + base; }; // 按值捕获base std::cout << add_base(5); // 输出: 15 ``` ##### 示例3:在STL算法中的应用[^3] ```cpp std::vector<int> nums{3,1,4,2}; std::sort(nums.begin(), nums.end(), [](int a, int b) { return a > b; }); // 降序排序 // 结果: {4,3,2,1} ``` ##### 示例4:带mutable关键字 ```cpp int count = 0; auto counter = [count]() mutable { count++; // 允许修改按值捕获的变量 return count; }; counter(); // 返回1 counter(); // 返回2(外部count仍为0) ``` #### 5. 注意事项 - **生命周期风险**:按引用捕获的变量需确保使用时有效 - **性能优化**:简单Lambda可能被编译器内联优化 - **类型推导**:优先使用`auto`而非`std::function`(避免类型擦除开销) ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春日安然

可以赏个鸡腿吃嘛~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值