美文网首页
java8新特性

java8新特性

作者: ZMRWEGo | 来源:发表于2019-04-02 16:18 被阅读0次

    java8相对于此前的版本有一个很大的更新,相较于java7,它新增了lambda表达式,流API,以及JVM和一些底层数据结构的优化。这里我们着重认识一下lambda表达式和流API。

    一、lambda表达式

    1.1 为什么要出现lambda表达式?

    简化了操作,但是可读性降低了?

    1.2 lambda表达式的使用

    • 一个 Lambda 表达式可以有零个或多个参数
    • 参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a)与(a)效果相同
    • 所有参数需包含在圆括号内,参数之间用逗号相隔。例如:(a, b) 或 (int a, int b) 或 (String a, int b, float c)
    • 空圆括号代表参数集为空。例如:() -> 42
    • 当只有一个参数,且其类型可推导时,圆括号()可省略。例如:a -> return a*a
    • Lambda 表达式的主体可包含零条或多条语句
    • 如果 Lambda 表达式的主体只有一条语句,花括号{}可省略。匿名函数的返回类型与该主体表达式一致
    • 如果 Lambda 表达式的主体包含一条以上语句,则表达式必须包含在花括号{}中(形成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空
    int a, int b) -> {  return a + b; }
    
    () -> System.out.println("Hello World");
    
    (String s) -> { System.out.println(s); }
    
    () -> 42
    
    () -> { return 3.1415 };
    
    函数式接口

    函数式接口是只包含一个抽象方法声明的接口
    每个lambda表达式都能隐式地复制给函数式接口,我们可以通过lambda表达式创建Runnable接口的引用

    Runnable r = ()->1+1;
    

    当不指明函数式接口时,编译器会自动解释这种转化

    new Thread(
    ()->1+1;
    ).start;
    

    当然,我们可以使用@FunctionalInterface自己定义一个接口,但注意此接口只能含有一个方法,否则编译器会抛出异常,不声明该注解,但只有一个方法的接口也可以直接用lambda表达式
    下面的例子使用lambda表达式打印链表中每个元素的平方,我们使用.stream()方法将常规链表转化为流

    List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
    list.stream().map((x)->x*x).forEach((n)->System.out.println(n));
    list.stream().map((x) -> x*x).forEach(System.out::println);
    

    上面是一个mapReduce的初级例子,下面我们再看一个例子

    //Old way:
    List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
    int sum = 0;
    for(Integer n : list) {
        int x = n * n;
        sum = sum + x;
    }
    System.out.println(sum);
    
    //New way:
    List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
    int sum = list.stream().map(x -> x*x).reduce((x,y) -> x + y).get();
    System.out.println(sum);
    

    二、流式处理

    2.1 什么是流

    流是针对于java集合的,结合函数式编程完成对java集合元素的相关操作
    Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator。原始版本的 Iterator,用户只能显式地一个一个遍历元素并对其执行某些操作;高级版本的 Stream,用户只要给出需要对其包含的元素执行什么操作,比如 “过滤掉长度大于 10 的字符串”、“获取每个字符串的首字母”等,Stream 会隐式地在内部进行遍历,做出相应的数据转换。

    2.2 流的使用

    常用的操作为filter、map、reduce

    1. filter用来对元素进行过滤,接收一个Prediction对象(类似于Consumer)。
            List<Integer> list = Arrays.asList(1, 2, 3);
            list.stream().filter((x)->x%2!=0).forEach(System.out::println);
    

    2.map操作,对元素进行映射

            List<Integer> list = Stream.of(1, 2, 3).map((x) -> x * x).collect(Collectors.toList());
    或
        List<Integer> list = Stream.of(1, 2, 3).map((x) -> x * x).collect(Collectors.toCollection(ArrayList:new));
    

    相关文章

      网友评论

          本文标题:java8新特性

          本文链接:https://www.haomeiwen.com/subject/aalgbqtx.html