Java8新特性Stream学习(一)初露锋芒

2018-08-24  本文已影响19人  惜鱼

初露锋芒

距离Java8发布已经过了四年,但是很多朋友依旧使用着Java7,甚至Java6,也不是说不行,但是对于新的东西我们还是要敢于去尝试,毕竟可以带来一定效率提升,为了帮助更多朋友过渡到Java8,所以把自己学习的一些总结写出来,希望新手可以少走很多弯路。使用JDK8如果没有使用它的新特性,和没有使用JDK8是同一回事。

image

初识Lambda

讲到Stream咱们必须了解一下Lambda,因为Stream里面API大部分都是基于Lambda实现的,可以说Stream将Lambda使用的淋漓尽致,说个题外话,在响应式编程并不提倡使用java提供Stream来完成流式操作,而是推荐使用实现了响应式规范的框架Reactor 3,当然在Spring5.0之后使用WebFlux也可以很好的体验响应式编程,如果后期有时间本人会更新相应的文章。不过咱们也不需要担心Webflux学起来困难,因为把Stream学好可以很快上手。

什么是Lambda

第一个Lambda
BinaryOperator<Integer> sum = (x, y) -> x + y;

提到Lambda相信很多第一会说,带有->的就是Lambda,的确Lambda表达式其中一个明显的特征就是使用->来表示。让我们回到第一个Lambda,从代码中可以看到我们定义了一个x和一个y,然后使用->来连接对应操作。从这里可以看出Lambda是一组表达式,仅仅是一组表达式么,那肯定不是了,让我们看下面这个例子,看不懂的业没有关系,因为我们后面会讲到的。

students.stream().filter(student -> {
            System.out.println(student.getName());
            return student.isMan();
        });

在上面这段代码中,我们输出了学生的姓名,然后还返回了一个Boolean值,这时我们又可以得知一点Lambda还可以是方法(是不是感觉和匿名方法很像,这里就是匿名方法,不过比之前的匿名方法看起来更简洁,后面会详细讲解的)。当然不仅如此,在lambda中还可以使用局部变量,<b>不过请悉知lambda中并不是引用的变量,而是值,在lambda中的className是使用final修饰的,只不过java帮我们隐藏了。</b>

String className = "高三五班";
students.stream().peek(student -> student.setClassName(className));

lambda重要的接口

方法名 参数 返回类型 示例
Predicate<T> T boolean 这个学生是男生吗
Consumer<T> T void 输出一个值
Function<T,R> T R 获得Artist 对象的名字
Supplier<T> None T 工厂方法
UnaryOperator<T> T T 逻辑非( !)
BinaryOperator<T> (T, T) T 数值计算

lambda接口创建

看了官方的介绍,对于函数式接口定义:一个接口中只能包含一个抽象方法,static和default修饰的不计(在java8之后支持在接口中有默认实现,只需要用default修饰即可),在接口中添加@FunctionalInterface即可,@FunctionalInterface也可以不用加,不过加上这个注解我们便能一目了然它是一个函数式的接口。下面我们看一个简单的Demo。

一、函数式接口的定义

@FunctionalInterface
public interface Numerical {

    /**
     * 默认方法
     * @param message
     */
    void hello(String message);

    /**
     * 数值计算
     * @param x
     * @param y
     * @param m
     * @return
     */
    static<T> T calc(BinaryOperator<T> m, T x, T y){
        return m.apply(x, y);
    }
}

二、使用
public class Demo {

    public static void main(String[] args) {
        // 自己实现一个函数式接口
        Numerical numerical = (message -> System.out.println("Hello:" + message));
        numerical.hello("Tom");
        
        // 利用Lambda实现一个灵活的数值计算器
        
        // 求和
        BinaryOperator<Integer> sum = (x, y) -> x + y;
        System.out.println("sum:" + sum.apply(5, 10));

        // 求积
        BinaryOperator<Integer> product = (x, y) -> x * y;
        System.out.println("product:" + product.apply(5, 10));

        // 复杂运算
        BinaryOperator<Integer> complex = (x, y) -> ((x - 1) * (y * y)) - 5;
        System.out.println("complex:" + complex.apply(5, 10));
    }
}

================================
结果:
Hello:Tom
sum:15
product:50
complex:395
=================================

总结

  1. Lambda是一个匿名方法,将行为像数据一样进行传递。
  2. 函数式接口指的是仅有一个抽象方法的接口,用来表示Lambda的类型。

转载请注明:https://tisnz.com/2018/08/24/stream-01/

上一篇下一篇

猜你喜欢

热点阅读