2016-11-26 65 views
5

據我所知,有3種Java的lambda表達式。在Lambda表達式(爪哇),如何使用沒有參數的表達式?

  1. (int x, int y) -> { return x + y; }
  2. x -> x * x
  3. () -> x

第三人似乎從來沒有使用過。

可不可以給每個各3例範例(3的情況下額外的例子將是很好的)來說明它們的使用情況如何?請使它們儘可能簡單(優選與list.stream(開始)....)

+1

第三個似乎從未使用過?我只是用在這裏:http://stackoverflow.com/questions/40797960/chicken-egg-lifecycle – ajb

+0

供應商 SUP =() - > 2; – Kachna

+3

這些不是lambda表達式的不同「種類」(並且您甚至沒有詳盡地涵蓋選項)。第三個僅僅是第一個的特例,其中只有零個參數。第二種是特殊的語法形式,如果只有一個參數,並且您選擇讓編譯器推斷參數類型,則可以省略括號。你也可以選擇讓編譯器推斷所有的參數類型,在這種情況下,你會得到類似'(x,y,z) - > x + y + z'的東西。但他們都是一樣的「善良」的東西。 –

回答

4

前兩個例子是從最後一個不同。函數中的變量(lambda表達式)引用其參數。

雖然在第三個示例中,x引用了lambda表達式之外但在詞法範圍內的變量(可以是來自方法或實例變量的局部變量)。

實施例1(通常爲料流降低),通過將到目前爲止計算總和和下一個項目從列表中lambda函數計算的總和:

int sum = list.stream().reduce((int x, int y) -> x+y); 

例2中,計算從元件的平方:

squares = list.stream().map((int x) -> x*x).collect(Collectors.toList()); 

例3,設置元素爲默認值,如果它在列表中的空:

final int x = MY_DEFAULT_VALUE; 
// lambda refers the the variable above to get the default 
defaults = list.stream().map((Integer v) -> v != null ? v : x); 

或者例如3更好是在地圖原子的方法:你在哪裏得到2個參數的方法和返回值

int x = MY_DEFAULT_VALUE; 
// lambda refers the the variable above to get the default 
map.computeIfAbsent(1, (Integer key) -> x); 
// the same could be achieved by putIfAbsent() of course 
// but typically you would use (Integer key) -> expensiveComputeOfValue(x) 
// ... 
// or quite common example with executor 
public Future<Integer> computeAsync(final int value) { 
    // pass the callback which computes the result synchronously, to Executor.submit() 
    // the callback refers to parameter "value" 
    return executor.submit(() -> computeSync(value)); 
} 
5
  1. 第一個表達式將被使用。

  2. 第二個表達式將用於x -> x * x你在哪裏得到了一種方法1個參數和返回值。

  3. 將使用第三個表達式() -> x() -> x其中您獲得方法的0個參數並返回一個值。

讓我們的第三個。假如你有一個不帶任何參數和返回值的接口。

static interface RandomMath { 
    public int random(); 
} 

現在你想給這個接口實例化一下它的實現。通常,其將被波紋管完成: -

Random random = new Random(); 
RandomMath randomMath = new RandomMath() { 
    @Override 
    public int random() { 
     return random.nextInt(); 
    } 
}; 

使用的λ它將是這樣的: -

Random random = new Random(); 
RandomMath randomMath =() -> random.nextInt(); //the third type. 

同樣,對於前兩個它可用於其中需要兩個和一個參數的方法和返回一個值。

static interface PlusMath { 
    public int plus(int a, int b); 
} 

PlusMath plusMath = (a, b) -> a + b; 

static interface SquareMath { 
    public int square(int a); 
} 

SquareMath squareMath = a -> a * a; 
3

之前通過下面的實施例打算,首先,注意,Lambda表達式可以針對任何SAM(也稱爲功能性)接口被寫入(逸岸,Lambda表達式是用於替換冗長匿名一個語法糖類(使用單一方法)在Java中)。

一個抽象方法的接口或功能接口是隻包含一個abstract方法的接口),你可以看看here。如果你知道這個簡單點,你可以編寫(使用)任意數量的你自己的Functional接口,然後根據每個Functional接口方法編寫不同的Lambda表達式。

下面的例子已被寫入通過利用現有的JDK(1.8)功能接口,如CallableFunctionBiFunction(像這些,有許多內置功能接口在JDK 1.8,大多數時候他們容易套裝我們的要求)。

(1)(中間體X,int y)對實施例 - > {返回X + Y; }

//Below Lamda exp, takes 2 Input int Arguments and returns string 
BiFunction<Integer, Integer, String> biFunction = (num1, num2) -> 
       "Sum Is:" +(num1 + num2); 
System.out.println(biFunction.apply(100, 200)); 

(2)對於x實施例 - > X * X

//Below Lamda exp, takes string Input Argument and returns string 
list.stream().map((String str1) -> 
     str1.substring(0, 1)). 
      forEach(System.out::println);  

(3)實施例爲() - > X

//Below Lambda exp, Input argument is void, returns String 
Callable<String> callabl =() -> "My Callable"; 
ExecutorService service = Executors.newSingleThreadExecutor(); 
Future<String> future = service.submit(callable); 
System.out.println(future.get());