学习Java8新特性这一篇就够了

目录

  • Java 8新特性简介
  • 1. Lambda表达式
    • 1-1. Lambda表达式的使用
    • 1-2. 总结
  • 2. 函数式接口
    • 2-1. 函数式接口
    • 2-2. Java内置的函数式接口
  • 3. 方法引用
  • 4. Stream API
    • 4-1 什么是Stream
    • 4-2 为什么要使用Stream API
    • 4-3 Stream 的三个操作步骤
    • 4-4 Stream 的操作
      • 创建方式
      • 中间操作

Java 8新特性预览

  1. 函数式接口
  2. Lambda表达式
  3. 方法引用/构造器引用
  4. Stream API
    • 串行流
    • 并行流
  5. Optional类
  6. 接口增强
    • 静态方法
    • 默认方法
  7. 新的时间和日期API
  8. 其他新特性
    • 重复注解
    • 类型注解
    • 通用目标类型推断
    • JDK的更新
    • 新的编译工具
      • jjs
      • jdeps
    • JVM
      • Metaspace取代PermGen空间

Java 8新特性简介

Java8 (又称为jdk1.8) 是Java语言开发的一个主要版本。Java8是oracle公司于2014年3月发布,可以看成是自Java5以来最具革命性的版本。Java8为Java语言、编译器、类库、开发工具与JVM带来了大量新特性。

  • 速度更快
  • 代码更少(增加了新的语法:Lambda表达式)
  • 强大的Stream API
  • 便于并行
  • 最大化减少空指针异常:Optional
  • Nashorn引擎,允许在JVM上运行JS应用

1. Lambda表达式

Lambda是一个匿名函数,我们可以把Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。使用它可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。

1-1. Lambda表达式的使用

举例:

(o1, o2) -> Integer.compare(o1, o2);

格式:

  • ->:lambda操作符 或 箭头操作符
  • ->左边:Lambda形参列表 (其实就是接口中的抽象方法的形参列表
  • ->右边:Lambda体(其实就是重写的抽象方法的方法体

Lambda表达式的本质

  • 作为函数式接口的实例

格式1:无参

	// 语法格式一:无参
    public void test1() {
        Runnable r1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("生与死轮回不止");
            }
        };
        // lambda表达式
        Runnable r2 = () -> System.out.println("生与死轮回不止");
    }

格式2:有参

  • 参数类型可以省略
  • 当只有一个参数时,()可以省略
	// 语法格式二:需要参数
    public void test2() {
        Consumer<String> con = new Consumer<String>(){
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        con.accept("谎言和誓言的区别是什么?");
		// 参数s的类型可以省略,通过Consumer进行类型推断
        Consumer<String> con2 = (s) -> System.out.println(s);
        con.accept("一个是听的人当真了,一个是说的人当真了");
    }

格式3:Lambda体只有一条语句

return与大括号若有,都可以省略

1-2. 总结

  • ->左边:Lambda形参列表的参数类型可以省略,如果Lambda形参列表只有一个参数,()可以省略
  • ->右边:Lambda体应该使用一对{}包裹,如果Lambda体只有一条语句(可能是return语句),return与一对{}都可以省略
  • Lambda只能对函数式接口进行改写
  • 以前用匿名实现类表示的现在都可以用Lambda表达式来写。

2. 函数式接口

2-1. 函数式接口

  • 在一个接口中,只声明了一个抽象方法,则此接口就称为函数式接口
  • 可以通过@FunctionalInterface注解限制接口中只能有一个抽象方法
  • 可以通过Lambda表达式来创建函数式接口的对象。(若Lambda表达式抛出一个受检异常(即:非运行时异常),那么该异常需要在目标接口的抽象方法上进行声明)

2-2. Java内置的函数式接口

学习Java8新特性这一篇就够了_第1张图片
学习Java8新特性这一篇就够了_第2张图片

3. 方法引用

  • 当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!
  • 方法引用可以看做是Lambda表达式深层次的表达。换句话说,方法引用就是Lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向个方法,可以认为是Lambda表达式的一个语法糖。

格式

  • 使用操作符“::”将类(或对象)与方法名分隔开来

3种使用情况

  • 对象::实例方法名
  • 类::静态方法名 用到的多
  • 类::实例方法名

使用条件

  • 实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致才可以使用方法引用!

学习Java8新特性这一篇就够了_第3张图片

4. Stream API

4-1 什么是Stream

  • Stream是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。
  • 集合讲的是数据,Stream进的是计算!

注意

  1. Stream自己不会存储元素
  2. Stream不会改变源对象。相反,他们会返回一个持有结果的新Stream。
  3. Stream操作是延迟执行的。这意味着他们会等到需要结果的时候才执行

4-2 为什么要使用Stream API

  • 实际开发中,项目中多数数据源都来自于ysql,Oracle等。可以在这些关系型数据库中使用sql命令进行数据的处理。
  • 但现在数据源可以更多了,有MongDB,Radis等,而这些NoSQL的数据就需要Java层面去处理。

4-3 Stream 的三个操作步骤

1. 创建Stream

  • 一个数据源(如:集合、数组),获取一个流

2. 中间操作

  • 一个中间操作链,对数据源的数据进行处理

3. 终止操作

  • 一旦执行终止操作,就执行中间操作链并不是到了一个中间操作,就执行一个,而是执行终止操作后,才执行中间操作),并产生结果。之后,这个流不会再被使用。

学习Java8新特性这一篇就够了_第4张图片

4-4 Stream 的操作

创建方式

1. 集合:通过Collection接口的默认方法获取

接口的默认方法只能由其实现类来调用

 List<String> list = new ArrayList<>();
 Stream<String> stream = list.stream();

2. 数组:通过Arrays的静态方法stream()获取

String[] strArr = new String[2];
Stream<String> stream1 = Arrays.stream(strArr);

中间操作

1. 筛选与切片

学习Java8新特性这一篇就够了_第5张图片

List<Employee> list = EmployeeData.getEmployees();

//filter(Predicate p)一接收Lambda,从流中排除某些元素。
Stream<Employee>stream = list.stream();
//练习:查询员工表中薪资大于7000的员工信息
stream.filter(e -> e.getsalary()>7000).forEach(System.out::println);

//limit(n) 截断流,使其元素不超过给定数量,即top(n)。
//练习:查询前3个员工
list.stream().limit(3).forEach(System.out::println);

//skip(n) 跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回空流
//练习:跳过前3个员工,查询剩余员工
list.stream().skip(3).forEach(System.out:println);

//distinct() 筛选,通过流所生成元素的hashCode()和equals()去除重复元素
list.stream().distinct().forEach(System.out:println)

2. 映射

学习Java8新特性这一篇就够了_第6张图片

//将该流中的元素类型映射成另外一种
list.stream.map(e -> e.getName).forEach(System.out::println);

3. 排序

学习Java8新特性这一篇就够了_第7张图片

你可能感兴趣的:(JavaSE,java)