- lambda表達(dá)式含義
- 函數(shù)式接口
- 1.什么是函數(shù)式接口
- 2.自定義函數(shù)
- 3.作為參數(shù)傳遞Lambda表達(dá)式
- 4.四大內(nèi)置核心函數(shù)式接口
- 方法引用與構(gòu)造器引用
- 方法引用
- 構(gòu)造器引用(了解)
- 數(shù)組引用(了解)
lambda表達(dá)式含義
lambda表達(dá)式是對(duì)某些接口的簡(jiǎn)單實(shí)現(xiàn)不瓶,Lambda 規(guī)定接口中只能有一個(gè)需要被實(shí)現(xiàn)的方法刻坊,不是規(guī)定接口中只能有一個(gè)方法,這就是函數(shù)式接口藏澳。 ** lambda表達(dá)式引入“->” 左側(cè)代表參數(shù)列表统翩,右側(cè)代表需要的功能仙蚜,邏輯
<pre class="custom" data-tool="mdnice編輯器" style="margin-top: 10px; margin-bottom: 10px; box-shadow: rgba(170, 170, 170, 0.48) 0px 0px 6px 0px; max-width: 100%; border-radius: 4px; margin: 10px auto 0 auto;">Consumer<String> con = (c) -> System.out.println(c);
</pre>
函數(shù)式接口
1.什么是函數(shù)式接口
(1)、只包含一個(gè)抽象方法的接口厂汗,稱為函數(shù)式接口委粉。 (2)、你可以通過(guò)Lambda表達(dá)式來(lái)創(chuàng)建該接口的對(duì)象娶桦。(若Lambda表達(dá)式拋出一個(gè)受檢異常贾节,那么該異常需要在目標(biāo)接口的抽象方法上進(jìn)行聲明)。 (3)衷畦、我們可以在任意函數(shù)式接口上使用@FunctionalInterface注解栗涂,這樣做可以檢查它是否是一個(gè)函數(shù)式接口,同時(shí)javadoc也會(huì)包含一條聲明祈争,說(shuō)明這個(gè)接口是一個(gè)函數(shù)式接口斤程。
2.自定義函數(shù)
示例代碼一:
<pre class="custom" data-tool="mdnice編輯器" style="margin-top: 10px; margin-bottom: 10px; box-shadow: rgba(170, 170, 170, 0.48) 0px 0px 6px 0px; max-width: 100%; border-radius: 4px; margin: 10px auto 0 auto;">@FunctionalInterface public interface MyNumber{ public double getValue(); }
</pre>
示例代碼二:函數(shù)式接口中使用泛型
<pre class="custom" data-tool="mdnice編輯器" style="margin-top: 10px; margin-bottom: 10px; box-shadow: rgba(170, 170, 170, 0.48) 0px 0px 6px 0px; max-width: 100%; border-radius: 4px; margin: 10px auto 0 auto;">@FunctionalInterface public interface MyFunc<T>{ public T getValue(T t); }
</pre>
3.作為參數(shù)傳遞Lambda表達(dá)式
示例代碼:
<pre class="custom" data-tool="mdnice編輯器" style="margin-top: 10px; margin-bottom: 10px; box-shadow: rgba(170, 170, 170, 0.48) 0px 0px 6px 0px; max-width: 100%; border-radius: 4px; margin: 10px auto 0 auto;">public String strHandler(String str, MyFunction mf) { return mf.getValue(str); } 作為參數(shù)傳遞Lambda表達(dá)式: String trimStr = strHandler("\t\t 你是大傻逼 ", (str) -> str.trim()); String upperStr = strHandler("abcdefg", (str) -> str.toUpperCase()); String newStr = strHandler("我大望江威武", (str) -> str.substring(2, 5));
</pre>
作為參數(shù)傳遞Lambda表達(dá)式:為了將Lambda表達(dá)式作為參數(shù)傳遞,接收Lambda表達(dá)式的參數(shù)類型必須是與該Lambda表達(dá)式兼容的函數(shù)式接口的類型菩混。 **
4.四大內(nèi)置核心函數(shù)式接口
一忿墅、Consumer<t>:消費(fèi)型接口(void accept(T t))</t>
consumer 接口翻譯過(guò)來(lái)就是消費(fèi)者,顧名思義,該接口對(duì)應(yīng)的方法類型為接收一個(gè)參數(shù)墨吓,沒(méi)有返回值球匕,可以通俗的理解成將這個(gè)參數(shù)'消費(fèi)掉了',一般來(lái)說(shuō)使用Consumer接口往往伴隨著一些期望狀態(tài)的改變或者事件的發(fā)生,例如最典型的forEach就是使用的Consumer接口帖烘,雖然沒(méi)有任何的返回值亮曹,但是卻向控制臺(tái)輸出了語(yǔ)句。 Consumer 使用accept對(duì)參數(shù)執(zhí)行行為
<pre class="custom" data-tool="mdnice編輯器" style="margin-top: 10px; margin-bottom: 10px; box-shadow: rgba(170, 170, 170, 0.48) 0px 0px 6px 0px; max-width: 100%; border-radius: 4px; margin: 10px auto 0 auto;">`/**
* 消費(fèi)型接口Consumer<T>
*/
@Test
public void test1 () {
consumo(500, (x) -> System.out.println(x));
}
public void consumo (double money, Consumer<Double> c) {
c.accept(money);
}` </pre>
以上為消費(fèi)型接口秘症,有參數(shù)照卦,無(wú)返回值類型的接口。
二乡摹、Supplier<t>:供給型接口(T get())</t>
Supplier 接口翻譯過(guò)來(lái)就是提供者,和上面的消費(fèi)者相反役耕,該接口對(duì)應(yīng)的方法類型為不接受參數(shù),但是提供一個(gè)返回值聪廉,通俗的理解為這種接口是無(wú)私的奉獻(xiàn)者瞬痘,不僅不要參數(shù)故慈,還返回一個(gè)值,使用get()方法獲得這個(gè)返回值
<pre class="custom" data-tool="mdnice編輯器" style="margin-top: 10px; margin-bottom: 10px; box-shadow: rgba(170, 170, 170, 0.48) 0px 0px 6px 0px; max-width: 100%; border-radius: 4px; margin: 10px auto 0 auto;">`/**
* 供給型接口,Supplier<T>
*/
@Test
public void test2 () {
Random ran = new Random();
List<Integer> list = supplier(10, () -> ran.nextInt(10));
for (Integer i : list) {
System.out.println(i);
}
}
/**
* 隨機(jī)產(chǎn)生sum個(gè)數(shù)量得集合
* @param sum 集合內(nèi)元素個(gè)數(shù)
* @param sup
* @return
*/
public List<Integer> supplier(int sum, Supplier<Integer> sup){
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < sum; i++) {
list.add(sup.get());
}
return list;
}` </pre>
上面就是一個(gè)供給類型得接口框全,只有產(chǎn)出察绷,沒(méi)人輸入,就是只有返回值津辩,沒(méi)有入?yún)?/p>
三拆撼、Function<T, R>:函數(shù)型接口(R apply(T t))
function,顧名思義,函數(shù)的意思,這里的函數(shù)是指數(shù)學(xué)上的函數(shù)哦,你也可以說(shuō)是嚴(yán)格函數(shù)語(yǔ)言中的函數(shù),例如haskell里的,他接受一個(gè)參數(shù),返回一個(gè)值,永遠(yuǎn)都是這樣,是一個(gè)恒定的,狀態(tài)不可改變的方法。其實(shí)想講函數(shù)這個(gè)徹底將明白可以再開一篇博客了,所以這里不詳細(xì)的說(shuō)了喘沿。 ?? 上面說(shuō)到,函數(shù)接口是對(duì)行為的抽象,因此我方便大家理解,就用java中的方法作例子闸度。
<pre class="custom" data-tool="mdnice編輯器" style="margin-top: 10px; margin-bottom: 10px; box-shadow: rgba(170, 170, 170, 0.48) 0px 0px 6px 0px; max-width: 100%; border-radius: 4px; margin: 10px auto 0 auto;">`/**
* 函數(shù)型接口:Function<R, T>
*/
@Test
public void test3 () {
String s = strOperar(" asdf ", x -> x.substring(0, 2));
System.out.println(s);
String s1 = strOperar(" asdf ", x -> x.trim());
System.out.println(s1);
}
/**
* 字符串操作
* @param str 需要處理得字符串
* @param fun Function接口
* @return 處理之后得字符傳
*/
public String strOperar(String str, Function<String, String> fun) {
return fun.apply(str);
}` </pre>
上面就是一個(gè)函數(shù)型接口,輸入一個(gè)類型得參數(shù)蚜印,輸出一個(gè)類型得參數(shù)莺禁,當(dāng)然兩種類型可以一致。
四窄赋、Predicate<t>:斷言型接口(boolean test(T t))</t>
predicate<T,Boolean> 謂語(yǔ)接口睁宰,顧名思義,中文中的‘是’與‘不是’是中文語(yǔ)法的謂語(yǔ)寝凌,同樣的該接口對(duì)應(yīng)的方法為接收一個(gè)參數(shù),返回一個(gè)Boolean類型值孝赫,多用于判斷與過(guò)濾较木,當(dāng)然你可以把他理解成特殊的Funcation<T,R>,但是為了便于區(qū)分語(yǔ)義青柄,還是單獨(dú)的劃了一個(gè)接口伐债,使用test()方法執(zhí)行這段行為
<pre class="custom" data-tool="mdnice編輯器" style="margin-top: 10px; margin-bottom: 10px; box-shadow: rgba(170, 170, 170, 0.48) 0px 0px 6px 0px; max-width: 100%; border-radius: 4px; margin: 10px auto 0 auto;">`/**
* 斷言型接口:Predicate<T>
*/
@Test
public void test4 () {
List<Integer> l = new ArrayList<>();
l.add(102);
l.add(172);
l.add(13);
l.add(82);
l.add(109);
List<Integer> list = filterInt(l, x -> (x > 100));
for (Integer integer : list) {
System.out.println(integer);
}
}
/**
* 過(guò)濾集合
* @param list
* @param pre
* @return
*/
public List<Integer> filterInt(List<Integer> list, Predicate<Integer> pre){
List<Integer> l = new ArrayList<>();
for (Integer integer : list) {
if (pre.test(integer))
l.add(integer);
}
return l;
}` </pre>
上面就是一個(gè)斷言型接口,輸入一個(gè)參數(shù)致开,輸出一個(gè)boolean類型得返回值峰锁。
總結(jié)
四大函數(shù)接口和他們引申出的各類接口,終點(diǎn)是對(duì)不同種類行為的封裝導(dǎo)致了設(shè)計(jì)出不同的函數(shù)接口双戳,另外在使用函數(shù)接口或者lambda表達(dá)式的時(shí)候虹蒋,要注意lambda對(duì)值封閉這個(gè)特性。
方法引用與構(gòu)造器引用
方法引用
當(dāng)要傳遞給Lambda體的操作飒货,已經(jīng)有實(shí)現(xiàn)的方法魄衅,就可以使用方法引用! 實(shí)現(xiàn)抽象方法的參數(shù)列表塘辅,必須與方法引用方法的參數(shù)列表保持一致 方法引用使用操作符“::”將方法名和對(duì)象或者類的名字分隔開來(lái)晃虫。 三種使用情況: 對(duì)象::實(shí)例方法 類::靜態(tài)方法 類::實(shí)例方法
例如
BinaryOperator bo=(x,y)->Math.pow(x,y)
等同于:
BinaryOperator<Double> bo=Math::pow;
<pre class="custom" data-tool="mdnice編輯器" style="margin-top: 10px; margin-bottom: 10px; box-shadow: rgba(170, 170, 170, 0.48) 0px 0px 6px 0px; max-width: 100%; border-radius: 4px; margin: 10px auto 0 auto;">/* * 類::靜態(tài)方法 * Comparator的Compare(T t1,T t2) * Integer的Compare(T t1,T t2) * */ Comparator<Integer> com1 = (t1,t2) -> Integer.compare(t1,t2); System.out.println(com1.compare(21,20)); System.out.println("------------"); Comparator<Integer> com2 = Integer::compare; System.out.println(com2.compare(12,14));
</pre>
構(gòu)造器引用(了解)
格式:ClassName::new 與函數(shù)式接口相結(jié)合,自動(dòng)與函數(shù)式接口中方法兼容扣墩。 可以把構(gòu)造器引用賦值給定義的方法哲银,與構(gòu)造器參數(shù)列表要與接口中抽象方法的參數(shù)列表一直 例如:
Function<Integer,MyClass> fun=(n)->new MyClass(n);
等同于:
Function<Integer,MyClass> fun=MyClass::new;
數(shù)組引用(了解)
格式:type[]::new 例如:
Function<Integer,Integer[]> fun=(n)->new Integer[n];
等同于:
Function<Integer,Integer[]> fun=Integer[]::new;
歡迎關(guān)注公眾號(hào)【ggball blog】!
- END -