变量不合法的表达式JAVA_Java8中lambda表达式的语法,别人都会的,你还不会吗?「一」...
函數式編程
函數式編程是一種編程方式,它將電腦運算視為函數的計算。函數編程語言最重要的基礎是λ演算(lambda calculus),λ演算的函數可以接受函數當作輸入(參數)和輸出(返回值)。 函數式編程是"結構化編程"的一種,主要思想是把運算過程盡量寫成一系列嵌套的函數調用。
lambda表達式
JSR-335首次定義了在Java中使用lambda表達式的基本規范,當前的實現就是針對JSR-335規范的。 lambda表達式是一種緊湊的、傳遞行為的方式。Lambda表達式本質上是為了解決方便的將代碼作為數據傳遞的難題。從本質上講lambda表達式就是一種將行為參數化的操作。
在JDK8之前,需要利用匿名內部類來實現的傳遞行為的操作,現在可以用lambda表達式來實現了。 從編碼的角度講,lambda表達式是一個代碼塊,以及必須傳入代碼的變量規范。
由于規范基本一致,所以Java中的lambda表達式和JavaScript中的在使用上幾乎完全一樣。所差別的只是胖箭頭和瘦箭頭而已。當然由于語言特性的問題,兩種lambda表達式的實際差距還是很大的,這種差距表現在:在Java中,lambda表達式本身是有類型的。也就是說要傳遞的行為必須是有類型的,這種類型就是函數接口。
除了傳參之外,lambda表達式也可以出現在賦值符號的右邊。
lambda表達式的語法: lambda表達式由參數、箭頭、表達式組成。
(parameters) -> expression //此處行為為表達式,這里隱含了return語句。
或者
(parameters) -> { statements; } //此處行為為語句,需要返回時要手寫return語句。
1,如果代碼無法在一個表達式中完成,可以像寫方法一樣把代碼放在大括號中。只有一行代碼的Lambda表達式也可以使用大括號。
()->{
...
}
2,沒有參數時,也要提供一個空的小括號。如果只有一個參數,而且這個參數的類型可以推導,也可以省略小括號。Lambda表達式也可以包含多個參數
(param)->expression
param->expression
3,大部分情況中,無需指定lambda表達式的返回類型。具體的返回類型可以由上下文推斷得出。
這種類型推導實際上是Java7中的目標類型推斷的擴展。在Java7中以下代碼是合法的,這是泛型的又一個升級。
Map map=new HashMap<>(); //不用聲明HashMap的中的鍵值對類型,系統可以通過Map的相關類型推斷出來。
這就是所謂的類型推斷。
4,lambda表達式中只在某些分支返回值,另一個些分支不返回值是不合法的。
5,與JavaScript相同,lambda表達式只有一個入參時,可以省略小括號。
example:
BinaryOperator add=(x,y)->x+y; //創建一個函數,用來計算x和y相加的結果。
注意:add不是兩個數字的和,而是將兩個數字加相的那行代碼。
System.out.println(add.apply(1l,2l)); //打印3
解析:binaryOperator是一個接口,其含義進行一次兩數據的某種操作,并返回這個操作的結果。其抽象方法來自父接口BiFunction。BiFunction接口是不同數據類型的操作、而binaryOperator接口是針對相同類型數據的操作。
public interface BiFunction {
R apply(T t, U u);
}
public interface BinaryOperator extends BiFunction{}
需要注意的是: Lambda表達式中引用的在表達式之外定義的局部變量必須是final或既成事實上的final變量。 這個約束性的規定來源于java 8之前的匿名內部類,java 8放寬了這個規定,既局部變量可以不加final關鍵字,但依然不能給該變量多次賦值。
函數接口
函數接口是只有一個抽象方法的接口,用作Lambda表達式的類型。也就是說所謂的Lambda表達式對應的其實就是函數接口。 java8提供@FunctionalInterface注解函數接口,當然這個注解是非必須的,只要接口符合函數接口的標準(即只包含一個抽象方法的接口)即可。 函數式接口的抽象方法簽名基本上就是Lambda表達式的簽名,這種抽象方法叫作函數描述符。 幾個重要的函數式接口,它們都位于java.util.function包中:
Predicate接口
@FunctionalInterface
public interface Predicate{
boolean test(T t);
}
Consumer接口
@FunctionalInterface
public interface Consumer{
void accept(T t);
}
BiConsumer接口
@FunctionalInterface
public interface BiConsumer {
void accept(T t, U u);
}
Function接口
@FunctionalInterfac
public interface Function{
R apply(T t);
}
為避免在使用原始類型時進行自動拆、裝箱操作,jdk8提供了以上函數式接口的原始類型版本。
IntPredicate、DoublePredicate等
Supplier接口
@FunctionalInterface
public interface Supplier {
T get();
}
BinaryOperator接口
BinaryOprator接口繼承自BiFunction接口,其接口方法源型如下:
R apply(T t, U u);
方法引用
方法引用是lambda表達式的一種簡化寫法。當要調用的方法是一個已經存在的方法時可以使用方法引用。使用方法引用替換整個Lambda表達式。 語法為:左邊是容器(可以是類名,實例名),中間是"::",右邊是相應的方法名(不帶小括號)。
ObjectReference::methodName
一般方法的引用格式:
調用靜態方法,ClassName::methodName。如 Person::compareByAge調用實例方法,Instance::methodName。如System.out::println;調用參數的實例方法,ClassName::methodName。Object::equals;調用構造方法,ClassName::new 。如:Person::new;注意:
當匿名方法有參數并且lambda表達式就是調用參數中的方法的時候,可以直接用參數的類名做為容器。如下:
List collected=Stream.of("a","b","hello")
.map(string->string.toUpperCase)
.collect(Collectors.toList());
//注意這里使用了方法引用
List collected=Stream.of("a","b","hello")
.map(String::toUpperCase)
.collect(Collectors.toList());
本質上講:方法引用是Lambda表達式的快捷寫法。當這個Lambda表達式代表的只是直接調用某個已經存在的方法時使用。
可以把方法引用當作針對僅涉及單一方法的Lambda的語法糖。
forExample:
public class LambdaExample {
public static void main(String[] args) {
List names = Arrays.asList("peter", "anna", "mike", "xenia");
/*匿名內部類的方式
Collections.sort(names, new Comparator() {
@Override
public int compare(String a, String b) {
return b.compareTo(a);
}
});
*/
/*lambda表達式
Collections.sort(names, (a,b) -> {
return b.compareTo(a);
});
*/
//簡易寫法
Collections.sort(names, (a, b) -> b.compareTo(a));
//進一步簡寫
Collections.sort(names,String::compareTo);
for(String s:names){
System.out.println(s);
}
}
}
public class ThreadExample {
public static void main(String[] args) {
Thread thread=new Thread(()->{
for(int i=0;i<10;i++){
System.out.println(i);
}
});
thread.start();
}
}
每一個lambda表達式都對應一個類型,通常是接口類型。而“函數式接口”是指僅僅只包含一個抽象方法的接口,每一個該類型的lambda表達式都會被匹配到這個抽象方法。因為默認方法不算抽象方法,所以你也可以給你的函數式接口添加默認方法。 我們可以將lambda表達式當作任意只包含一個抽象方法的接口類型,確保你的接口一定達到這個要求,你只需要給你的接口添加 @FunctionalInterface 注解,編譯器如果發現你標注了這個注解的接口有多于一個抽象方法的時候會報錯的。
@FunctionalInterface
interface Converter {
T convert(F from);
}
Converter converter = (from) -> Integer.valueOf(from);
Integer converted = converter.convert("123");
System.out.println(converted); // 123
下一篇lambda2講解具體的API語法,以及應用場景。
Java8中lambda表達式的語法,別人都會的,你還不會嗎?「二」
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的变量不合法的表达式JAVA_Java8中lambda表达式的语法,别人都会的,你还不会吗?「一」...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 虚拟机安装rsync服务器配置,虚拟机安
- 下一篇: python查看内存地址的内容_pyth