lambda表达式学习整理

前言

以下是自己学习lambda整理的笔记还在完善,如有更好的写法欢迎各位大佬在下方提出

代码注释我写的很清楚多看注释

1.List存储对象取id 和name转成Map 集合
 //创建集合存储user对象
        List<UserInfo> userInfoList = new ArrayList<>();
        UserInfo user = new UserInfo();
        user.setUserId(1L);
        user.setRealName("张三");
        userInfoList.add(user);
        Map<Long, String> map = 
                  //创建一个并行流
                  userInfoList.parallelStream()
                  //添加过滤条件        
                .filter(u -> u != null)
                  //返回一个Map集合key是userId  value是用户姓名    
                .collect(toMap(UserInfo::getUserId, UserInfo::getRealName));
        //遍历打印
         map.forEach((k,v)->{
             System.out.println("key:"+k+"  "+"value: "+v);
         });
2.List存储对象条件过滤遍历
  //创建集合存储user对象
        List<UserInfo> userInfoList = new ArrayList<>();
        UserInfo user = new UserInfo();
        user.setUserId(1L);
        user.setRealName("zs");
        userInfoList.add(user);
        UserInfo user2 = new UserInfo();
        user2.setUserId(2L);
        user2.setRealName("ls");
        userInfoList.add(user2);
        //判断集合是否为空
        Optional.ofNullable(userInfoList)
                //集合为空返回默认
                .orElseGet(ArrayList::new)
                //创建并行流 相当于多线程无序
                .parallelStream()
                //过滤名字不能为空
                .filter(u -> StringUtils.isNotBlank(u.getRealName()))
                //转成list集合
                .collect(Collectors.toList())
                //遍历
                .forEach(u->{
                    System.out.println(u.getRealName());
                });
3.List存放string数据转为大小写
List<String> strList = Arrays.asList("a", "b", "d", "s", "n", "a", "s", "c", "d", null);
        //创建并行流
        strList.parallelStream()
                //过滤 非空判断
                .filter(s-> StringUtils.isNotBlank(s))
                //转成大写    toLowerCase转为小写
                .map(String::toUpperCase)
                //遍历
                .forEach(System.out::println);
4.获取List数据得到一个以逗号分隔的字符串
List<String> strList = Arrays.asList("a", "b", "d", "s", "n", "a", "s", "c", "d", "b","");
        String str = strList.parallelStream()
                //过滤条件
                .filter(s -> StringUtils.isNotBlank(s))
                //以逗号分隔数据
                .collect(Collectors.joining(","));
        //打印
        System.out.println(str);
5.List去重
List<String> strList = Arrays.asList("a","b","d","s","n","a","s","c","d", "b");
//原来集合长度
System.out.println(strList.size());
// 返回一个去掉重复元素之后的新的lis
List<String> noRepeatList = strList.stream()
//去重
.distinct()
//转为新集合
.collect(Collectors.toList());
//新集合长度
System.out.println(noRepeatList.size());
6.List存储int数据查找最大值最小值
       //创建集合存放int数据
        List<Integer> ints = Stream.of(1,2,4,3,5).collect(Collectors.toList());
        //创建并行流
        int asInt = ints.parallelStream()
                //查找最大值
                .max(comparing(i->i))
                //返回最大值
                .get();
        //打印
        System.out.println(asInt);

       //创建集合存放int数据
        List<Integer> ints2 = Stream.of(1,2,4,3,5).collect(Collectors.toList());
        //创建并行流
        int asInt = ints2.parallelStream()
                //查找最小值
                .min(comparing(i->i))
                //返回最小值
                .get();
 		// 集合中最大长度
        List<String> strList = Arrays.asList("a", "b", "d", "s", "n", "yu", "luo", "shuai", "spot", "xhuai");
        int max = strList.stream()
                // 判断条件:长度
                .mapToInt(s -> s.length())
                // 获取判断条件的最大值
                .max()
                // 转成int长度
                .getAsInt();
        //打印最大长度
        System.out.println(max);
                strList.stream()
                //过滤条件 查找元素中的最大值
                .filter(s -> s.length() == max)
                 //转成list集合       
                .collect(Collectors.toList())
                 //遍历打印
                .forEach(s->{
                    System.out.println(s);
                });

        // 集合中最小长度
        List<String> strList2 = Arrays.asList("a", "b", "d", "s", "nd", "yu", "luo", "shuai");
        //创建顺序流
        int min = strList2.stream()
                //判断条件: 长度
                .mapToInt(s -> s.length())
                //获取最小长度
                .min().getAsInt();
        //打印最小长度
        System.out.println(min);
