1. java8 lambda 表達式是個什麼
為了支持函數式編程,Java 8引入了Lambda表達式.
在Java 8中採用的是內部類來實現Lambda表達式.具體實現代碼,可以通過debug看, 同時通過位元組碼查看工具及反編譯工具來驗證.
自從lambda表達式成為Java語言的一部分之後,Java集合(Collections)API就面臨著大幅變化。而JSR 355(規定了Java lambda表達式的標准)的正式啟用更是使得Java集合API變的過時不堪。
盡管我們可以從頭實現一個新的集合框架(比如「Collection II」),但取代現有的集合框架是一項非常艱難的工作,因為集合介面滲透了Java生態系統的每個角落,將它們一一換成新類庫需要相當長的時間。因此,我們決定採取演化的策略(而非推倒重來)以改進集合API: 為現有的介面(例如Collection,List和Stream)增加擴展方法;
在類庫中增加新的流(stream,即java.util.stream.Stream)抽象以便進行聚集(aggregation)操作;
改造現有的類型使之可以提供流視圖(stream view);
改造現有的類型使之可以容易的使用新的編程模式,這樣用戶就不必拋棄使用以久的類庫,例如ArrayList和HashMap
(當然這並不是說集合API會常駐永存,畢竟集合API在設計之初並沒有考慮到lambda表達式。我們可能會在未來的JDK中添加一個更現代的集合類庫)。
除了上面的改進,還有一項重要工作就是提供更加易用的並行(Parallelism)庫。盡管Java平台已經對並行和並發提供了強有力的支持,然而開發者在實際工作(將串列代碼並行化)中仍然會碰到很多問題。因此,我們希望Java類庫能夠既便於編寫串列代碼也便於編寫並行代碼,因此我們把編程的重點從具體執行細節(how computation should be formed)轉移到抽象執行步驟(what computation should be perfomed)。
2. JAVA8的lambda表達式的一個問題
這個功能性/函數介面主要用做轉換的作用。Converter<String, Integer> converter = (from) -> Integer.valueOf(from);這就是lambda表達式, (from) -> Integer.valueOf(from)這個是具體的實現, 這句話的意思將輸入的字元串from,經過轉換後輸出整數。當然你可以自己實現一個轉換邏輯,比如 Converter<String, Integer> converter =
str -> customConvert(str)。
下面就是自己實現的一個轉化器。
private Integer customConvert(String str){
return 1;//這樣輸入的字元串永遠都輸出1;
}
3. java表達式是什麼
Java是面向表達式的語言,Java中一個簡單表達式可以是下面任意一種:● 常量:7、false。● 單引號括起來的字元字面常量:'A'、'3'。● 雙引號括起來的字元串字面常量:"foo"、"Java"。● 任何正確聲明的變數名:myString、x。● 任何用Java二元運算符(本章稍後將詳細討論)連接起來的兩個上述類型的表達式:x+2。● 任何用Java一元運算符(本章稍後將詳細討論)修飾的單個上述類型的表達式:i++。● 任何用小括弧括起來的上述類型的表達式:(x+2)。以及另外一些與本書後面將要學到的對象有關的表達式類型。無論多麼復雜的表達式都可以由不同類型的簡單表達式和括弧嵌套組合而成,例如:((((4/x) + y) * 7) + z)。2.9.1 算術運算符 Java語言提供了許多基本的算術運算符,如表2-1所示。表2-1 Java算術運算符運算符描 述+加法-減法*乘法/除法%求余(%左邊的操作數除以右邊的
操作數所得到的余數,例如10%3=1)+和-運算符也可作為一元運算符用於表示正負數:-3.7、+42。除了簡單賦值運算符=,還有許多特定的復合賦值運算符,這些運算符將變數賦值和算術操作合並在一起,如表2-2所示。表2-2 Java復合賦值運算符運算符描 述+=a+=b等價於a=a+b-=a-=b等價於a=a-b*=a*=b等價於a=a*b/=a/=b等價於a=a/b%=a%=b等價於a=a%b最後要介紹的兩個算術運算符是一元遞增運算符(++)和一元遞減運算符(--),用於將整數變數的值加1或減1,或者將浮點數變數的值加1.0或減1.0。稱它們為一元運算符是因為它們用於單個變數,而前面討論的二元運算符則連接兩個表達式的值。一元遞增運算符和一元遞減運算符也可用於將字元變數在Unicode序列中向前或向後移動一個字元位置。例如,在下面的代碼片段中,字元變數c的值從'e'遞增為'f':遞增和遞減運算符可以以前綴或者後綴方式使用。如果運算符放在操作數之前(前綴模式),變數的遞增或遞減操作將在更新後的變數值被用於任何由它構成的賦值操作之前執行。例如,考慮下面的使用前綴遞增運算符的代碼片段,假設a和b在程序前面已經聲明為int變數:上述代碼執行後,變數a的值是2,變數b的值也是2。這是因為在第二行中變數a的遞增(從1到2)發生在它的值賦給b之前。因此這行代碼在邏輯上等價於下面兩行代碼: 另一方面,如果運算符放在操作數之後(後綴模式),遞增或遞減操作發生在原來的變數值被用於任何由它構成的賦值操作之後。看一下以後綴方式使用遞增運算符的相同代碼片段:上述代碼執行後,變數b的值是1,而變數a的值是2。這是因為在第二行中變數a的遞增(從1到2)發生在它的值賦給b之後。因此這行代碼在邏輯上等價於下面兩行代碼:下面是一個稍微復雜一點例子,請閱讀附加的注釋以確保你能夠明白x最終是如何被賦值為10的:稍後將會看到,遞增和遞減運算符通常和循環一起使用。2.9.2 關系和邏輯運算符邏輯表達式以指定的方式比較兩個(簡單或者復雜)表達式exp1和exp2,決議出一個boolean值true或者false。 Java提供了表2-3所示的關系運算符來創建邏輯表達式。表2-3 Java關系運算符運算符描 述exp1==exp2如果exp1等於exp2,值為true(注意使用雙等號測試相等性)exp1>exp2如果exp1大於exp2,值為trueexp1>=exp2如果exp1大於等於exp2,值為trueexp1<exp2如果exp1小於exp2,值為trueexp1<=exp2如果exp1小於等於exp2,值為trueexp1!=exp2如果exp1不等於exp2,值為true!exp如果exp為false值為true,如果exp為true值為false除了關系運算符,Java還提供了用於組合/修飾邏輯表達式的邏輯運算符。表2-4列出了最常用的邏輯運算符。表2-4 Java邏輯運算符運算符描 述exp1&&exp2邏輯「與」,僅當exp1和exp2都為true時復合表達式值為trueexp1||exp2邏輯「或」,exp1或exp2值為true時復合表達式值為true!exp邏輯「非」,將邏輯表達式的值從true切換到false,反之亦然下面這個例子用邏輯「與」運算符來編程實現邏輯表達式「如果x大於2.0且y不等於4.0」:邏輯表達式常用於流程式控制制結構,本章稍後將進行討論。2.9.3 表達式求值和運算符優先順序如同本章前面提到的那樣,任何復雜的表達式都可以用分層嵌套的小括弧構成,例如(((8 * (y + z)) + y) x)。編譯器通常按照從內到外,從左到右的順序對這樣的表達式求值。假設x、y、z按照下面的方式聲明並初始化:下面的賦值語句右邊的表達式:將像下面這樣逐步求值:沒有小括弧時,根據運算符用於表達式求值的順序,某些運算符具有高於其他運算符的優先順序。例如,乘除法先於加減法執行。通過使用小括弧可以強制改變運算符的優先順序,括弧內的運算符比括弧外的先執行。考慮下面的代碼片段:代碼的第一行沒有使用括弧,乘法操作比加法操作先執行,因此整個表達式的值為2+12=14,就像我們將表達式明確地寫成2+(3*4)一樣,當然這樣做沒有必要。 在代碼的第二行,括弧被明確地放在操作2+3兩邊,因此加法操作將首先執行,然後求和結果乘以4作為整個表達式的值,即5*4=20。回到前面的例子注意到>和!=運算符優先順序高於&&運算符,因此可以去掉嵌套的括弧而變成下面這樣:然而,額外的括弧並不會對代碼造成傷害,事實上它可以使表達式的目的更加清楚。2.9.4 表達式類型表達式類型是表達式最終求值結果的Java類型。例如給定下面的代碼片段:表達式(x > 2.0) && (y != 4.0)求值結果為true,因此表達式(x > 2.0) && (y != 4.0)稱為boolean型表達式。在下面的代碼片段中:表達式((8 * (y + z)) + y) * x求值結果為42,因此表達式((8 * (y + z)) + y) * x稱為整型表達式。
4. Java 8的新特性lambda表達式是否比匿名內部類具有更好的可讀性
對於大多數剛剛接觸jdk8的同學來說,應該都會認為lambda表達式其實就是匿名內部類的語法糖(包括我自己,在剛剛接觸的時候,也是這樣認為的),但實際上二者還是存在不少差異,其中最主要的兩點就是標識性和作用域。
首先,內部類在創建表達式時,會確保創建一個擁有唯一標識的新對象,而對於lambda,其計算結果(其實就是一個映射的過程)可能有也可能沒有唯一標識,這取決於具體實現。
其次,內部類的聲明會創建出一個新的命名作用域,在這個作用域中,this與super指向內部類本身的當前實例;但是lambda恰恰相反,它不會引入任何新的命名環境,這樣就避免了內部類名稱查找的復雜性,名稱查找會導致很多問題,比如想要調用外圍實例的方法時卻錯誤的調用了內部類實例的Object方法。
5. java8 中的->和::是什麼意思呢
->是Java 8新增的Lambda表達式中,變數和臨時代碼塊的分隔符,即:
(變數) -> {代碼塊}
如果代碼塊只有一個表達式,大括弧可以省略。如果變數類型可以自動推斷出來,可以不寫變數類型。
::是類似於C++的域運算符,獲取方法使用的。
stream()也是JDK8新增的流,你的表達式中將numbers轉換為流,就可以惰性處理,這樣只有變數要用的時候才會被調用,專門處理較多的數字或者字元串(如配合readAllLines()方法使用),i -> i % 2 == 0就是自動判斷了i的類型(可能是int型,我沒法判斷),這樣就將numbers中所有的偶數過濾出來了(distinct()保證了每個數字只保留一個),然後將這些過濾出的數字每個佔用一行地列印出來。
6. Java 8為什麼需要Lambda表達式
很多編程語言早就引入了Lambda 表達式
而java語法又比較繁瑣,被很多人嫌棄.
於是java8新增了特性支持Lambda 表達式.
例如:
不用Lambda表達式寫的匿名內部類
List<String> names = Arrays.asList("jack", "tom", "jerry");
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s2.compareTo(s1);
}
});
採用Lambda表達式簡化上面的代碼
List<String> names = Arrays.asList("jack", "tom", "jerry");
Collections.sort(names, (s1, s2) -> s2.compareTo(s1));
當然了java8中Lambda表達式還有其他用法,但我比較喜歡它的簡潔
7. Java 8的Lambda表達式為什麼要基於invokedynamic
很多編程語言早就引入了Lambda表達式而java語法又比較繁瑣,被很多人嫌棄.於是java8新增了特性支持Lambda表達式.例如:不用Lambda表達式寫的匿名內部類List names = Arrays.asList("jack", "tom", "jerry");Collections.sort(names,
8. 如何在android studio中使用java8 的Lambda表達式
1、下載Java8的jdk進行安裝。
2、然後在Andstudio中打開Project Structure 設置一下JDK的路徑。
3、在項目中bulid.gradle中 將jdk版本更改為JavaVersion.VERSION_1_8
4、到這時候 已經可以在項目中書寫 Lambda語法 而不會報錯了,但是 當編譯的時候還是會報 class file for java.lang.invoke.MethodType not found #23 這個錯,
這時候只要在工程的bulid.gradle中的buildscript里去配置下:classpath 'me.tatarka:gradle-retrolambda:3.2.4' 。
5、最後在app的bulid.gradle中加上 apply plugin: 'me.tatarka.retrolambda' 就OK了。
完成以上步驟,就能在androidstudio中使用Lambda 表達式了。
9. Java8新特性lambda表達式有什麼用
一:因為lambda表達式能夠使代碼看起來更簡潔,清爽
匿名內部類的寫法
List<String>names=Arrays.asList("jack","tom","jerry");
Collections.sort(names,newComparator<String>(){
@Override
publicintcompare(Strings1,Strings2){
returns2.compareTo(s1);
}
});
lambda表達式的寫法
List<String>names=Arrays.asList("jack","tom","jerry");
Collections.sort(names,(s1,s2)->s2.compareTo(s1));
二: 很多編程語言都支持lambda表達式. java不支持都不好意思了......
三: 通過lambda 表達式 來實現函數是編程.將來聲明式編程語言借鑒函數編程思想,函數編程語言融合聲明式編程特性...這幾乎是一種必然趨勢。
10. java8新特性lambda表達式有什麼用
一:因為lambda表達式能夠使代碼看起來更簡潔,清爽
匿名內部類的寫法
List<String>names=Arrays.asList("jack","tom","jerry");
Collections.sort(names,newComparator<String>(){
@Override
publicintcompare(Strings1,Strings2){
returns2.compareTo(s1);
}
});
lambda表達式的寫法
List<String>names=Arrays.asList("jack","tom","jerry");Collections.sort(names,(s1,s2)->s2.compareTo(s1));
二: 很多編程語言都支持lambda表達式. java不支持都不好意思了......
三: 通過lambda 表達式 來實現函數是編程.將來聲明式編程語言借鑒函數編程思想,函數編程語言融合聲明式編程特性...這幾乎是一種必然趨勢。