JAVA8 Lambda表达式详解

语法基础

java8中lambda表达式主要用来解决java中函数式编程语法太拖沓。

什么是函数式编程呢,我们来看个例子。

下面的代码是根据字符串长度来排序

List<String> strs = new ArrayList<>();
strs.add("123");
strs.add("123456");
strs.add("12");

Collections.sort(strs, new Comparator<String>() {
     @Override
     public int compare(String s1, String s2) {
          return Integer.compare(s1.length(), s2.length());
     }
});

 Collections.sort第二个参数是排序规则,在js中可以通过传递函数来实现,java中不允许直接传递函数,只能通过匿名内部类来实现,但是代码就显得很冗余,再来看看lambda的实现方式

//不需要new对象了,省略了方法名
Collections.sort(strs, (String s1, String s2) -> {
     return Integer.compare(s1.length(), s2.length());
});

//lambda支持类型推断,参数不需要写类型
Collections.sort(strs, (s1, s2) -> {
     return Integer.compare(s1.length(), s2.length());
});

//方法体里面只有单行代码可以省略括号,return和分号
Collections.sort(strs, (s1, s2) -> Integer.compare(s1.length(), s2.length()));

可以看到,通过层层省略只需要一行代码就能实现了 

函数式接口

什么是函数式接口呢?接口里面只有一个方法的就是函数式接口,只有函数式接口才能使用lambda表达式!

java8提供了很多内置函数式接口供开发者使用,常用的是以下几个

 消费型接口可以实现你提供一种资源,具体如何使用资源由调用方决定,比如你女朋友要买东西,你只需要提供钱包即可,具体买什么由你女朋友决定

@Test
public void testComsumer() {
    //如果参数只有一个可以省略括号
    buy(money -> System.out.println(StrUtil.format("你的女朋友拿到{}元,消费{}元", money, 5)));
}

public void buy(Consumer<Integer> consumer) {
    int money = 10; //你的钱包,真实环境中应该是个对象
    consumer.accept(money);//把你的钱包交给你女朋友消费
}

 供给型正好相反,调用方提供资源,由你决定如何使用资源,比如你们公司福利比较好,每天下午有免费饮料可以喝,但是喝什么饮料完全是随机的

    @Test
    public void testDrink() {
        //公司随机提供一款饮料
        String[] drinks = new String[]{"奶茶", "咖啡", "旺仔牛奶"};
        drink(() -> drinks[RandomUtil.randomInt(drinks.length)]);
    }

    public void drink(Supplier<String> supplier) {
        //获取到饮料
        String drink = supplier.get();
        //开始喝
        System.out.println("我今天喝的饮料是" + drink);
    }

 函数型顾名思义,可以提供一种映射关系,把一种输入转换成另一种输出,比如把数组里的数值都乘以2输出,具体如何转换由调用方决定,算是策略模式的一种变形

    @Test
    public void testTransform() {
        List<String> numbers = new ArrayList<>();
        numbers.add("111");
        numbers.add("222");
        numbers.add("333");
        //提供转换策略,输出[111, 222, 333]
        List<Integer> intNum = transform(numbers, item -> Integer.parseInt(item));
        System.out.println(intNum);
        //提供转换策略,输出[222, 444, 666]
        List<Integer> multiNum = transform(numbers, item -> Integer.parseInt(item) * 2);
        System.out.println(multiNum);
    }

    //T是输入类型,R是输出类型
    public <T, R> List<R> transform(List<T> input, Function<T, R> transform) {
        List<R> output = new ArrayList<>();
        for (T item : input) {
            output.add(transform.apply(item));
        }
        return output;
    }

断定型就很简单了,可以用来做过滤,具体的过滤策略可以由调用方提供

 

    @Test
    public void testFilter() {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        //调用方提供过滤策略,返回大于2的值
        list = filter(list, item -> item > 2);
        //输出3
        System.out.println(list);
    }

    public List<Integer> filter(List<Integer> list, Predicate<Integer> predicate) {
        List<Integer> returnList = new ArrayList<>();
        for (Integer item : list) {
            //满足条件的返回
            if (predicate.test(item)) {
                returnList.add(item);
            }
        }
        return returnList;
    }

方法引用

 方法引用的格式为 类::方法名,是lambda的一种简写形式

        //这个消费型接口用来打印获取到的字符串
        Consumer<String> consumer = s -> System.out.println(s);
        //等价上面的代码,参数和箭头可以省略,打印的参数就是s
        consumer = System.out::println;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值