学习Java8系列-Lambda (2)

学习到匿名类以后,小王感觉到Java的浩瀚,然后继续学习,后来接触到Lambda,于是对待做了以下改造:

 List<Student> list = filterStudent(students, student -> student.getAge() > 15);
Lambda知识整理 Lambda定义

从上面的演进过程,我们基本上可以得到Lambda表达式是一种匿名函数,简单地说,它是没有声明的方法,也即没有访问修饰符、返回值声明和名字。Java中的Lambda表达式通常使用(argument) -> (body)语法书写,常用的Lamda表达式例子有:

(int a, int b) -> {  return a + b; }

() -> System.out.println("Hello World");

(String s) -> { System.out.println(s); }
函数式接口

函数式接口指的是是只包含一个抽象方法声明的接口。例如java.lang.Runnable就是一种函数式接口,在 Runnable接口中只声明了一个抽象方法方法void run();

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

对于注解@FunctionalInterface对于lamda表达式来说的话并不是必要的,@FunctionalInterface是Java8新加入的一种接口,用于指明该接口类型声明是根据Java语言规范定义的函数式接口。Java8还声明了一些Lambda表达式可以使用的函数式接口,当你注释的接口不是有效的函数式接口时,可以使用@FunctionalInterface解决编译层面的错误。

常用函数式

Java8中在java.util.function中引入了很多的函数式接口,这里介绍一下3个常用的函数式接口,

Predicate
Predicate接口定义一个名叫test的抽象方法,它接收泛型T对象,并返回一个boolean类型。经常使用到的地方是在流处理的过程中filter方法,满足条件的数据才会被过滤出来,例如我们上面的例子也可以改造成为Predicate函数式接口的形式。

@FunctionalInterface
public interface Predicate<T{
   boolean test(T t);
}
public static List<Student> filterStudent(List<Student> students,
                                          Predicate<Student> predicate) {
   List<Student> list = Lists.newArrayList();
   for (Student student : students) {
   if (predicate.test(student)) {
     list.add(student);
   }
  }
  return list;
}

Consumer
Consumer定义一个名叫accept的抽象方法,他接受泛型T的对象,没有返回值。如果你需要访问泛型对象T,并其进行修改,就使用Consumer。经常使用的地方就是常用的forEach方法。

@FunctionalInterface
public interface Consumer<T{
  void accept(T t);
}
void forEachOrdered(Consumer<? super T> action);

Function
Function定义一个叫apply的方法,他接受一个泛型对象T,返回一个泛型对象R。如果你需要定义一个Lambda表达式,将输入的对象映射到输出,就使用Function,经常使用到的地方就是常用的map方法。

@FunctionalInterface
public interface Function<TR{
  apply(T t);
}
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
Lambda原理窥探

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwxfjx.html