zoukankan      html  css  js  c++  java
  • java8之lambda表达式看这一篇就够了

     java8增加了许多新特性,其中lambda表达式可以说为最重要的特性之一,本文将从如下几个方面来学习lambda:

        1、lambda表达式的基本定义

      2、lambda表达式的语法

      3、lambda表达式基本示例

    一、何为lambda表达式?

      简单点说lambda为一种匿名函数,它既没有名字也没有声明的方法、访问修饰符和返回值等。它允许将函数作为方法的参数进行传递。

    二、基本语法:lambda通常包含如下几种书写方式

      () -> expression  

      () -> {  statement  }

      () -> { statements }

      (arg1,arg2) -> { statement }

      (Type arge1,Type arge2) -> { statement }

     三、jdk内置的函数式接口以及基本示例介绍

      jdk内置了如下四大函数式接口,在java.util.function包下可以找到:

      1、Function  接收一个参数类型 T , 返回类型 R ,适用于包装、修改等操作

    @FunctionalInterface
    public interface Function<T, R> {
    
        R apply(T t);
    
        default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
            Objects.requireNonNull(before);
            return (V v) -> apply(before.apply(v));
        }
    
        default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
            Objects.requireNonNull(after);
            return (T t) -> after.apply(apply(t));
        }
    
        static <T> Function<T, T> identity() {
            return t -> t;
        }
    }

      下面的代码演示了如何获取一个学生的所有名字:

     public static void main(String[] args) {
            Student student1 = new Student("a",11);
            Student student2 = new Student("b",12);
            Student student3 = new Student("c",21);
            Student student4 = new Student("d",1);
            List<Student> students = new ArrayList <>();
            students.add(student1);
            students.add(student2);
            students.add(student3);
            students.add(student4);
            List < String > names = filterStudent(students , student -> student.getName());
            names.forEach((name)-> System.out.println(name));
        //输出结果:a b c d
        }
    
        public static <T,R> List<R> filterStudent(List<T> list, Function<T,R > function){
            List<R> names = new ArrayList <>();
             for (T t : list) {
                 names.add(function.apply(t));
            }
            return names;
        }

      2、Consumer 接收一个参数 类型T ,无返回值 ,适用于遍历等操作

    @FunctionalInterface
    public interface Consumer<T> {
    
        void accept(T t);
    
        default Consumer<T> andThen(Consumer<? super T> after) {
            Objects.requireNonNull(after);
            return (T t) -> { accept(t); after.accept(t); };
        }
    }

      适用于遍历,最典型的 foreach 示例:

     1         List<String> list = new ArrayList <>();
     2         list.add("a");
     3         list.add("b");
     4         list.add("c");
     5         list.add("d");
     6         list.forEach((str)->System.out.println(str));
     7         //直接调用类的方法进行输出
     8         list.forEach(System.out::println);
     9 
    10         list.forEach((str)->{
    11             //若为一个对象,可以进行其余的保存、更新等操作
    12             System.out.println(str);
    13         });
    

      

      3、Predicate 接受一个参数T ,返回boolean,适用于判断过滤等操作

     1 @FunctionalInterface
     2 public interface Predicate<T> {
     3 
     4     boolean test(T t);
     5 
     6     default Predicate<T> and(Predicate<? super T> other) {
     7         Objects.requireNonNull(other);
     8         return (t) -> test(t) && other.test(t);
     9     }
    10 
    11    
    12     default Predicate<T> or(Predicate<? super T> other) {
    13         Objects.requireNonNull(other);
    14         return (t) -> test(t) || other.test(t);
    15     }
    16 
    17    
    18     static <T> Predicate<T> isEqual(Object targetRef) {
    19         return (null == targetRef)
    20                 ? Objects::isNull
    21                 : object -> targetRef.equals(object);
    22     }
    23 }

    下面的代码演示了 Predicate 接口的基本用法:

     1  public static void main(String[] args) {
     2         Student student1 = new Student("a",11);
     3         Student student2 = new Student("b",12);
     4         Student student3 = new Student("c",21);
     5         Student student4 = new Student("d",1);
     6         List<Student> students = new ArrayList <>();
     7         students.add(student1);
     8         students.add(student2);
     9         students.add(student3);
    10         students.add(student4);
    11         List < Student > students1 = testStudent(students , student -> student.getAge() > 11);
    12         students1.forEach(student -> System.out.println(student.getName()));
    13      //输出结果:b c
    14     }
    15 
    16     public static <T> List<T> testStudent(List<T> list , Predicate<T> function){
    17         List<T> newList = new ArrayList <>();
    18         for (T t : list) {
    19             if(function.test(t)){
    20                 newList.add(t);
    21             }
    22         }
    23         return newList;
    24     }

    4、Supplier 无参数,返回一个结果

    1 @FunctionalInterface
    2 public interface Supplier<T> {
    3 
    4     T get();
    5 
    6 }

      从上面的四个函数式接口中我们可以总结出如下几点:

      1、函数式接口一般都有 @FunctionalInterface 注解标识,但是此注解并非强制需要,如果不标注的话编译器将无法识别只能拥有一个未实现的方法

      2、函数式接口之接受唯一的 public 方法 ,但是允许有 default 方法 、静态方法以及 父类Object的方法(如果声明第二个public方法会直接报错,大家可以试一下)。

       函数式接口的使用一般会配合 java中Stream Api进行使用,下篇文章将会讲解java中Stream流的处理。

      

  • 相关阅读:
    常见浏览器兼容性问题与解决方案(转)
    jQuery.noConflict() 方法—— jquery库与其他库冲突的问题解决
    Image Map的制作
    SQL存储过程(Stored Procedure)
    WEB前端底层知识浏览器是如何工作的(转)
    PHP面试题(English)
    MVC分页
    C#中的接口
    关于类关系图的使用小技巧
    用virtual避免c++中继承时出现的二义性
  • 原文地址:https://www.cnblogs.com/dhjmjava/p/10367557.html
Copyright © 2011-2022 走看看