一、函數式接口
理解FunctionalInterface(函數式接口)是學習Java8 Lambda表達式的基礎。
函數式接口的定義
- 函數式接口是指在接口中只有一個抽象方法,可以使用 @FunctionalInterface註解來約束,有多個抽象方式就會報錯(但若抽象方法爲Object類中的方法,並不會報錯)
- 函數式接口只能有一個抽象方法,所以在使用lambda表達式時,編譯器可以根據上下文直接找到接口中的方法。
函數式接口的用處
- Java8中在java.util.function包下爲我們提供了很多的函數式接口,如下圖所示:
- 提供的函數式接口中最主要的有四個,其他函數式接口都是根據這四個進行擴展的,以方便我們的開發。
四個函數式接口
我只講述下接口的抽象方法,至於默認方法和靜態方法大家可以自行了解。
- 1、Consumer接口
接受一個T類型參數,但並不返回值
@FunctionalInterface
public interface Consumer<T> {
/**
* 接受一個T類型的參數,但並不返回值
* @param t 接收一個參數
*/
void accept(T t);
}
- 2、Function接口
接收一個T類型參數,返回一個R類型結果
@FunctionalInterface
public interface Function<T, R> {
/**
* @param t 接收一個參數
* @return 返回一個結果
*/
R apply(T t);
}
- 3、Supplier接口
不接收參數,返回一個結果
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
- 4、Predicate接口
接收T類型參數並返回boolean
@FunctionalInterface
public interface Predicate<T> {
/**
* @param 接受一個T類型參數
* @return 返回一個boolean值
*/
boolean test(T t);
}
Lambda表達式
- Java中Lambda表達式又被成爲“閉包”或“匿名方法”,其格式:(param1、param2) ‐>{函數體};
使用Lambda來演示Consumer接口
public class TestConsumer {
public static void main(String[] args) {
// 創建一個List集合,集合元素爲Integer
List<Integer> list = Arrays.asList(1,2,3,4,5);
System.out.println("-----------");
// (i)就是Consumer中所傳遞的參數,而{System.out.println(i);}則是通過lambda創建的實例對象
list.forEach((i) -> {System.out.println(i);});
System.out.println("-----------");
List<String> list2 = Arrays.asList("hello","lambda","hello lambda");
list2.forEach((i) -> {System.out.println(i);});
}
}
控制檯輸出結果如下:
-----------
1
2
3
4
5
-----------
hello
lambda
hello lambda
使用Lambda來演示Function接口
public class TestFunction {
public static void main(String[] args) {
// 創建一個TestFunction對象
TestFunction test = new TestFunction();
// (value) -> value * value 這部分就是通過lambda式創建出來的Function實例
// 作用就是將傳進來的value進行平方,然後返回出去,這正好符合Function的定義,傳入一個參數,返回一個結果
System.out.println("----------------");
System.out.println(test.calculate((value) -> value * value,3));
System.out.println("----------------");
System.out.println(test.calculate((value) -> value * value,4));
}
/**
* @Description: calculate用於計算一個函數值
* @param function 傳入一個Function函數作爲參數
* @param value 傳入一個Integer參數用來計算的
* @return
*/
public int calculate(Function<Integer, Integer> function,Integer value){
return function.apply(value);
}
}
控制檯輸出:
----------------
9
----------------
16
使用Lambda來演Supplier接口
public class TestSupplier {
public static void main(String[] args) {
TestSupplier test = new TestSupplier();
// () -> Arrays.asList(1,2,3,5) 此處就是Supplier的一個實現
// 不傳值獲取一個List集合,Supplier常用於工廠模式中
List<Integer> result = test.getIntegerList(() -> Arrays.asList(1,2,3,5));
System.out.println("---------------------");
//遍歷集合 (value) -> System.out.println(value) 此處相當於一個Consumer集合
result.forEach((value) -> System.out.println(value));
System.out.println("---------------------");
// 函數式接口實例還可以通過方法引用的方式來創建,這裏就不再進行詳解,我會在下篇文章進行介紹。
result.forEach(System.out::println);
}
/**
*
* @Description: 返回一個List
* @param supplier 傳入一個supplier函數
* @return
*/
public List<Integer> getIntegerList(Supplier<List<Integer>> supplier){
return supplier.get();
}
}
控制檯輸出:
---------------------
1
2
3
5
---------------------
1
2
3
5
使用Lambda來演示Predicate接口
public class TestPredicate {
public static void main(String[] args) {
TestPredicate test = new TestPredicate();
// (value) -> value > 5 這部分其實就是lambda表達式生成的Predicate實例
// 作用:判斷穿進去參數是否大於5,時則返回true,否則爲false
System.out.println("---------------");
System.out.println(test.testMethod((value) -> value > 5 ,5));
}
public boolean testMethod(Predicate<Integer> predicate,Integer value){
return predicate.test(value);
}
}
控制檯輸出爲:
---------------
false