首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FilenameFilter的java 8 lambda表达式

FilenameFilter的java 8 lambda表达式
EN

Stack Overflow用户
提问于 2015-03-28 10:57:09
回答 4查看 37.3K关注 0票数 18

我正在阅读java 8中的lambda表达式。

当我更改线程代码时,它工作正常

代码语言:javascript
复制
new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("run");
    }
}).start();

被转换为lambda表达式为

代码语言:javascript
复制
new Thread(
    () -> System.out.println("Hello from thread")
).start();

但是我无法转换FilenameFilter表达式

代码语言:javascript
复制
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;
    }
});

但没有成功地转换为

代码语言:javascript
复制
file.list(new FilenameFilter () {
    (File a1, String a2) -> { 
        return false;
    }
});

它会产生错误,就像在eclipse中

这条线的多个标记 -语法错误,插入";“以完成语句 -语法错误,插入"}“以完成块 -语法错误,插入"AssignmentOperator表达式“以完成赋值

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-03-28 11:09:06

首先,您的格式是可怕的,整理一下!

现在,使用lambda语法;来转换匿名类:

代码语言:javascript
复制
final FilenameFilter filter = new FilenameFilter() {
    @Override
    public boolean accept(File dir, String name) {
        return false;
    }
};

我们首先将匿名类替换为单个方法accept(File dir, String name)的等效lambda。

代码语言:javascript
复制
final FilenameFilter filter = (File dir, String name) -> {
    return false;
};

但是我们可以做得更好,我们不需要定义类型-编译器可以计算出:

代码语言:javascript
复制
final FilenameFilter filter = (dir, name) -> {
    return false;
};

而且我们还可以做得更好,因为方法返回一个boolean;如果我们有一个计算结果为boolean的语句,我们可以跳过return和大括号:

代码语言:javascript
复制
final FilenameFilter filter = (dir, name) -> false;

这可以是任何语句,例如:

代码语言:javascript
复制
final FilenameFilter filter = (dir, name) -> !dir.isDirectory() && name.toLowerCase().endsWith(".txt");

但是,File API是非常老的,所以不要使用它。使用nio API。从2011年的Java 7开始就出现了这种情况,所以确实有没有的借口:

代码语言:javascript
复制
final Path p = Paths.get("/", "home", "text", "xyz.txt");
final DirectoryStream.Filter<Path> f = path -> false;
try (final DirectoryStream<Path> stream = Files.newDirectoryStream(p, f)) {
    stream.forEach(System.out::println);
}

实际上,您的示例中有一个特定的方法内置在Files中,即拿着一只

代码语言:javascript
复制
final Path p = Paths.get("/", "home", "text", "xyz.txt");
try (final DirectoryStream<Path> stream = Files.newDirectoryStream(p, "*.txt")) {
    stream.forEach(System.out::println);
}

或者,使用更现代的Files.list

代码语言:javascript
复制
final Path p = Paths.get("/", "home", "text", "xyz.txt");
final PathMatcher filter = p.getFileSystem().getPathMatcher("glob:*.txt");
try (final Stream<Path> stream = Files.list(p)) {
    stream.filter(filter::matches)
          .forEach(System.out::println);
}

这里,filter::matches是一个方法引用,因为方法PathMatcher.matches可以用于实现函数接口Predicate<Path>,因为它接受Path并返回boolean

作为旁白:

代码语言:javascript
复制
f.list(new FilenameFilter() {

    @Override
    public boolean accept(File dir, String name) {
        name.endsWith(".txt");
        return false;
    }
});

这没道理..。

票数 51
EN

Stack Overflow用户

发布于 2015-03-28 10:59:50

它应该更简单:

代码语言:javascript
复制
f.list((File a1, String a2) -> {return false;});

甚至:

代码语言:javascript
复制
f.list((a1,a2) -> {return false;});

lambda表达式替换抽象类实例的实例化。

票数 8
EN

Stack Overflow用户

发布于 2015-03-28 11:12:40

FileNameFilter是一个功能接口。您不需要显式实例化它。

代码语言:javascript
复制
    f.list((dir, name) -> name.endsWith(".txt"));

还要注意的是,f应该是一个目录,而不是您的示例中的文件。您的示例中的f1是一个文件,它将使用指定的过滤器返回null

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29316310

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档