約束:抽象方法有且只有一個,即不能有多個抽象方法,在接口中覆寫Object類中的public方法(如equals),不算是函數式接口的方法。html
被@FunctionalInterface註解該接口,沒有該註解的接口知足約束也行。java
在Java8中,知足下面任意一個條件的接口都是函數式接口: 編程
/** * 自定義一個函數式編程接口 * 函數式編程只有一個抽象方法,因此默認的是實現的是這個抽象方法 * @param <T> * @param <R> */ @FunctionalInterface public interface CalcFunctionInterface<T, R> { /** * 計算t1和t2 * * @param t1 * @param t2 * @return */ R calc(T t1, T t2); }
傳入不一樣calc函數實現的對象,進行調用函數式編程
至關於之前建立CalcFunctionInterface的匿名類,重寫了calc方法(因爲只有一個抽象方法,因此默認就是calc方法)函數
/** * 至關於一個類實現了CalcFunction接口中的惟一一個函數calc * 而後在利用多態,調用calc函數,傳入兩個參數,進行計算 */ @Test public void add(){ CalcFunctionInterface<Integer, Integer> add = (t1, t2) -> t1+t2; Integer calc = add.calc(2, 3); System.out.println(calc); // 5 }
傳入一個匿名類對象,進行方法調用calcpost
@Test public void multiply(){ // 至關於經過匿名類的形式傳入一個實現了CalcFunctionInterface接口的子類對象,重寫了該接口的方法 Integer calc = FunctionalInterfacesTest.calc(2, 3, (t1, t2) -> t1 * t2); System.out.println(calc); // 6 } /** * 接受了一個對象,利用對象的calc方法計算 */ public static Integer calc(Integer i1, Integer i2, CalcFunctionInterface<Integer, Integer> calc){ return calc.calc(i1,i2); }
一個Convert接口spa
@FunctionalInterface public interface Convert<F, T> { T convert(F from); }
lambda表達式的形式重寫該函數式編程的惟一接口code
@Test public void testLambda(){ Convert<String, Integer> stringIntegerConvert = (from -> Integer.valueOf(from)); Integer convert = stringIntegerConvert.convert("123"); System.out.println(convert); // 123 }
下面使用"::"運算符更精簡htm
靜態方法對象
@Test public void testStaticMethod(){ Convert<String, Instant> stringInstantConvert = Instant::parse; Instant convert = stringInstantConvert.convert("2019-04-25T16:09:03.852Z"); System.out.println(convert); // 2019-04-25T16:09:03.852Z }
實例方法
/** * 實例對象的方法 */ @Test public void testObjectMethod(){ Something something = new Something(); Convert<String, String> startsWith = something::startsWith; String convert = startsWith.convert("123"); System.out.println(convert); // 1 }
class Something { public String startsWith(String s) { return String.valueOf(s.charAt(0)); } }
對象的構造方法
/** * 調用對象的構造方法 */ @Test public void testConstructor(){ PersonFactory<Person> personFactory = Person::new; Person person = personFactory.create("Chris", "Paul"); System.out.println(person); // Person(firstName=Chris, lastName=Paul) }
/** * Person 工廠 */ @FunctionalInterface public interface PersonFactory<P extends Person> { P create(String firstName, String lastName); }
@NoArgsConstructor @AllArgsConstructor @Getter @Setter @ToString class Person { private String firstName; private String lastName; }
https://juejin.im/post/5c7d1254e51d45720f72264c