2017-01-16 32 views
3

我是java 1.8中函數式編程的新手。 我有簡單的循環像下面的代碼:Java 8:Map而不是簡單循環

File folder = new File("./src/renamer/Newaudio"); 
File[] listOfFiles = folder.listFiles(); 

for (int i = 0; i < listOfFiles.length; i++) { 
    System.out.println("Here is file number: " + i); 
} 

我將上部for loop更改爲使用箭頭函數(像一個lambda)中的官能格式。

listOfFiles.map((file) = > { 
     System.out.println("Here is file number: " + i); 
}); 

不幸的是,它抱怨:

Cannot invoke map((<no type> file) -> {}) on the array type File[] 

爲什麼我得到這個錯誤? 我該如何解決它?

我想了解LAMBDA,所以我也沒興趣在foreach

+7

使用'.forEach'代替'.map'。請注意,您可以使用Files.list(Paths.get(「./ src/renamer/Newaudio」)).forEach(...)'直接跳轉到Stream API。 – aioobe

+2

你的lambda中有什麼'i'? –

+6

如果您使用的是Java 8,請不要使用'File'類**。它已經過時了,應該放下休息。使用'路徑'和'文件'。 – RealSkeptic

回答

4

folder.listFiles()應與Optional.ofNullable從防止被包裝NullPointerException。如果給定的路徑名​​不表示目錄,或者發生I/O錯誤,它可以返回null

Stream.of(ofNullable(folder.listFiles()). 
      orElseThrow(() -> new IllegalArgumentException("It's not a directory!"))) 
     .forEach(f -> {}); 

其中forEach方法可以採取以下參數:

(1)一個匿名類

new Consumer<File>() { 
    public @Override void accept(File file) { 
     System.out.println(file); 
    } 
} 

(2)消耗lambda表達式

(File f) -> { System.out.println(f); } 
(f) -> { System.out.println(f); } 

(3)簡化拉姆達表達式

f -> { System.out.println(f); } 
f -> System.out.println(f) 

(4)的方法參考

System.out::println 
+0

當我用的λ**的多行格式(F - > {system.out.pringlin()})**它抱怨 語法錯誤,插入 「AssignmentOperator表達」 完成 \t表達 \t - 的賦值的左邊必須是一個變量 – Salman

+1

@Salman:'System'類以大寫字母'S'開頭,方法是'println',而不是'pringlin',並且必須有一個分號聲明之後。 – Holger

+1

@Andrew Tobilko:'forEach'(而不是'foerEach')可以採取比這四種不同的論點。實現'Consumer'的命名類也適用於任何其他表達式,例如讀取包含現有實例的變量或調用工廠方法的表達式。你可以通過'null',編譯器不會反對,雖然結果可預測的很少用... – Holger

4
IntStream.range(0, listOfFiles.length).forEach(file -> { 
    System.out.println(file); 
}); 
+3

注意:OP的原始代碼沒有打印文件名,而只是數字。 –

5

您可以使用IntStream.range打印的文件數只

IntStream.range(0,listOfFiles.length).forEach(System.out::println); 

或要打印您可以使用的陣列內容

Arrays.stream(listOfFiles).forEach(System.out::println); 

編譯器將你的方法引用轉換爲 lambda表達式在編譯時間,所以這

Arrays.stream(listOfFiles).forEach(System.out::println); 

將被轉換成該

=> Arrays.stream(listOfFiles).forEach(i->System.out.println(i)); 

隨着拉姆達,您可以使用所耗費的拉姆達{}以及

=> Arrays.stream(listOfFiles).forEach(i->{ 
     if (!i.isHidden()) { // don't print hidden files 
      System.out.println(i);    
     } 
    }); 

因此listFiles返回null是文件不是一個目錄,併爲簡單起見,你可以簡單地把支票擺在首位

File folder = new File("./src/renamer/Newaudio"); 
    if (folder.isDirectory()) { 
     File[] listOfFiles = folder.listFiles(); 
     Arrays.stream(listOfFiles).forEach(i->System.out.println(i));   
    } 

參考

Lambda and Method reference concise details

+0

我喜歡瞭解Lambda,所以我對這個foreach不感興趣 – Salman

+1

@Salman forEach方法接受一個lambda表達式。 – hoat4

+5

@Salman你似乎誤解了「Lambda」。 lambda是'map'或'forEach'方法的參數,而不是'map'方法本身。 –