7.List集合获取int元素的平方
 List<Integer> list = Arrays.asList(1, 2, 6, 9);
        //创建一个串行流
        list.stream()
                //取每个元素的平方
                .map(s -> s * s).collect(Collectors.toList())
                //打印
                .forEach(System.out::println);
8.List返回特定结果
		//返回特定结果
        List<String> strList = Arrays.asList("a", "b", "c", "d", "e", "f");
        //创建串行流
        strList.stream()
                .skip(2) // 扔掉前面2个元素
                .limit(3) // 返回前3个元素
                //转换成集合
                .collect(Collectors.toList())
                //打印
                .forEach(System.out::println);
9.List对int类型数据进行排序
   List<Integer> ints = Arrays.asList(5,8,9,4,3,2,7,1,6,2);
        //创建顺序流
        ints.stream()
                //排序规则后面-前面倒序排序
                //排序规则前面-后面正序排序
                .sorted((ln1, ln2) -> (ln1 - ln2)) // 排序
                .distinct()//去除重复元素 可选可不选 不用这个方法重复元素并列
                //转换成集合
                .collect(Collectors.toList())
                //遍历
                .forEach(System.out::println);
10.List匹配规则
       /**
         * allMatch: Stream 中全部元素符合传入的predicate, 返回true
         * anyMatch: Stream 中只要有一个元素符合传入的predicate, 返回true
         * noneMatch: Stream 中没有一个元素符合传入的predicate, 返回true
         */
        List<String> strList = Arrays.asList("a", "b", "d", "s", "n", "a", "s", "c", "d", "b");
        // 判断集合中有没有c元素, 返回值boolean
        boolean isExits = strList.stream().anyMatch(s -> s.equals("c"));
        //打印 true
        System.out.println(isExits);
        List<String> strList2 = Arrays.asList("a", "b", "d", "s", "n", "a", "s", "c", "d", "");
        // 判断集合是否全不为空
        boolean isFull = strList2.stream().allMatch(s -> s.isEmpty());
        //打印false
        System.out.println(isFull);
        //Stream 中没有一个元素符合传入的predicate, 返回true
        boolean isNotEmpty = strList2.stream().noneMatch(s -> s.isEmpty());
        //打印false
        System.out.println(isNotEmpty);
11.List存储对象数据按条件进行分组
       //创建集合存储user对象
        List<UserInfo> userInfoList = new ArrayList<>();
        UserInfo user = new UserInfo();
        user.setUserId(5L);
        user.setRealName("zs");
        userInfoList.add(user);
        UserInfo user2 = new UserInfo();
        user2.setUserId(3L);
        user2.setRealName("ls");
        userInfoList.add(user2);
        //返回一个map
        Map<Long, List<UserInfo>> map = userInfoList.parallelStream()
                //过滤条件 名字不能为空
                .filter(s -> StringUtils.isNotBlank(s.getRealName()))
                //使用userId进行分组
                .collect(groupingBy(UserInfo::getUserId));
            //遍历打印
            map.forEach((k,v)->{
                System.out.println("key:"+k+"  "+"value:"+v);
            });
