完全瞭解lambda及函數式接口

1、lambda是什麼

  • 函數式編程?匿名內部類?簡潔?
  • 來源於學術界λ,主要是行爲參數化、簡化內部類,在函數式接口中應用普遍。

2、爲何要學習lambda?

  • 不要問我爲何,廠長是我表哥。
  • 本文讓你完全學會使用lambda,無論在哪裏你都能()->{} 一把嗦。

3、lambda語法

  • 一個完整的lambda表達式
(Type1 param1,Type2 param2,Type3 params)->{

	statement1;
	statement2;
	....
	return data;
}
複製代碼

一、()->{},lambda參數、箭頭、lambda主體缺一不可java

二、參數類型能夠省略,並且基本都是省略編程

三、lambda主體中若是隻有一條語句能夠省略大括號、return及結尾分號app

四、方法引用能夠做爲lambda表達式dom

無參lambda

  • 比匿名內部類更先進,接口名稱、函數名都省略了。
  • lambda體只有一行,{}能夠省略。

有參lambda

  • 不少時候idea都能優化,可是可是。。。提交的代碼庫中依然一堆idea提示灰色。

4、 函數式接口

  • 可以使用lambda的依據是函數式接口,即內部只有一個抽象方法的接口,並不是只有一個方法。
  • lambda表達式的類型推斷也是跟函數式接口有關,編譯器能根據上下文信息推斷出參數類型。

幾個典型的函數式接口

一、BiFunction

@FunctionalInterface
public interface BiFunction<T, U, R> {
    R apply(T t, U u);

    default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t, U u) -> after.apply(apply(t, u));
    }
}
複製代碼

一、這個函數式接口在java 8 stream中大量使用。ide

二、有2個方法,只有1個抽象方法函數式編程

三、抽象方法apply接受2個參數,類型是T,U,返回值是R。函數

四、下面的get()第三個參數的BiFunction函數式接口,所以你在調用get()能夠傳遞一個符合該函數式接口規範的lambda。至於參數一、參數2怎麼操做、運算、加密。。。依賴於你的lambda主體。學習

二、Consumer

  • 消費函數,返回值爲void。
@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); };
    }
}

複製代碼
  • 返回值void,故通常使用其反作用。

三、Predicate

  • 斷言/條件測試,定義一個抽象方法,一定有1個入參,返回值boolean。
  • 最經常使用在stream中的filter(),能夠組成predicate調用鏈。
//如下均可以作一個Predicate的lambda
1、(s)->s.length()>0;
2、(v)->v > 100;
3、(o)->o.startWith("a");

複製代碼

四、Supplier

  • 不須要輸入,產出T。像是一個容器,調用get返回對象。
Supplier<Integer> supplier = new Supplier<Integer>() {
            @Override
            public Integer get() {
                //返回一個隨機值
                return new Random().nextInt();
            }
        };
System.out.println(supplier.get());
System.out.println(supplier.get());
複製代碼

方法引用

  • 簡單來說就是讓你能夠重複使用現有的方法定義,並像lambda同樣傳遞他們,使用::來表示。主要有三類。
  • 核心點:函數簽名要符合,即傳參類型、參數數量、返回值類型仍是void。

一、靜態方法的方法引用

  • 靜態方法做用於對象上。
public static void main(String[] args) {
    List<String> list = Lists.newArrayList("1","2","3","4");

    List<Integer> collect1 = list.stream().map(v -> Integer.parseInt(v))
        .collect(Collectors.toList());
    List<Integer> collect2 = list.stream().map(Integer::parseInt)
        .collect(Collectors.toList());
    
  }
複製代碼

二、指向 任意類型實例方法 的方法引用

一、這個任意類型通常指的是你的lambda的入參類型。測試

二、以下面的入參是v,調用v.length能夠寫做v的類型String::length。優化

public static void main(String[] args) {

    List<String> list = Lists
        .newArrayList("hello", "how", "are", "you", "i", "am", "fine", "thank", "you", "and",
            "you");
    Set<Integer> collect = list.stream().map(v -> v.length()).collect(Collectors.toSet());

    Set<Integer> collect1 = list.stream().map(String::length).collect(Collectors.toSet());
    System.out.println(collect);
    System.out.println(collect1);
  }
複製代碼

三、指向既有對象的方法的方法引用

  • 與上述第2點相似,不詳細說明。

5、小結

  • 主要介紹了lambda表達式及函數式接口
  • 使用函數式接口的核心就是搞對函數簽名,傳入一個符合條件簽名的lambda,就能夠()->{}一把唆了。
相關文章
相關標籤/搜索