2014-12-27 110 views
3

我不太清楚我是否理解Oracle Java教程中的Lambda表達式教程。令我困惑的主要是lambda的Index參數。 ds.print(index ->{...}編譯器如何知道甚至是什麼值索引?索引沒有在程序中的其他地方聲明,那麼索引參數究竟是什麼引用以及編譯器如何知道?瞭解Lambda表達式

Excerise問題:

public class DataStructure { 

    private final static int SIZE = 15; 
    private int[] arrayOfInts = new int[SIZE]; 

    public DataStructure() { 
     for (int i = 0; i < SIZE; i++) { 
      arrayOfInts[i] = i; 
     } 
    } 

    public int size() { 
     return SIZE; 
    } 

    public int get(int index) { 
     return arrayOfInts[index]; 
    } 

    interface DataStructureIterator extends java.util.Iterator<Integer> { } 

    private class EvenIterator implements DataStructureIterator { 

     private int nextIndex = 0; 

     public boolean hasNext() { 
      return (nextIndex <= SIZE - 1); 
     } 

     public Integer next() { 
      Integer retValue = Integer.valueOf(arrayOfInts[nextIndex]); 
      nextIndex += 2; 
      return retValue; 
     } 
    } 

    public DataStructureIterator getEvenIterator() { 
     return new EvenIterator(); 
    } 

    public void printEven() { 
     DataStructureIterator iterator = getEvenIterator(); 
     while (iterator.hasNext()) { 
      System.out.print(iterator.next() + " "); 
     } 
     System.out.println(); 
    } 

    public void print(DataStructureIterator iterator) { 
     while (iterator.hasNext()) { 
      System.out.print(iterator.next() + " "); 
     } 
     System.out.println(); 
    } 

    public void print(java.util.function.Function<Integer, Boolean> function) { 
     for (int i = 0; i < SIZE; i++) { 
      if (function.apply(i)) { 
       System.out.print(arrayOfInts[i] + " "); 
      } 
     } 
     System.out.println(); 
    } 

    public static Boolean isEvenIndex(Integer index) { 
     if (index % 2 == 0) return Boolean.TRUE; 
     return Boolean.FALSE; 
    } 

    public static Boolean isOddIndex(Integer index) { 
     if (index % 2 == 0) return Boolean.FALSE; 
     return Boolean.TRUE; 
    } 

    public static void main(String s[]) { 

     DataStructure ds = new DataStructure(); 

     System.out.println("printEven()"); 
     ds.printEven(); 

     System.out.println("print(DataStructureIterator) with " 
       + "getEvenIterator"); 
     ds.print(ds.getEvenIterator()); 

     System.out.println("print(DataStructureIterator) with " 
       + "anonymous class, odd indicies"); 
     ds.print(
       new DataStructure.DataStructureIterator() { 
        private int nextIndex = 1; 
        public boolean hasNext() { 
         return (nextIndex <= ds.size() - 1); 
        } 
        public Integer next() { 
         int retValue = ds.get(nextIndex); 
         nextIndex += 2; 
         return retValue; 
        } 
       } 
     ); 

     System.out.println("print(Function) with lambda expressions"); 
     ds.print(index -> { 
      if (index % 2 == 0) return Boolean.TRUE; 
      return Boolean.FALSE; 
     }); 
     ds.print(index -> { 
      if (index % 2 == 0) return Boolean.FALSE; 
      return Boolean.TRUE; 
     }); 

     System.out.println("print(Function) with method references"); 
     ds.print(DataStructure::isEvenIndex); 
     ds.print(DataStructure::isOddIndex); 
    } 
} 
+1

的Java現在使用類型Intereface即它看起來什麼表達式返回以及如何表達來確定它的類型。 –

回答

6

ds.print方法需要參數類型Function<Integer,Boolean>。因此,這:

ds.print(index -> { 
    if (index % 2 == 0) return Boolean.TRUE; 
    return Boolean.FALSE; 
}); 

使用匿名類,而不是一個lambda的等效行爲與此語法:(所述Function類的功能的方法是apply

ds.print(new Function<Integer,Boolean>() { 
    @Override 
    public Boolean apply(Integer index) { 
     if (index % 2 == 0) return Boolean.TRUE; 
     return Boolean.FALSE; 
    } 
}); 

所以參數名稱index是任意的。你可以隨心所欲地調用它。這只是您的lambda方法的本地名稱。它的值由該呼叫print提供:

if (function.apply(i)) ... 
+0

我認爲編譯器在通過打印函數之前首先處理lambda表達式?如果是這樣的話,它將如何從function.apply(i)中獲得它的值?或者我在這裏錯過了什麼? – karsius

+1

@karsius它首先處理lambda表達式,然後用可調用的方法將其轉換爲函數對象。每次調用'function.apply(i)'''''''''''將'i'值提供給'index',就像調用任何普通方法爲方法中的參數提供值一樣。 – Boann

+0

啊,我明白了!非常感謝 – karsius

0

因爲打印的參數被聲明爲類型:從整數函數爲布爾值。