12.流中的归约用法
 		//创建集合存储user对象
        List<UserInfo> userInfoList = new ArrayList<>();
        UserInfo user = new UserInfo();
        user.setUserId(5L);
        user.setRealName("zs");
        userInfoList.add(user);
        UserInfo user2 = new UserInfo();
        user2.setUserId(3L);
        user2.setRealName("ls");
        userInfoList.add(user2);
        //归约求和
        Optional<Long> reduce = userInfoList.stream()
                //过滤
                .filter(u -> StringUtils.isNotBlank(u.getRealName()))
                //提取userInfo的id
                .map(UserInfo::getUserId)
                //归约求和
                .reduce(Long::sum);
        System.out.println(reduce.get());
        //归约求最大值
        Optional<Long> reduce1 = userInfoList.stream()
                //提取
                .map(UserInfo::getUserId)
                //求最大值
                .reduce(Long::max);
        System.out.println(reduce1.get());
        //归约求最小值
        Optional<Long> reduce2 = userInfoList.stream()
                //提取
                .map(UserInfo::getUserId)
                //求最小值
                .reduce(Long::min);
        System.out.println(reduce2.get());
        //求平均值
        OptionalDouble average = userInfoList.stream()
                //提取
                .mapToLong(UserInfo::getUserId)
                //求平均值
                .average();
        System.out.println(average.getAsDouble());
  		//计数
        long count = userInfoList.stream()
                //提取
                .mapToLong(UserInfo::getUserId)
                //计数
                .count();
        //打印
        System.out.println(count);
13.Java8 summaryStatijstics配合流使用
 
//创建集合存储user对象
        List<UserInfo> userInfoList = new ArrayList<>();
        UserInfo user = new UserInfo();
        user.setUserId(5L);
        user.setRealName("zs");
        userInfoList.add(user);
        UserInfo user2 = new UserInfo();
        user2.setUserId(3L);
        user2.setRealName("ls");
        userInfoList.add(user2);
					//summaryStatijstics使用
LongSummaryStatistics summaryStatistics = userInfoList.stream()
    			//提取
                .mapToLong(UserInfo::getUserId)
                .summaryStatistics();
        //求最大值
        System.out.println("最大值:"+summaryStatistics.getMax());
        //求最小值
        System.out.println("最小值:"+summaryStatistics.getMin());
        //求和
        System.out.println("求和:"+summaryStatistics.getSum());
        //计数
        System.out.println("计数:"+summaryStatistics.getCount());
 		//求平均值
        System.out.println("平均值:"+summaryStatistics.getAverage());
14.Java8字符串转字符
		//字符串转字符数组
        List<String> strList = Arrays.asList("a", "b", "d", "s", "n", "yu", "luo", "shuai", "spot", "xhuai");
       //创建集合存放character元素
        List<Character> newList = new ArrayList<>();
                        //转换为char数组流
        strList.stream().map(String::toCharArray)
                //遍历存放character元素
                .forEach(s->{
                    //遍历每个元素
                    for (char c : s) {
                        //存放
                        newList.add(c);
                    }
                });
        //打印
        newList.stream().forEach(System.out::println);
	 //第二种写法
	 strList.stream().map(String::toCharArray)
                //对转换的char[]数组整合
                .flatMapToInt(chars -> CharBuffer.wrap(chars).chars())
                //转换为char类型
                .mapToObj(e -> (char) e)
                //转为集合存储
                .collect(Collectors.toList())
                //遍历
                .forEach(System.out::println);
15.取List中的数据返回一个新对象集合
       //构造测试数据
        List<Student> list = new ArrayList<>();
        Student stu = new Student();
        stu.setId(1L);
        stu.setName("ZS");
        list.add(stu);
        Student stu2 = new Student();
        stu2.setId(2L);
        stu2.setName("ls");
        list.add(stu2);
        list.add(null);
        System.out.println(list);
         List<Person> perList = list.stream()
                    //过滤条件
                    .filter(Objects::nonNull)
                    //构造信息
                    .map(s -> {
                        Person person = new Person();
                        //重新赋值
                        person.setId(s.getId());
                        person.setAge(18);
                        person.setName(s.getName());
                        return person;
                    })
                    //返回新集合
                    .collect(Collectors.toList());
            //打印
            perList.forEach(System.out::println);
