I am going through the lambda expression in java 8
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
new Thread(
() -> System.out.println("Hello from thread")
).start();
But i am not able to convert the FilenameFilter Expression
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
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
public interface FilenameFilter. java.io.FilenameFilter. Instances of classes that implement this interface are used to filter filenames. These instances are used to filter directory listings in the list method of class File , and by the Abstract Window Toolkit's file dialog component.
Lambda Expressions were added in Java 8. A lambda expression is a short block of code which takes in parameters and returns a value. Lambda expressions are similar to methods, but they do not need a name and they can be implemented right in the body of a method.
Introduction. Lambda expressions are a new and important feature included in Java SE 8. They provide a clear and concise way to represent one method interface using an expression. Lambda expressions also improve the Collection libraries making it easier to iterate through, filter, and extract data from a Collection .
From Java 8 onwards, lambda expressions can be used to represent the instance of a functional interface. A functional interface can have any number of default methods.
First things first, your formatting is horrible, sort it out!
Now, lambda syntax; to convert the anonymous class:
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)
:
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 boolean
we can skip the return
and the braces:
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 File
API is very old, so don't use it. Use the nio API
. This has been around since Java 7 in 2011 so there is really no excuse:
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 Files
that takes a 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
:
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::matches
is a method reference because the method PathMatcher.matches
can be used to implement the functional interface Predicate<Path>
as it takes a Path
and returns 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...
FileNameFilter
is a functional interface. You don't need to instantiate it explicitly.
f.list((dir, name) -> name.endsWith(".txt"));
Note also, that f
should be a directory, not a file as in your example. Your example where f1
is a file will return null
with the specified filter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With