2017-01-16 78 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'方法本身。 –