16.把对象转为流并进行操作
//构造测试数据
       //构造测试数据
        UserInfoVO postUserInfo = new UserInfoVO();
        postUserInfo.setUserId(143L);
        postUserInfo.setCreateUserId(153L);
        postUserInfo.setMobile("12345678910");
        //构造要返回的参数
        OrderMessageRequest newOrderMessageRequest = Stream.of(postUserInfo)
                    .map(u -> {
                        //过滤条件
                        if ((!u.getCreateUserId().equals(u.getUserId())) && StringUtils.isNotBlank(u.getMobile())) {
                            //构造发送短信需要的数据
                            OrderMessageRequest orderMessageRequest = new OrderMessageRequest();
                            // 获取驿站人员手机号
                            orderMessageRequest.setMobile(u.getMobile());
                            //是驿站人员
                            orderMessageRequest.setIsCourierStation("1");
                            System.out.println("驿站重新赋值成功");
                            return orderMessageRequest;
                        } 
                            //不是驿站人员给运营人员发短信
                            OrderMessageRequest orderMessageRequest =  new OrderMessageRequest();
                            //不是驿站人员
                            orderMessageRequest.setIsCourierStation("0");
                            System.out.println("运营重新赋值成功");
                            return orderMessageRequest;
                    })
                 	//返回任意一个元素   这里只有一个元素因为我们只有一个对象
                    .findAny()
                    //为空返回默认
                    .orElseGet(OrderMessageRequest::new);  
17.提取list集合对象中的某列数据转为新集合
 List<UserLoginInfoVO> list = new ArrayList<>();
        UserLoginInfoVO userLoginInfoVO = new UserLoginInfoVO();
        userLoginInfoVO.setMobile("15655654654");
        userLoginInfoVO.setPushToken("textPushToken");
        list.add(userLoginInfoVO);
        UserLoginInfoVO userLoginInfoVO2 = new UserLoginInfoVO();
        userLoginInfoVO2.setMobile("12345678910");
        userLoginInfoVO2.setPushToken("textPushToken2");
        list.add(userLoginInfoVO2);
        UserLoginInfoVO userLoginInfoVO3 = new UserLoginInfoVO();
        userLoginInfoVO3.setMobile("123565645567");
        userLoginInfoVO3.setPushToken("textPushToken3");
        list.add(userLoginInfoVO3);
        list.stream()
                //过滤
                .filter(u -> u != null)
                //提取
                .map(UserLoginInfoVO::getMobile)
                //转为新集合
                .collect(Collectors.toList())
                //打印
                .forEach(System.out::println);
18.提取list中的数据转为数组
List<UserLoginInfoVO> list = new ArrayList<>();
        UserLoginInfoVO userLoginInfoVO = new UserLoginInfoVO();
        userLoginInfoVO.setMobile("15655654654");
        userLoginInfoVO.setPushToken("textPushToken");
        list.add(userLoginInfoVO);
        UserLoginInfoVO userLoginInfoVO2 = new UserLoginInfoVO();
        userLoginInfoVO2.setMobile("12345678910");
        userLoginInfoVO2.setPushToken("textPushToken2");
        list.add(userLoginInfoVO2);
        UserLoginInfoVO userLoginInfoVO3 = new UserLoginInfoVO();
        userLoginInfoVO3.setMobile("123565645567");
        userLoginInfoVO3.setPushToken("textPushToken3");
        list.add(userLoginInfoVO3);
        String[] arrays = list.stream()
                //提取
                .map(UserLoginInfoVO::getMobile)
                //转为string数组
                .toArray(String[]::new);
        //打印
        Stream.of(arrays).forEach(System.out::println);
19.partitioningBy 按某个条件分组
/按某个条件分组
//给一组年龄,分出成年和未成年
List<Integer> ageList = Arrays.asList(11, 22, 13, 14, 25, 26);
    Map<Boolean, List<Integer>> ageMap = ageList.stream()
            .collect(Collectors.partitioningBy(age -> age > 18));
    System.out.println("未成年:" + ageMap.get(false));
    System.out.println("成年:" + ageMap.get(true));
    // 输出结果
// 未成年:[11, 13, 14]
// 成年:[22, 25, 26]
<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`(避免类型擦除开销) ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值