本文目錄一覽:
- 1、java lambda表達式是什麼?
- 2、java的lambda表達式應用在哪些場合
- 3、Java的for循環、增強for循環、lambda表達式中的forEach 三種方式優缺點比較?
- 4、java lambda有什麼用
- 5、如何強迫自己使用java8新特性
- 6、Java匿名類可以用Lambda寫,但是如果需要實現多個方法怎麼寫呢?
java lambda表達式是什麼?
lambda表達式是JAVA8中提供的一種新的特性,它支持JAVA也能進行簡單的“函數式編程”。它是一個匿名函數,Lambda表達式基於數學中的λ演算得名,直接對應於其中的lambda抽象(lambda abstraction),是一個匿名函數,即沒有函數名的函數。
函數式接口:
這個是理解Lambda表達式的重點,也是產生lambda表達式的“母體”,這裡我們引用一個比較容易理解的說法:函數式接口是 一個只有一個抽象方法(不包含object中的方法)的接口。
這個需要說明一點,就是在Java中任何一個對象都來自Object 所有接口中自然會繼承自Object中的方法,但在判斷是否是函數式接口的時候要排除Object中的方法。
java的lambda表達式應用在哪些場合
例1、用lambda表達式實現Runnable
我開始使用Java 8時,首先做的就是使用lambda表達式替換匿名類,而實現Runnable接口是匿名類的最好示例。看一下Java 8之前的runnable實現方法,需要4行代碼,而使用lambda表達式只需要一行代碼。我們在這裡做了什麼呢?那就是用() – {}代碼塊替代了整個匿名類。
// Java 8之前:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(“Before Java8, too much code for too little to do”);
}
}).start();
//Java 8方式:
new Thread( () – System.out.println(“In Java8, Lambda expression rocks !!”) ).start();
輸出:
too much code, for too little to do
Lambda expression rocks !!
這個例子向我們展示了Java 8 lambda表達式的語法。你可以使用lambda寫出如下代碼:
(params) – expression
(params) – statement
(params) – { statements }
例如,如果你的方法不對參數進行修改、重寫,只是在控制台打印點東西的話,那麼可以這樣寫:
() – System.out.println(“Hello Lambda Expressions”);
如果你的方法接收兩個參數,那麼可以寫成如下這樣:
(int even, int odd) – even + odd
順便提一句,通常都會把lambda表達式內部變量的名字起得短一些。這樣能使代碼更簡短,放在同一行。所以,在上述代碼中,變量名選用a、b或者x、y會比even、odd要好。
例2、使用Java 8 lambda表達式進行事件處理
如果你用過Swing API編程,你就會記得怎樣寫事件監聽代碼。這又是一個舊版本簡單匿名類的經典用例,但現在可以不這樣了。你可以用lambda表達式寫出更好的事件監聽代碼,如下所示:
// Java 8之前:
JButton show = new JButton(“Show”);
show.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(“Event handling without lambda expression is boring”);
}
});
// Java 8方式:
show.addActionListener((e) – {
System.out.println(“Light, Camera, Action !! Lambda expressions Rocks”);
});
Java開發者經常使用匿名類的另一個地方是為 Collections.sort() 定製 Comparator。在Java 8中,你可以用更可讀的lambda表達式換掉醜陋的匿名類。我把這個留做練習,應該不難,可以按照我在使用lambda表達式實現 Runnable 和 ActionListener 的過程中的套路來做。
例3、使用lambda表達式對列表進行迭代
Java的for循環、增強for循環、lambda表達式中的forEach 三種方式優缺點比較?
個人理解不喜勿噴。
簡單的來說其實三種並沒有什麼太大的區別,一般情況下的性能也差不多。
for循環:
優點:可以直接獲取下標,能更精確的定位。下標變量屬於循環內變量,循環結束會自動回收。下標變量的步長可以自定,比較靈活。
缺點:需要根據下標才會獲取循環內容。只能循環有序集合和數組,如Set和Map就無法遍歷。
增強for:
優點:循環直接進行賦值,直接得到循環對象,不需要通過下標獲取。可以遍歷所有集合類型和數組。
缺點:循環有序集合時無法定位下標,需要在循環外層定義下標。無法遍歷Map類型。
lambda:
優點:可以對所有集合類型和Map進行循環,特別是支持對Map進行循環,循環也是直接進行賦值,直接得到循環對象。
缺點:循環有序集合時無法定位下標,無法遍曆數組,因為理論上來說他是屬於迭代器的一種。同時因為循環體屬於一個封閉範圍的線程,在循環體內使用部分循環體外的變量需要加final關鍵字,很不方便。
另外說到了迭代器,可以參考lambda,不過寫法就沒lmbda那麼方便了,不過迭代器有很多功能是循環比不上的,可以去看看。
java lambda有什麼用
lambda,匿名表達式,舉個例子來說
以前寫代碼
xx.doSomething(new CallBack(){
public void do(){
// do something
}
});
使用lambda的寫法:
xx.doSomething(() – {// do something});
Java中的lambda,主要是為了支持函數式編程,只有在Java 8中才引入了lambda
如何強迫自己使用java8新特性
一、Lambda表達式
Lambda表達式可以說是Java 8最大的賣點,她將函數式編程引入了Java。Lambda允許把函數作為一個方法的參數,或者把代碼看成數據。
一個Lambda表達式可以由用逗號分隔的參數列表、–符號與函數體三部分表示。例如:
Arrays.asList( “p”, “k”, “u”,”f”, “o”, “r”,”k”).forEach( e – System.out.println( e ) );
1 Arrays.asList( “p”, “k”, “u”,”f”, “o”, “r”,”k”).forEach( e – System.out.println( e ) );
為了使現有函數更好的支持Lambda表達式,Java
8引入了函數式接口的概念。函數式接口就是只有一個方法的普通接口。java.lang.Runnable與java.util.concurrent.Callable是函數式接口最典型的例子。為此,Java
8增加了一種特殊的註解@FunctionalInterface:
1 @FunctionalInterface
2 public interface Functional {
3 void method();
4 }
二、接口的默認方法與靜態方法
我們可以在接口中定義默認方法,使用default關鍵字,並提供默認的實現。所有實現這個接口的類都會接受默認方法的實現,除非子類提供的自己的實現。例如:
1 public interface DefaultFunctionInterface {
2 default String defaultFunction() {
3 return “default function”;
4 }
5 }
我們還可以在接口中定義靜態方法,使用static關鍵字,也可以提供實現。例如:
1 public interface StaticFunctionInterface {
2 static String staticFunction() {
3 return “static function”;
4 }
5 }
接口的默認方法和靜態方法的引入,其實可以認為引入了C++中抽象類的理念,以後我們再也不用在每個實現類中都寫重複的代碼了。
三、方法引用
通常與Lambda表達式聯合使用,可以直接引用已有Java類或對象的方法。一般有四種不同的方法引用:
構造器引用。語法是Class::new,或者更一般的Class T ::new,要求構造器方法是沒有參數;
靜態方法引用。語法是Class::static_method,要求接受一個Class類型的參數;
特定類的任意對象方法引用。它的語法是Class::method。要求方法是沒有參數的;
特定對象的方法引用,它的語法是instance::method。要求方法接受一個參數,與3不同的地方在於,3是在列表元素上分別調用方法,而4是在某個對象上調用方法,將列表元素作為參數傳入;
四、重複註解
在Java 5中使用註解有一個限制,即相同的註解在同一位置只能聲明一次。Java
8引入重複註解,這樣相同的註解在同一地方也可以聲明多次。重複註解機制本身需要用@Repeatable註解。Java
8在編譯器層做了優化,相同註解會以集合的方式保存,因此底層的原理並沒有變化。
五、擴展註解的支持
Java 8擴展了註解的上下文,幾乎可以為任何東西添加註解,包括局部變量、泛型類、父類與接口的實現,連方法的異常也能添加註解。
六、Optional
Java 8引入Optional類來防止空指針異常,Optional類最先是由Google的Guava項目引入的。Optional類實際上是個容器:它可以保存類型T的值,或者保存null。使用Optional類我們就不用顯式進行空指針檢查了。
七、Stream
Stream
API是把真正的函數式編程風格引入到Java中。其實簡單來說可以把Stream理解為MapReduce,當然Google的MapReduce的靈感也是來自函數式編程。她其實是一連串支持連續、並行聚集操作的元素。從語法上看,也很像linux的管道、或者鏈式編程,代碼寫起來簡潔明了,非常酷帥!
八、Date/Time API (JSR 310)
Java 8新的Date-Time API (JSR 310)受Joda-Time的影響,提供了新的java.time包,可以用來替代
java.util.Date和java.util.Calendar。一般會用到Clock、LocaleDate、LocalTime、LocaleDateTime、ZonedDateTime、Duration這些類,對於時間日期的改進還是非常不錯的。
九、JavaScript引擎Nashorn
Nashorn允許在JVM上開發運行JavaScript應用,允許Java與JavaScript相互調用。
十、Base64
在Java 8中,Base64編碼成為了Java類庫的標準。Base64類同時還提供了對URL、MIME友好的編碼器與解碼器。
除了這十大新特性之外,還有另外的一些新特性:
更好的類型推測機制:Java 8在類型推測方面有了很大的提高,這就使代碼更整潔,不需要太多的強制類型轉換了。
編譯器優化:Java 8將方法的參數名加入了字節碼中,這樣在運行時通過反射就能獲取到參數名,只需要在編譯時使用-parameters參數。
並行(parallel)數組:支持對數組進行並行處理,主要是parallelSort()方法,它可以在多核機器上極大提高數組排序的速度。
並發(Concurrency):在新增Stream機制與Lambda的基礎之上,加入了一些新方法來支持聚集操作。
Nashorn引擎jjs:基於Nashorn引擎的命令行工具。它接受一些JavaScript源代碼為參數,並且執行這些源代碼。
類依賴分析器jdeps:可以顯示Java類的包級別或類級別的依賴。
JVM的PermGen空間被移除:取代它的是Metaspace(JEP 122)。
Java匿名類可以用Lambda寫,但是如果需要實現多個方法怎麼寫呢?
Lambda表達式,也常常叫做閉包,是一個在很多現代程序語言中十分流行的特性。在眾多不同的原因中當中,Java平台最迫切的原因之一是lambda表達式能簡化多線程上的集合的分布式處理。列表和集是有代表性,在客戶端代碼獲取一個來自集合的迭代器,那麼使用通過元素的迭代和輪流取出並處理他們。如果在並行中處理不同元素,客戶端代碼的有責任把它組織起來。
在Java 8中,目的是替代集合提供的函數,獲取函數並使用他們以各種不同的方法處理元素(我們將使用非常簡單的函數forEach為例子,通過它獲取一個函數並適用於任何元素)優勢是轉變集合在內部迭代並組織那些元素,將來自客戶端的並行代碼轉移到庫代碼中。
可是 ,為了讓客戶端代碼在這裡取得優勢,需要一個簡單方法給集合函數提供一個函數。當前標準的方式是建立一個匿名類實現對應的接口。但定義內部匿名類的語法太笨拙了
舉個例子,在forEach函數集合上將獲取Block接口的一個實例並調用它的apply函數為任何元素。
interface Block { void apply(T t); }
假設我們想使用forEach在List中的Point元素(Java.awt.Point)上調換x和y的坐標。使用內部匿名類實現Block我們通過調換函數,像這樣:
pointList.forEach(new Block() {
public void apply(Point p) {
p.move(p.y, p.x);
}
});
可是,使用Lambda,同樣的效果可以用更簡介的形式來寫:
pointList.forEach(p – p.move(p.y, p.x));
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/159326.html