1.1函數式接口概述
函數式接口:有且僅有一個抽象方法的接口
Java中的函數式編程體現就是Lambda表達式,因此函數式接口就是能夠適用於Lambda使用的接口
只有確保接口中有且僅有一個抽象方法, Java中的L ambda才能順利地進行推導
html
如何檢測一個接口是否是函數式接口呢?
@Functionallnterface放在接口定義的上方:java
若是接口是函數式接口,編譯經過;若是不是,編譯失敗編程
注意
●咱們本身定義 函數式接口的時候,@Functionallnterface是可選的, 就算我不寫這個註解,只要保證知足函數式接口定
義的條件,也照樣是函數式接口。可是,建議加上該註解數組
1.2函數式接口做爲方法的參數
需求
● 定義一個類(RunnableDemo),在類中提供兩個方法
一個方法是: startThread(Runnable r)方法參數Runnable是一 個函數式接口
一個方法是主方法,在主方法中調用startThread方法
若是方法的參數是一個函數式接口, 咱們可使用 ambda表達式做爲參數傳遞
●startThread(0 -> System.out.println(Thread.currentThread0.getName0 + "線程啓動了));app
package com.Test01; /* 定義一個類(RunnableDemo),在類中提供兩個方法 一個方法是: startThread(Runnable r) 方法參數Runnable是一 個函數式接口 一個方法是主方法,在主方法中調用startThread方法 */ public class RunnableDemo { public static void main(String[] args) { //在主方法中調用startThread方法 //採用匿名內部類的方式 startThread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + "線程啓動了"); } });
startThread (() -> System.out.println(Thread.currentThread().getName() + "線程啓動了"));
} private static void startThread(Runnable r) { // Thread t = new Thread(r); // t.start(); new Thread(r).start(); } }
1.3函數式接口做爲方法的返回值
需求●定義一個類(ComparatorDemo), 在類中提供兩個方法
一個方法是: Comparator <String> getComparator()方法返回值C omparator是一個函數式接口
一個方法是主方法,在主方法中調用getComparator方法ide
若是方法的返回值是一個函數式接口,咱們可使用L ambda表達式做爲結果返回
●private static Comparator <String> getComparator({
return (s1, s2) -> s1.length( - s2.length0;
}
函數式編程
package com.Test01; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; public class CommparatorDemo { public static void main(String[] args) { //構造使用場景 //定義集合 存儲字符串元素 ArrayList<String> array = new ArrayList<String>(); array.add("cccc"); array.add("aaa"); array.add("dd"); array.add("b"); System.out.println("排序前:" + array); Collections.sort(array, getComparator()); System.out.println("排序後:" + array); } public static Comparator<String> getComparator() { //返回該接口的實現類對象 //首先採用匿名內部類的方式 // Comparator<String> comp = new Comparator<String>() { // @Override // public int compare(String s1, String s2) { // return s1.length()-s2.length(); // } // }; // return comp; // return new Comparator<String>() { //// @Override //// public int compare(String s1, String s2) { //// return s1.length() - s2.length(); //// } //// }; // return (String s1,String s2) ->{ // return s1.length()-s2.length(); // }; return (s1, s2) -> s1.length() - s2.length(); } }
經常使用的4個函數式接口函數
Java 8在java.util.function包下預約義了大量的函數式接口供咱們使用
咱們重點來學習下面的4個接口
●Supplier接口
●Consumer接口
●Predicate接口、
●Function接口
學習
1,Supplier接口spa
@FunctionalInterface
public interface Supplier<T>
package com.Test01; /* Supplier<T>:包含一個無參的方法 T get ():得到結果 該方法不須要參數,它會按照某種實現邏輯(由Lambda表達式實現)返回一個數據 Supplier<T>接口也被稱爲生產型接口,若是咱們指定了接口的泛型是什麼類型,那麼接口中的get方法就會生產什麼類型的數據供使用 */ import java.util.function.Supplier; public class SupplierDemo { public static void main(String[] args) { // String s = getString(() -> { // return "林青霞"; // }); String s = getString(() -> "林青霞"); System.out.println(s); } private static String getString(Supplier<String> sup) { return sup.get(); } }
package com.Test01; import java.util.function.Supplier; public class SupplierTest { public static void main(String[] args) { //定義一個數組 int[] arr = {15, 20, 3, 65, 45, 6}; int x = getMax(() -> { int Max = arr[0]; for (int i = 0; i < arr.length; i++) { if (Max < arr[i]) { Max = arr[i]; } } return Max; }); System.out.println(x); } private static int getMax(Supplier<Integer> sup) { return sup.get(); } }
,2,Consumer接口
@FunctionalInterface
public interface Consumer<T>
1.6 Consumer接口
Consumer<T>:包含兩個方法
void accept(T t): 對給定的參數執行此操做
default Consumer <T> andThen(Consumer after):返回一個組合的Consumer,依次執行此操做,而後執行after操做
●Consumer<T>接口也被稱爲消費型接口,它消費的數據的數據類型由泛型指定
package com.Test01; /* Consumer<T>:包含兩個方法 void accept (T t): 對給定的參數執行此操做 default Consumer<T> andThen (Consumer after): 返回一個組合的Consumer, 依次執行此操做,而後執行after操做 Consumer<T>接口也被稱爲消費型接口,它消費的數據的數據類型由泛型指定 / */ import java.util.function.Consumer; public class ConsumerDemo { public static void main(String[] args) { // Lamada表達式 // OperatorString("林青霞",(s) -> { // System.out.println(s); // }); // OperatorString("林青霞", (s) -> System.out.println(s)); //方法引用 OperatorString("林青霞", System.out::println); } //定義一個方法,消費一個字符串數據 private static void OperatorString(String name, Consumer<String> con) { con.accept(name); } }
Consumer練習
String[] strArray = {"林青霞, 30",」張曼玉,35", 」王祖賢, 33"};
字符串數組中有多條信息,請按照格式: "姓名: Xx,年齡: xX"的格式將信息打印出來
要求:
把打印姓名的動做做爲第- -個Consumer接口的L ambdo實例
把打印年齡的動做做爲第二個Consumer接口的L ambda實例
將兩個Consumer接口按照順序組合到一塊兒使用
package com.Test01; /**/ import java.util.function.Consumer; public class ConsumerDemo02 { public static void main(String[] args) { String[] strArray = {"林青霞,30", "張曼玉,35", "王祖賢,33"}; printString(strArray, (String str) -> { String name = str.split(",")[0]; System.out.print("姓名:" + name); }, (String str) -> { int age = Integer.parseInt(str.split(",")[1]); System.out.println(",年齡:" + age); }); } private static void printString(String[] strArray, Consumer<String> con1, Consumer<String> con2) { for (String s : strArray) { con1.andThen(con2).accept(s); } } }
3, Predicate接口
@FunctionalInterface
public interface Predicate<T>
Predicate<T>:經常使用的四個方法
●boolean test(T t):對給定的參數進行判斷(判斷邏輯由L ambda表達式實現),返回一個布爾值
●default Predicate<T> negate():返回-一個邏輯的否認,對應邏輯非
●default Predicate<T> and(Predicate other):返回一個組合判斷,對應短路與
●default Predicate<T> or(Predicate other):返回一個組合判斷,對應短路或
----------- - -- - - - - - - - - -- - - - - - - - - - - - - -- - - -- - - - - - --
●Predicate<T>接口一般用於判斷參數是否知足指定的條件
●boolean test(T t):對給定的參數進行判斷(判斷邏輯由L ambda表達式實現),返回一個布爾值
●default Predicate<T> negate():返回-一個邏輯的否認,對應邏輯非
以下演示
package com.Test01; /* Predicate<T>:經常使用的四個方法 boolean test (T t):對給定的參數進行判斷(判斷邏輯由Lambda表達式實現),返回一個布爾值 default Predicate<T> negate (): 返回一個邏輯的否認,對應邏輯非 Predicate<T>接口一般用於判斷參數是否知足指定的條件 */ import java.util.function.Predicate; public class PredicateDemo01 { public static void main(String[] args) { // boolean b = checkString("hello", (String s) -> { // return s.length() > 8; // }); boolean b = checkString("hello", s -> s.length() > 8); System.out.println(b); } //判斷給定的字符串是否知足要求 private static boolean checkString(String s, Predicate<String> pre) { // return pre.test(s); // return !pre.test(s);//不是標準非 return pre.negate().test(s);//接口提供的邏輯非的操做 } }
●default Predicate<T> and(Predicate other):返回一個組合判斷,對應短路與
●default Predicate<T> or(Predicate other):返回一個組合判斷,對應短路或
以下演示
package com.Test01; /* /* Predicate<T>: default Predicate<T> and (Predicate other): 返回一個組合判斷,對應短路與 default Predicate<T> or (Predicate other): 返回-一個組合判斷,對應短路或 */ import java.util.function.Predicate; public class PredicateDemo02 { public static void main(String[] args) { boolean b1 = checkString("hello", s -> s.length() > 8); //System.out.println(b1); boolean b2 = checkString("helloworld", s -> s.length() > 8); //System.out.println(b2); boolean b3 = checkStringandor("helloworld", s -> s.length() > 11, s -> s.length() < 15); System.out.println(b3); } //同一個字符串給出兩個不一樣的判斷條件,最後把這兩個判斷的結果作邏輯與運算的結果做爲最終的結果 private static boolean checkStringandor(String s, Predicate<String> pre1, Predicate<String> pre2) { // boolean b1 = pre1.test(s); //// boolean b2 = pre2.test(s); //// boolean b = b1 || b2; //// return b; return pre1.or(pre2).test(s);//return pre1.and(pre2).test(s); } private static boolean checkString(String s, Predicate<String> pre) { //斷定給定的字符串是否知足要求 return pre.test(s); // } }
Predicate練習
String[ strArray= {"林青霞30", "柳巖,34", "張曼玉,35",「貂蟬,31", "王祖賢,33"};
●字符串數組中有多條信息, 請經過Predicate接口的拼裝將符合要求的字符串篩選到集合ArrayList中,並遍歷ArrayList集合
●同時知足以下要求:姓名長度大於2;年齡大於33
●
分析
有兩個判斷條件,因此須要使用兩個Predicate接口,對條件進行判斷
必須同時知足兩個條件,因此可使用and方法鏈接兩個判斷條件
package com.Test01; /* String[] strArray = {"林青霞,30」,「柳巖,34", "張曼玉,35", "貂蟬,31","王祖賢,33"}; 字符串數組中有多條信息,請經過Predicate接口的拼裝將符合要求的字符串篩選到集合Arraylist中,並遍歷Arraylist集合 要求:同時知足以下要求 1:姓名長度大於2 2:年齡大於33 分析: 1:有兩個判斷條件,因此須要使用兩個Predicate接口,對條件進行判斷 2:必須同時知足兩個條件,因此可使用and方法鏈接兩個判斷條件 */ import java.util.ArrayList; import java.util.function.Predicate; public class PredicateTest { public static void main(String[] args) { String[] strArray = {"林青霞,30", "柳巖,34", "張曼玉,35", "貂蟬,31", "王祖賢,33"}; ArrayList<String> stringArrayList = myfilter(strArray, s -> s.split(",")[0].length() > 2, s -> Integer.parseInt(s.split(",")[1]) > 33); for (String s : stringArrayList) { System.out.println(s); } } // 請經過Predicate接口的拼裝將符合要求的字符串篩選到集合ArrayList中, private static ArrayList<String> myfilter(String[] arr, Predicate<String> pre1, Predicate<String> pre2) { //定義一個集合 ArrayList<String> array = new ArrayList<String>(); for (String s : arr) { String name = s.split(",")[0]; int age = Integer.parseInt(s.split(",")[1]); if (pre1.and(pre2).test(s)) { array.add(s); } } return array; } }
4, Function接口
@FunctionalInterface
public interface Function<T,R>
Function<T,R>:經常使用的兩個方法
R apply(Tt):將此函數應用於給定的參數
default <V> Function andThen(Function after):返回-個組合函數,首先將該函數應用於輸入,而後將after函數應用於結果
Function<T,R>接口一般用於對參數進行處理,轉換(處理邏輯由Lambda表達式實現),而後返回一個新的值
package com.Test01; /* Function<T,R>:經常使用的兩個方法 R apply (T t):將此函數應用於給定的參數 default <V> Function andThen (Function after): 返回一個組合函數,首先將該函數應用於輸入,而後將ofter函數應用於結果 Function<T, R>接口一般用於對參數進行處理,轉換(處理邏輯由L ambda表達式實現),而後返回一一個新的值 */ import java.util.function.Function; public class FunctionDemo { public static void main(String[] args) { // Convert("100", (String s) -> { // return Integer.parseInt(s); // }); Convert("100", s -> Integer.parseInt(s)); Convert("100", Integer::parseInt); Convert(100, i-> String.valueOf(i+566)); Convert("300",s->Integer.parseInt(s),i->String.valueOf(i+300)); } //定義一個方法,把一個字符串轉換int類型,在控制檯輸出 private static void Convert(String s, Function<String, Integer> fun) { // Integer i = fun.apply(s); int i = fun.apply(s); System.out.println(i); } //定義一個方法,把一個int類型的數據加上一個整數以後,轉爲字符串在控制檯輸出 private static void Convert(int i, Function<Integer, String> fun) { String s = fun.apply(i); System.out.println(s); } //定義一個方法,把一個字符串轉換int類型,把int類型的數據加上一一個整數以後, // 轉爲字符串在控制檯輸出 private static void Convert(String s,Function<String,Integer> fun1,Function<Integer,String> fun2) { // Integer i = fun1.apply(s); // String s1 = fun2.apply(i); // System.out.println(s1); String s1 = fun1.andThen(fun2).apply(s); System.out.println(s1); } }
練習
package com.Test01; /* ●Strings = "林青霞30"; ●請按照我指定的要求進行操做: 1:將字符串截取獲得數字年齡部分string 2:將上一步的年齡字符串轉換成爲int類型的數據int 3:將上一步的int數據加70,獲得個int結果,在控制檯輸出 ●請經過Function接口來實現函數拼接 */ import java.util.function.Function; public class FunctionDemo02 { public static void main(String[] args) { Convert("林青霞30",s-> Integer.parseInt(s.substring(3,5))+70); //也能夠按照題目的要求一步一步來 } private static void Convert(String s, Function<String, Integer> fun) { Integer i = fun.apply(s); System.out.println(i); } }