lambda和java並發,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

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-19 18:58
下一篇 2024-11-19 18:58

相關推薦

  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Bean加載過程

    Java Bean加載過程涉及到類加載器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean加載的過程。 一、類加載器 類加載器是Java虛擬機…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字符串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字符串中是否存在多個指定字符: 一、字符串遍歷 字符串是Java編程中非常重要的一種數據類型。要判斷字符串中是否存在多個指定字符…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29
  • Java任務下發回滾系統的設計與實現

    本文將介紹一個Java任務下發回滾系統的設計與實現。該系統可以用於執行複雜的任務,包括可回滾的任務,及時恢復任務失敗前的狀態。系統使用Java語言進行開發,可以支持多種類型的任務。…

    編程 2025-04-29
  • Java 8 Group By 會影響排序嗎?

    是的,Java 8中的Group By會對排序產生影響。本文將從多個方面探討Group By對排序的影響。 一、Group By的概述 Group By是SQL中的一種常見操作,它…

    編程 2025-04-29

發表回復

登錄後才能評論