<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 常用的函數式接口 ## 回顧 &nbsp;&nbsp;函數接口的概念在之前的文章《Lambda表達式》中就有提到,函數接口配合Lambda表達式的使用在一些情況下可以大大簡化java代碼的書寫。函數接口指的就是接口中只有一個抽象方法, 并且接口使用@FunctionalInterface注解進行修飾。JDK中幫我們定義好了一些常用的函數接口,這些函數接口配合Lambda和后面要講的stream流進行一些**過濾數據**的操作,用起來非常簡潔。常用在“作為參數傳遞給一個方法”的場景中。下面就來講常用到的函數接口有哪些。 &nbsp;&nbsp; ## Supplier接口 &nbsp;&nbsp;(supplier 供應商)是一個"工廠"類型接口,用來"生產"對應的數據類型,不用傳入任何數據。具體使用在后面的stream流中可以體現。 ~~~ @FunctionalInterface public interface Supplier<T> { /** * Gets a result. * * @return a result */ T get(); } ~~~ ### 抽象方法 > T get():用來獲取一個泛型參數類型指定的數據,即用來提供一個符合要求的數據類型,"生產"一個數據,就跟"供應商"一樣。 舉例:獲取一個數組中的最大值 ```java public class SupplierDemo { public static int getMaxValue(Supplier<Integer> supplier) { //接口作為參數進行傳遞 return supplier.get(); } public static void main(String[] args) { int[] nums = {2, 9, 19, 1, 20}; int max = getMaxValue(()->{ //使用Lambad表達式 int max = nums[0]; for (int i = 1; i < nums.length; i++) { max = nums[i] > max ? nums[i] : max; } return max; }); } } ``` &nbsp;&nbsp;get()方法的目的就是給我們提供一個想要的數據類型。 &nbsp;&nbsp; ## Consumer接口 Consumer接口具有和Supplier接口相反的功能,主要是為了消費一個數據。 ~~~ @FunctionalInterface public interface Consumer<T> { /** * Performs this operation on the given argument. * * @param t the input argument */ void accept(T t); default Consumer<T> andThen(Consumer<? super T> after) { Objects.requireNonNull(after); return (T t) -> { accept(t); after.accept(t); }; } } ~~~ ### 抽象方法 > void accept(T):對給定的參數執行該方法的內容。 舉例:將傳遞的字符串數據進行逆轉 ```java public class ConsumerDemo { public static void reserveString(String str, Consumer<String> con) { con.accept(str); } public static void main(String[] args) { String str = "lambda"; reserveString(str, (str)->{ System.out.println(str); //lambda StringBuffer reStr = new StringBuffer(str); reStr.reverse().toString(); //將字符串進行逆轉 System.out.println(reStr); //adbmal }); } } ``` ### 默認方法 與Supplier接口不同的是,Consumer接口中實現了一個默認的方法,addThen() ```java /** * 默認方法 * 1. 返回一個組合的Consumer對象,并且會按照順序執行accept方法:即可以拼接多個進行執行 * 2. 如果after方法執行出現異常(或接下去拼接的出現異常了)就會將該異常轉發給調用者(例如main)。 * 3. 如果執行this操作出現異常時,不會執行after的操作。 */ default Consumer<T> andThen(Consumer<? super T> after) { Objects.requireNonNull(after); //判斷是否為空指針 return (T t) -> { accept(t); after.accept(t); }; //這也是一個Consumer接口accept的lambad實現 } ``` 舉例:將一個字符串轉化為大小寫 ```java public class ConsumerDemo { public static void method(String str, Consumer<String> con1, Consumer<String> con2) { con1.andThen(con2).accept(str); } public static void main(String[] args) { String str = "Lambda"; method(str, (t)->{ System.out.println(t.toUpperCase()); //LAMBDA }, (t) -> { System.out.println(t.toLowerCase()); //lambda }); } } ``` 可以使用默認方法實現一個責任鏈模式。 &nbsp;&nbsp; ## Predicate接口 (Predicate 謂詞,離散數學中的概念),傳入一個參數,對參數進行邏輯判斷,看參數是否符合條件(在給定的參數上評估這個謂詞),返回值為boolean。 ```java @FunctionalInterface public interface Predicate<T> { } ``` ### 抽象接口 > boolean test(T t):判斷傳入的參數是否符合條件 舉例:傳入一個字符串列表,打印長度大于4的字符串 ```java public class PredicateDemo { public static void checkString(String[] strs, Predicate<String> pre) { for (int i = 0; i < strs.length; i++) { if (pre.test(strs[i])) { System.out.println(strs[i]); } } } public static void main(String[] args) { String[] strs = {"java", "c", "C++", "python", "javascript", "Typescript"}; checkString(strs, (str)->{ return str.length() > 4; }); //python, javascript,Typescript } } ``` ### 默認方法 &nbsp;&nbsp;既然是用來進行邏輯判斷的,少不了要用到邏輯運算符,Predicate接口里面就內置了一些默認的邏輯運算方法: ```java /** * 1.返回一個通過邏輯與組合的Predicate接口 * 2.other.test拋出異常的話將該異常轉發給調用者 * 3.this.test拋出異常的話不執行other.test的內容 */ default Predicate<T> and(Predicate<? super T> other) { Objects.requireNonNull(other); return (t) -> test(t) && other.test(t); } //邏輯非 default Predicate<T> negate() { return (t) -> !test(t); } //邏輯或 default Predicate<T> or(Predicate<? super T> other) { Objects.requireNonNull(other); return (t) -> test(t) || other.test(t); } ``` 舉例:判斷字符串包含a并且長度大于5 ```java public class PredicateDemo { public static boolean checkString(String str, Predicate<String> pre1, Predicate<String> pre2) { return pre1.and(pre2).test(str); } public static void main(String[] args) { String str = "lambda"; boolean b = checkString(str, (str1)->{ return str1.length() > 5; }, (str1) -> { return str1.contains("a"); }); System.out.println(b); // true } } ``` &nbsp;&nbsp; ## Function接口 ```java @FunctionalInterface public interface Function<T, R> {} ``` &nbsp;&nbsp;該接口用來將類型T轉化為類型R,T稱為前置條件,R稱為后置條件 &nbsp;&nbsp; ### 抽象方法 > R apply(T t):將給定參數類型T轉化為R類型 例如,將String類型數字轉化為Integer類型 ```java public class FunctionDemo { private static void transform(Function<String, Integer> function) { int num = function.apply("10"); //數字10 System.out.println(num + 20); } public static void main(String[] args) { transform(s ‐> Integer.parseInt(s)); } } ``` ### 默認方法 &nbsp;&nbsp;與Consumer類似的,Function也有一個addThen方法,該方法也是返回一個組合操作后的Function接口,最終轉化的數據類型與after轉化的數據類型一致。 ```java default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) { Objects.requireNonNull(after); //判斷是否為空指針 return (T t) -> after.apply(apply(t)); //這也是一個Consumer接口apply的lambad實現 } ``` 舉例:將字符串數字轉化為Integer類型后+10再轉化為字符串 ```java public class FunctionDemo{ public static void addTen(String str, Function<String, Integer> fun1, Function<Integer, String> fun2) { //注意最后返回的與fun2的類型相同 String s = fun1.andThen(fun2).apply(str); System.out.println(s); //"20" } public static void main(String[] args) { String s = "10"; addTen(s, (String str1) ->{ return Integer.parseInt(str1) + 10; }, (Integer integer) -> { return integer.toString(); }); } } ``` &nbsp;&nbsp; ## 小結 1. 通過函數式接口,我們可以看到lambda表達式的簡潔之處。 2. 雖然現階段我們可能會覺得這么進行操作多此一舉,但是這些接口在后面的stream流就有很大的用處。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看