Lambda表达式使用示例

前言

Lambda表达式是 Java 8 发布的最重要新特性。Lambda 允许把函数作为一个方法的参数,也即是可以将函数作为参数传递到方法中。使用 Lambda 表达式可以使我们的代码变的更加简洁紧凑也更便于我们理解。

该文章仅仅只是记录一下本人在工作中用到的一些示例,不会介绍Lambda的一些底层原理,如函数式接口、方法引用等。如果大家需要了解这些知识,还请各位自行查阅相关资料。

准备工作

为了便于后续示例的编写,需要首先定义一个实体类:

package com.learn.lambda;

import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class LambdaDemo {
    private String item;
    private Integer statNum;
    private String itemValue;
    /**
     * 扩展字段 写入任意信息
     */
    private Object extendInfo;

    public LambdaDemo(String item, Integer statNum) {
        this.item = item;
        this.statNum = statNum;
    }
}

初始化样例数据:

private static List<LambdaDemo> demoList = new ArrayList<>();
    static {
        LambdaDemo demo1 = new LambdaDemo("001",100);
        LambdaDemo demo2 = new LambdaDemo("002",200);
        LambdaDemo demo3 = new LambdaDemo("003",300);
        LambdaDemo demo4 = new LambdaDemo("004",400);
        LambdaDemo demo5 = new LambdaDemo("005",500);
        LambdaDemo demo6 = new LambdaDemo("006",600);
        LambdaDemo demo7 = new LambdaDemo("007",700);
        LambdaDemo demo8 = new LambdaDemo("008",800);
        LambdaDemo demo9 = new LambdaDemo("009",900);
        LambdaDemo demo10 = new LambdaDemo("010",1000);
        demoList.add(demo1);
        demoList.add(demo2);
        demoList.add(demo3);
        demoList.add(demo4);
        demoList.add(demo5);
        demoList.add(demo6);
        demoList.add(demo7);
        demoList.add(demo8);
        demoList.add(demo9);
        demoList.add(demo10);
    }

到此准备工作基本已经完成。

示例

List集合转为Map集合

转换成map是如果没有重复key的情况是可以使用下边的方式

/**
 * list转为Map
 */
public static void listToMap(){
    Map<String, Integer> collect = demoList.stream().collect(Collectors.toMap(LambdaDemo::getItem, LambdaDemo::getStatNum));
    collect.forEach((key,value)-> System.out.println(key+":"+value));
    
    //如果value 为空的话 可以进行下判断
    Map<String, Integer> map = demoList.stream().collect(Collectors.toMap(LambdaDemo::getItem, p -> p.getStatNum() == null ? 0 : p.getStatNum()));
    System.out.println(map);
}
    

如果转换成map后有重复key值的话将会出现报错,将
样例数据
设置为有key值重复的情况。

LambdaDemo demo1 = new LambdaDemo("001",100);
LambdaDemo demo2 = new LambdaDemo("001",200);

再次执行上边的代码将会出现如下错误:

Exception in thread "main" java.lang.IllegalStateException: Duplicate key 100
	at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
	at java.util.HashMap.merge(HashMap.java:1254)
	at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
	at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)

解决该问题其实也很简单,如下是将重复key的value值相加,如果是String类型的话可以使用逗号隔开进行拼接。具体根据自己的实际业务需求进行相应的处理。

/**
 * list转为Map 解决重复key值的问题
 * 将值相加
 */
public static void listToMapSolveDuplicateKey(){
    Map<String, Integer> collect = demoList.stream().collect(Collectors.toMap(LambdaDemo::getItem, LambdaDemo::getStatNum,(oleValue,newValue)->oleValue+newValue));
    collect.forEach((key,value)-> System.out.println(key+":"+value));
}

运行输出结果为:

001:300     //001的值为300,说明已经将重复key值的value相加
003:300
004:400
005:500
006:600
007:700
008:800
009:900
010:1000

还可以进行覆盖操作:

/**
 * list转为Map 解决重复key值的问题
 * 将值覆盖
 */
public static void listToMapSolveDuplicateKey2(){
    Map<String, Integer> collect = demoList.stream().collect(Collectors.toMap(LambdaDemo::getItem, LambdaDemo::getStatNum,(oleValue,newValue)->newValue));
    collect.forEach((key,value)-> System.out.println(key+":"+value));
}

关键点就在于使用哪一个值,oleValue为第一个key对应的值,newValue为第二个相同key对应的值。

(oleValue,newValue)->newValue)
(oleValue,newValue)->oleValue)

list转为Map集合并进行分组

Map<String, List<LambdaDemo>> stringListMap =regionList.stream().collect(Collectors.groupingBy(LambdaDemo::getItem));

计算对象中的某值之和

/**
 * list 计算对象中的某值之和
 */
public static void listSum(){
    int sum = demoList.stream().mapToInt(LambdaDemo::getStatNum).sum();
    System.out.println(sum);
}

除了mapToInt方法外,还有mapToDouble、mapToLong等方法。可以按需使用。

list转换为字符串

逗号也可以根据需求换成其他相关的符号

/**
 * 将list转换为使用逗号隔开的字符串
 */
public static void listToString(){
    String value = demoList.stream().map(lambdaDemo -> String.valueOf(lambdaDemo.getItem())).collect(Collectors.joining(","));
    System.out.println(value);
}

list转换为list

样例数据中的list中存放的是对象,我们可以将对对象中的item抽取出来转换成一个新的list

/**
 * list转换为list
 */
public static void listToList(){
    List<String> stringList = demoList.stream().map(LambdaDemo::getItem).collect(Collectors.toList());
    stringList.forEach(System.out::println);
}

删除数据

使用Lambda删除数据也是非常方便的:

/**
 * 删除数据
 */
public static void removeData(){
    demoList.removeIf(lambdaDemo->lambdaDemo.getItem().equals("001"));
    demoList.forEach(lambdaDemo -> System.out.println(lambdaDemo.getItem()));
}

排序

样例数据中的statNum的数据打乱,可以使用如下方式进行排序:

/**
 * 排序
 */
public static void sortData() {
    //正序
    demoList.sort(Comparator.comparing(LambdaDemo::getStatNum));
    demoList.forEach(lambdaDemo -> System.out.println(lambdaDemo.getStatNum()));
    System.out.println("----------");
    //倒序
    demoList.sort(Comparator.comparing(LambdaDemo::getStatNum).reversed());
    demoList.forEach(lambdaDemo -> System.out.println(lambdaDemo.getStatNum()));
}

过滤

过滤也是比较常用的,比如我们过滤出statNum等于500的记录

    /**
     * 过滤
     */
    public static void filter(){
        Stream<LambdaDemo> lambdaDemoStream = demoList.stream().filter(lambdaDemo -> lambdaDemo.getStatNum() == 500);
        lambdaDemoStream.forEach(lambdaDemo -> {
            System.out.println(lambdaDemo.getStatNum());
        });

    }
以上只是本人在当前工作中使用到的部分示例,意在做下简单记录以备忘记时及时查询。我会不定时更新,欢迎大家评论区补充!
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值