1. 程式人生 > >java8之lambda表達式看這一篇就夠了

java8之lambda表達式看這一篇就夠了

重要 遍歷 equal jdk 之一 con res sts ()

 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流的處理。

  

java8之lambda表達式看這一篇就夠了