FilenameFilter的java 8 lambda表达式
我正在浏览java 8中的lambda表达式
当我改变线程代码时,它工作正常
new Thread(new Runnable() { @Override public void run() { System.out.println("run"); } }).start();
转换为lambda表达式为
new Thread( () -> System.out.println("Hello from thread") ).start();
但我无法转换FilenameFilter表达式
File file = new File("/home/text/xyz.txt"); file.list(new FilenameFilter() { @Override public boolean accept(File dir, String name) { name.endsWith(".txt"); return false; } });
并且未成功转换为此
file.list(new FilenameFilter () { (File a1, String a2) -> { return false; } });
它像日食一样给出错误
此行有多个标记
– 语法错误,插入“;” 完成声明
– 语法错误,插入“}”以完成阻止
– 语法错误,插入“AssignmentOperator Expression”以完成分配
首先,你的格式是可怕的 ,整理出来!
现在,lambda语法; 转换匿名类:
final FilenameFilter filter = new FilenameFilter() { @Override public boolean accept(File dir, String name) { return false; } };
我们首先将单个方法accept(File dir, String name)
的等效lambda替换为匿名类:
final FilenameFilter filter = (File dir, String name) -> { return false; };
但我们可以做得更好,我们不需要定义类型 – 编译器可以解决这些问题:
final FilenameFilter filter = (dir, name) -> { return false; };
而且我们可以做得更好,因为该方法返回一个boolean
; 如果我们有一个评估为boolean
语句,我们可以跳过return
和大括号:
final FilenameFilter filter = (dir, name) -> false;
这可以是任何语句,例如:
final FilenameFilter filter = (dir, name) -> !dir.isDirectory() && name.toLowerCase().endsWith(".txt");
但是, File
API 很老,所以不要使用它。 使用nio API
。 自2011年Java 7以来,这已经存在,所以没有任何借口:
final Path p = Paths.get("/", "home", "text", "xyz.txt"); final DirectoryStream.Filter f = path -> false; try (final DirectoryStream stream = Files.newDirectoryStream(p, f)) { stream.forEach(System.out::println); }
实际上你的例子有一个特定的方法内置到带有Glob的 Files
中:
final Path p = Paths.get("/", "home", "text", "xyz.txt"); try (final DirectoryStream stream = Files.newDirectoryStream(p, "*.txt")) { stream.forEach(System.out::println); }
或者,使用更现代的Files.list
:
final Path p = Paths.get("/", "home", "text", "xyz.txt"); final PathMatcher filter = p.getFileSystem().getPathMatcher("glob:*.txt"); try (final Stream stream = Files.list(p)) { stream.filter(filter::matches) .forEach(System.out::println); }
这里filter::matches
是一个方法引用,因为PathMatcher.matches
可用于实现function接口Predicate
因为它接受一个Path
并返回一个boolean
。
作为旁白:
f.list(new FilenameFilter() { @Override public boolean accept(File dir, String name) { name.endsWith(".txt"); return false; } });
这毫无意义……
它应该更简单:
f.list((File a1, String a2) -> {return false;});
甚至 :
f.list((a1,a2) -> {return false;});
lambda表达式替换抽象类实例的实例化。
FileNameFilter
是一个function接口。 您不需要显式实例化它。
f.list((dir, name) -> name.endsWith(".txt"));
另请注意, f
应该是目录,而不是示例中的文件。 f1
是文件的示例将使用指定的filter返回null
。
如果使用lambda表达式,则不必放置类名:
f.list( (File a1, String a2) -> { return false; } );
实际上,在第一个示例中,省略了new Runnable()
。