6

I use the following lambda expression to iterate over PDF files.

public static void run(String arg) {

        Path rootDir = Paths.get(arg);
        PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**.pdf");
        Files.walk(rootDir)
                .filter(matcher::matches)
                .forEach(Start::modify);
    }

    private static void modify(Path p) {
        System.out.println(p.toString());
    }

This part .forEach(Start::modify); executes the static method modify from the same class where the lambda expression is located. Is there a possibility to add something like else clause when no PDF file is found?

menteith
  • 596
  • 14
  • 51

3 Answers3

6

Or you could just do the obvious thing, which is collect the stream first.

List<File> files = Files.walk(rootDir)
            .filter(matcher::matches)
            .collect(toList());

if (files.isEmpty())
    doSomethingForEmpty();
else
    files.forEach(Start::modify);
Brian Goetz
  • 90,105
  • 23
  • 150
  • 161
  • I upvoted your answer since Aominè was first and his and your solution are almost the same. – menteith Mar 25 '18 at 17:57
2

You could collect the result after the filter operation into a list instance and then check the size before operating on it.

List<Path> resultSet = Files.walk(rootDir)
                            .filter(matcher::matches)
                            .collect(Collectors.toList());
if(resultSet.size() > 0){
    resultSet.forEach(Start::modify);
}else {
    // do something else   
}

Alternatively, you could do something like this:

if(Files.walk(rootDir).anyMatch(matcher::matches)) {
         Files.walk(rootDir)
              .filter(matcher::matches)
              .forEach(Start::modify);
}else {
        // do something else    
}
Ousmane D.
  • 54,915
  • 8
  • 91
  • 126
1

If an API gives you a Stream, but Stream isn't what you need, you can always convert it to an Iterable and use a simple for loop:

boolean fileModified = false;
for (Path path : (Iterable<Path>) Files.walk(rootDir)::iterator) {
    if (matcher.matches(path)) {
        Start.modify(path);
        fileModified = true;
    }
} 
if (!fileModified) {
     // do something
}

This iterates the files only once and doesn't require forming an intermediate collection.

Brian Goetz
  • 90,105
  • 23
  • 150
  • 161
Paul Boddington
  • 37,127
  • 10
  • 65
  • 116