三、函式式介面
阿新 • • 發佈:2020-11-18
自定義函式式介面
- Lambda表示式需要函式式介面的支援
- 函式式介面定義:介面中只有一個抽象方法的介面,稱為函式式介面。
- 可以使用註解 @FuncitonalInterface 修飾,其修飾作用為:限定該介面必須為函式式介面,即該介面中有且只有一個抽象方法。否則無法通過編譯。即可以檢查是否為函式式介面。
實現
/** * 自定義函式介面 * @param <T> * @param <R> */ @FunctionalInterface public interface Operation<T,R> { R operation(T t1, T t2); }
/**
* 具體實現方法
* @param l1
* @param l2
* @param operation
*/
public void op (Long l1, Long l2, Operation<Long,Long> operation){
System.out.println(operation.operation(l1,l2));
}
測試
/** * 寫具體實現方法再直接使用 */ @Test public void testOperation1(){ GoodsService goodsService = new GoodsService(); goodsService.op(10l,10l,(x,y) -> x*y); goodsService.op(100l,200l,(x,y)-> x+y); } /** * 先使用lambda表示具體實現方法體,再進行介面中的方法呼叫,傳入具體值 */ @Test public void testOperation2(){ Operation<Integer,Integer> op = (x,y) -> x*y; System.out.println(op.operation(10,10)); }
實際使用時,大多數情況下直接使用Java8內建四大函式式介面,並不要進行自己寫函式式介面。
Java內建的四大核心函式式介面
- Consumer
消費型介面 消費物件 - void accept(T t);
- Supplier
供給型介面 生成物件 - T get();
- Function<R,T> 函式型介面 指定特定功能
- R apply(T t);
- Predicate
斷言型介面 進行條件判斷 - boolean test(T t);
案例
/** * Consumer<T> 消費型介面 * void accept(T t); * * @param n * @param con */ public void consume(Integer n , Consumer<Integer> con){ con.accept(n); } /** * Supplier<T> 供給型介面 * T get();小括號無引數 * * 呼叫此方法時,第二個引數提供一個數字集合 * @param n * @param sup * @return */ public List<Integer> getNumList(int n, Supplier<Integer> sup){ List<Integer> numList = new ArrayList<>(); for (int i = 0; i < n; i++){ numList.add(sup.get()); //通過get方法得到數字 存到numList } return numList; } /** * Function<R,T> 函式型介面 指定特定功能 * 定義一個處理字串功能型介面函式 * @param str * @param fun * @return */ public String strHandler(String str, Function<String,String> fun){ return fun.apply(str); } /** * Predicate<T> 條件判斷 * boolean test(T t); 返回boolean * 使用斷言型介面過濾字串 * @param strs * @param pred * @return */ public List<String> strFilter(List<String> strs, Predicate<String> pred){ List<String> list = new ArrayList<>(); for (String s:strs ) { //利用斷言型介面進行指定功能判斷 即一個功能性條件判斷 if(pred.test(s)){ //過濾功能 list.add(s); } } return list; }
測試
@Test
public void testConsumer(){
FunctionInterface functionInterface = new FunctionInterface();
//此時的(d) 小括號裡有引數
//原因是因為 Consumer介面有引數
functionInterface.consume(1000,(d)-> System.out.println(d));
}
@Test
public void testSupplier(){
FunctionInterface functionInterface = new FunctionInterface();
//T get(); 小括號無引數
List<Integer> numList = functionInterface.getNumList(10,() -> (int)(Math.random()*101));
for ( Integer i: numList
) {
System.out.println(i);
}
}
@Test
public void testFunction(){
FunctionInterface functionInterface = new FunctionInterface();
//將字串轉成大寫
String str1 = functionInterface.strHandler("ghslkajh", (s) -> s.toUpperCase());
System.out.println(str1);
}
@Test
public void testPredicate(){
FunctionInterface functionInterface = new FunctionInterface();
//返回長度大於3的字串
List<String> s1 = functionInterface.strFilter(Arrays.asList("huzhiqi", "adaad", "1231", "414441", "gagsgasg"), (s) -> s.length() > 3);
System.out.println(s1); //[huzhiqi, adaad, 1231, 414441, gagsgasg]
//返回包含d的字串
List<String> s2 = functionInterface.strFilter(Arrays.asList("huzhiqi", "adaad", "1231", "414441", "gagsgasg"), (s) -> s.contains("d"));
System.out.println(s2); // [adaad]
}