java 8 lambda一些个人总结

在编写程序的时候,当你的 jdk 为8 时,你会看到很多类似这样的代码

bList.stream().reduce((a,b) -> a.add(b)); 

如果你之前没有接触过 Java8 的新特性,肯定会对这个有疑惑,看不懂。所以最简单的需求就是:看懂代码,然后学会新特性,让自己也能写出类似上面这样简洁的代码。

通过网上的查询,了解,通过自己的实践敲代码,然后就是记下这篇的感悟。

首先我们要知道这样的写法是来自于 Java8 的新特性:lambda(函数式编程)

在 Java8 中,lambda 是依赖于函数式接口的,函数式接口是什么呢?

函数式接口:简单来说就是一个接口 (interface)只有一个方法。不能有多余的方法,当然默认方法除开,比如下面:

interface  PersonInterface{
    int a(int c,int b);
    default void a(){
        System.out.println("hello");
    }
}
如果有一个方法需要用到这个接口当中参数,比如如下:
public static void test(PersonInterface c){
    int a = 5;
    int b= 2;
    System.out.println(c.a(a,b));
}

我们常见的方式就是:

test(new PersonInterface() {
    @Override
    public int a(int c, int b) {
        return c+b;
    }
});//通过匿名类的方式实现 PersonInterface 接口。

但是现在如果你的 jdk 是 8 ,那么你可以尝试这样写:

test((a,b) -> a+b);

它们的结果是一致的。

通过上面简单的一个例子,让我们知道了 lambda 的使用,下面就先熟息下 lambda 的语法。

Lambda 的语法

三部分:

      参数:可以有参数,有时又没有,主要还是看方法是否需要参数,跟方法对应的参数个数一致。

                 无参数的时候:() ->  { expression }  

                 单参数的时候:a -> { expression }

                 多参数的时候:(a,b .....) -> { expression } 

      符号:->

      方法体:表达式或者代码段,当方法有返回值时就需要 return (单行代码时,默认有 return 的),如果是 void 那就不需要。当代码行多时,就用 {} 括起来,单行的话,不需要。

下面多看几个例子:

List<Person> pList = Arrays.asList(new Person(18,"美呀"), new Person(6,"小新"), new Person(1,"小葵"));

pList.stream().forEach(new Consumer<Person>() {
    @Override
    public void accept(Person person) {
        System.out.println(person.getName());
    }
});

pList.stream().forEach(p -> System.out.println(p.getName()));
List<BigDecimal>  bList = Arrays.asList(new BigDecimal(18), new BigDecimal(26), new BigDecimal(23));
System.out.println(bList.stream().reduce(new BinaryOperator<BigDecimal>() {
    @Override
    public BigDecimal apply(BigDecimal bigDecimal, BigDecimal bigDecimal2) {
        return bigDecimal.add(bigDecimal2);
    }
}));

System.out.println(bList.stream().reduce((a,b) -> a.add(b)));

stream.reduce 等等这些写法,可以暂时不去纠结,它也是 java8 新特性 流(stream)。我们重点看 lambda 的写法。

通过上面的例子我们可以看出第一点:那就是 lambda 的方法体其实就是函数式接口中方法的实现:

a.add(b) == bigDecimal.add(bigDecimal2)     p.getName() == person.getName()

第二点:lambda 的参数,其实就是函数式接口中方法的参数

apply(BigDecimal bigDecimal, BigDecimal bigDecimal2) == (a,b)    accept(Person person) == p

综上两点,可以看出 lamdba 其实就是对函数式接口的实现(有点像匿名类,但是代码有简洁太多啦),前面是函数式接口中方法的参数,后面就是方法中的内容。

到这里:我们就已经可以看懂这些代码,同时也会写啦。首先,需要函数式接口(一个接口只能有一个方法,为了防止很多人把它当成普通接口,可以在接口名上面加一个注解 @FunctionalInterface,它会为你检测的,当你想加入第二个方法的时候,会报错的),然后就是开始 lambda 的写法啦。

 

还没有完,当我们写代码的时候会发现,方法里面有很多内容,这个时候发现 lambda 写法代码也开始变多啦。所以引出了一个更简化的写法:方法引用。

方法引用格式:

       (ClassName :: methodName) 、(ClassName :: new) 这个是调用构造函数

例子:

bList.stream().mapToDouble(BigDecimal :: doubleValue).reduce(Double :: sum)
bList.stream().mapToDouble(new ToDoubleFunction<BigDecimal>() {
    @Override
    public double applyAsDouble(BigDecimal value) {
        return value.doubleValue();
    }
}).reduce(Double :: sum)

bList.stream().mapToDouble(BigDecimal :: doubleValue).reduce(new DoubleBinaryOperator() {
 @Override 
public double applyAsDouble(double left, double right) {
 return left + right; 
} 
})

从上面的例子可以看出,BigDecimal :: doubleValue     value.doubleValue(); 其实就是让参数调用 doubleValue  方法,Double :: sum   left + right  也是不断的让 集合中的 值相加,其实也就是 sum 加总。

 

至此:lamdba 在 Java8 中的写法和运用都写在上面了,第一个就是函数式接口,熟息 lambda 语法,第二就是方法引用。学会这个后,后面就要去了解 stream 流,因为 lambda 如果不和 stream 结合起来,你会发现用到的地方不是很多。而 stream 会在下篇介绍。

目前理解只有这样,如果有人发现问题,欢迎指出,相互交流。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值