Java8自定義函數式編程接口和便捷的引用類的構造器及方法


什么是函數編程接口?

約束:抽象方法有且只有一個,即不能有多個抽象方法,在接口中覆寫Object類中的public方法(如equals),不算是函數式接口的方法。

被@FunctionalInterface注解該接口,沒有該注解的接口滿足約束也行。

 

在Java8中,滿足下面任意一個條件的接口都是函數式接口: 

  • 被@FunctionalInterface注釋的接口,滿足函數式接口的約束。
  • 沒有被@FunctionalInterface注釋的接口,但是滿足函數式接口的約束。
  •  @函數式的約束:  
    • 接口有且只能有個一個抽象方法,只有方法定義,沒有方法體。
    • 在接口中覆寫Object類中的public方法,不算是函數式接口的方法。
    • 在接口中的default方法,不算是函數式接口的方法。
    • 在接口中的static方法,不算是函數式接口的方法。

 

 

自定義一個函數式編程接口

/**
 * 自定義一個函數式編程接口
 * 函數式編程只有一個抽象方法,所以默認的是實現的是這個抽象方法
 * @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
    }

 

傳入一個匿名類對象,進行方法調用calc

@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接口

@FunctionalInterface
public interface Convert<F, T> {
    T convert(F from);
}

 

lambda表達式的形式重寫該函數式編程的唯一接口

@Test
    public void testLambda(){
        Convert<String, Integer> stringIntegerConvert = (from -> Integer.valueOf(from));
        Integer convert = stringIntegerConvert.convert("123");
        System.out.println(convert);
        // 123
    }

 

下面使用"::"運算符更精簡

 

靜態方法

@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;
}

 

Java8的內置函數式編程接口

https://juejin.im/post/5c7d1254e51d45720f72264c

https://www.cnblogs.com/theRhyme/p/10774341.html

https://mp.weixin.qq.com/s?__biz=MzIzMzgxOTQ5NA==&mid=2247483845&idx=1&sn=08990fd78e4f62ddf38238660cc4dd64&chksm=e8fe9dccdf8914da580e13a9fc5fee64c135f55d11f3c2de5731f052fa9f1a39060ed6375110&scene=21#wechat_redirect

https://www.exception.site/java8/java8-new-features


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM