FilenameFilter 的 java 8 lambda 表达式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29316310/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:46:18  来源:igfitidea点击:

java 8 lambda expression for FilenameFilter

javalambdajava-8

提问by SarthAk

I am going through the lambda expression in java 8

我正在使用 java 8 中的 lambda 表达式

when i changed the code of thread it's working fine

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

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("run");
    }
}).start();

is converted to lambda expression as

转换为 lambda 表达式为

new Thread(
    () -> System.out.println("Hello from thread")
).start();

But i am not able to convert the FilenameFilter Expression

但我无法转换 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;
    }
});

and unsuccessfully converted to this as

并未能成功转换为

file.list(new FilenameFilter () {
    (File a1, String a2) -> { 
        return false;
    }
});

it's giving error as in eclipse as

它在 eclipse 中给出错误

Multiple markers at this line
- Syntax error, insert ";" to complete Statement
- Syntax error, insert "}" to complete Block
- Syntax error, insert "AssignmentOperator Expression" to complete Assignment

此行有多个标记
- 语法错误,插入“;” 完成 Statement
- 语法错误,插入“}”完成 Block
- 语法错误,插入“AssignmentOperator Expression”完成赋值

采纳答案by Boris the Spider

First things first, your formatting is horrible, sort it out!

首先,你的格式很糟糕,整理一下!

Now, lambda syntax; to convert the anonymous class:

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

final FilenameFilter filter = new FilenameFilter() {
    @Override
    public boolean accept(File dir, String name) {
        return false;
    }
};

We start by replacing the anonymous class with an equivalent lambda for the single method accept(File dir, String name):

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

final FilenameFilter filter = (File dir, String name) -> {
    return false;
};

But we can do better, we don't need to define the types - the compiler can work those out:

但是我们可以做得更好,我们不需要定义类型 - 编译器可以解决这些问题:

final FilenameFilter filter = (dir, name) -> {
    return false;
};

And we can do better still, as the method return a boolean; if we have a single statement that evaluates to a booleanwe can skip the returnand the braces:

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

final FilenameFilter filter = (dir, name) -> false;

This can be any statement, for example:

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

final FilenameFilter filter = (dir, name) -> !dir.isDirectory() && name.toLowerCase().endsWith(".txt");

However, the FileAPI is veryold, so don't use it. Use the nio API. This has been around since Java 7 in 2011 so there is really noexcuse:

但是,FileAPI旧,所以不要使用它。使用nio API. 这自 2011 年的 Java 7 以来一直存在,所以真的没有任何借口:

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);
}

And in fact your example has a specific method built into Filesthat takes a Glob:

事实上,你的例子有一个内置的特定方法Files,它需要一个 Glob

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

Or, using the more modern Files.list:

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

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);
}

Here filter::matchesis a method reference because the method PathMatcher.matchescan be used to implement the functional interface Predicate<Path>as it takes a Pathand returns a boolean.

filter::matches是一个方法引用,因为该方法PathMatcher.matches可用于实现功能接口,Predicate<Path>因为它接受 aPath并返回 a boolean



As an aside:

作为旁白:

f.list(new FilenameFilter() {

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

This makes no sense...

这毫无意义...

回答by lodo

You don't have to put the class name, if you use a lambda-expression:

如果使用 lambda 表达式,则不必输入类名:

 f.list(
    (File a1, String a2) -> { 
        return false; }
    );

In fact, in your first example, you omit new Runnable().

事实上,在您的第一个示例中,您省略了new Runnable().

回答by Eran

It should be simpler :

应该更简单:

f.list((File a1, String a2) -> {return false;});

or even :

甚至 :

f.list((a1,a2) -> {return false;});

The lambda expression replaces the instantiation of the abstract class instance.

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

回答by T.Gounelle

FileNameFilteris a functional interface. You don't need to instantiate it explicitly.

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

    f.list((dir, name) -> name.endsWith(".txt"));

Note also, that fshould be a directory, not a file as in your example. Your example where f1is a file will return nullwith the specified filter.

另请注意,这f应该是一个目录,而不是您的示例中的文件。您的示例 where f1is a file 将返回null指定的过滤器。