Java8 新特性1—— Lambda表达式、内置函数式接…

2020-03-08 16:02:02来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

Java8 新特性1—— Lambda表达式、内置函数式接口、方法引用与构造器引用

Java 8是Java的一个重大版本,有人认为,虽然这些新特性领Java开发人员十分期待,但同时也需要花不少精力去学习。在这一小节中,我们将介绍Java 8新特性中Lambda表达式、内置函数式接口、方法引用与构造器引用部分

lambda 表达式

Lambda 允许把函数作为一个方法的参数(函数作为参数传递到方法中)

基本语法(parameters) -> expression(parameters) ->{ statements; },由 参数域,"->",实现方法 三部分组成。

注意事项

  1. 当参数为空时,参数域由 ()表示即可,多个参数时,参数之间用逗号","分隔;
  2. 参数不要求指定变量类型,编译器会根据代码上下文推断自动鉴别;
  3. 当实现方法只有一条语句时,{}可省略,当方法无返回值时,return 关键字可省略;

使用条件
lambda 表达式主要用来实现行内执行的函数式接口;
函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口,并且接口需要用_@FunctionalInterface_ 注解修饰,例如:

@FunctionalInterface
interface GreetingService 
{
    void sayMessage(String message);
}

在Java8之前,一般用匿名内部类的方式来实现接口内的抽象方法,Java8可以使用lambda表达式来实现,以精简代码;


核心函数式接口

由于lambda表达式是来实现函数式接口的,所以使用之前需要先定义对应的函数式接口,大量使用会导致代码文件琐碎繁复,因此Java8针对常见的使用的场景,已经内置了大部分函数式接口,只有少部分需要我们自己单独定义;

Java内置了四大核心函数式接口

函数式接口 类型参数 返回类型 用途
Consumer
消费型接口
T void 对类型为T的对象应用操作,
包含方法:void accept(T t);
Supplier
供给型接口
T 返回类型为T的对象,
包含方法:T get();
Funtional<T,R>
函数型接口
T R 对类型为T的对象应用操作,并返回结果是R类型的对象,
包含方法:R apply(T,t);
Predicate
断言型接口
T boolean 确定类型为T的对象是否满足某种约束,并返回boolean值,
包含方法:boolean test(T,t);

其他接口

函数式接口 参数类型 返回类型 用途
BiFunction<T, U, R> T, U R 对类型为 T, U 参数应用操作,返回 R 类型的结果。
包含方法为R apply(T t, U u);
UnaryOperator
(Function子接口)
T T 对类型为T的对象进行一元运算,并返回T类型的结果。
包含方法为T apply(T t);
BinaryOperator
(BiFunction 子接口)
T, T T 对类型为T的对象进行二元运算,并返回T类型的结果。
包含方法为: T apply(T t1, T t2);
BiConsumer<T, U> T, U void 对 类 型 为 T, U 参数 应 用操作。
包含方法为void accept(T t, U u)
ToIntFunction
ToLongFunction
ToDoubleFunction
T int
long
double
分 别 计 算 int 、 long 、double、值的函数
IntFunction
LongFunction
DoubleFunction
int
long
double
R 参 数 分 别 为 int 、 long 、double 类型的函数

结合lambda表达式和内置函数式接口的代码示例

public void checkSalary(List<Employee> employees, Predicate<Employee> p){
    for(Employee employee:employees){
      if (p.test(employee)) {
        System.out.println(employee.getName());
      }
    }
  }
  @Test
  public void testLambda(){
    List<Employee> employeeList = Arrays.asList(
            new Employee("张三",2500,34),
            new Employee("李四",4500,45),
            new Employee("lisi",3500,35),
            new Employee("zhangsan",3000,30));
    // 筛选出所有薪水在3000元以上的员工姓名
    checkSalary(employeeList,(e)->e.getSalary()>3000);
  }

方法引用与构造器引用

方法引用

当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!(实现抽象方法的参数列表,必须与方法引用方法的参数列表保持一致!)方法引用:使用操作符 “::” 将方法名和对象或类的名字分隔开来。
如下三种主要使用情况 :

  • 对象::实例方法
  • 类::静态方法
  • 类::实例方法
//例如
(x) -> System.out.println(x);
//等同于
System.out::println
//例如
BinaryOperator<Double> bo = (x,y) -> Math.pow(x,y);
//等同于
BinaryOperator<Double> bo = Math::pow;
//例如
compare((x,y) -> x.equals(y), "abcdef","abcdef");
//等同于
compare(String::equals,"abc","abc");

注意:当需要引用方法的第一个参数是调用对象,并且第二个参数是需要引用方法的第二个参数(或无参数)时:ClassName::methodName

构造器引用

格式:ClassName::new

与函数式接口相结合,自动与函数式接口中方法兼容。可以把构造器引用赋值给定义的方法,与构造器参数列表要与接口中抽象方法的参数列表一致

数组引用

格式: type[] :: new

// 例如:
Function<Integer,Integer[]> fun = (n) -> new Integer[n];
// 等同于:
Function<Integer,Integer[]> fun = Integer[]::new;





原文链接:https://www.cnblogs.com/geekHao/p/12441460.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:关于Socket服务器与客户端双向通信时碰到的一个坑

下一篇:JVM—GC垃圾回收器总结