I was trying to run this example code (Horstmann's Java for the Impatient) which tries to find the frequency of occurrence of words in all files under a directory tree path.
It looks for regular files but does not exclude executables and binary files including .class files.
So I wanted to add a filter to exclude .class and non-text files.
.filter(!Files::isExecutable)
over here:
return entries.filter(Files::isRegularFile).filter(!Files::isExecutable).collect(Collectors.toSet());
But that will not compile. Hence I was wondering - how can one combine a boolean operator with a method reference?
package ch10.sec05 ;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class CHMDemo {
public static ConcurrentHashMap<String, Long> map = new ConcurrentHashMap<>();
public static void process(Path path) {
try {
String contents = Files.readString(path);
for (String word : contents.split("\\PL+")) {
map.merge(word, 1L, Long::sum);
}
} catch (IOException ex) {
System.err.println("path:" + path);;
ex.printStackTrace();
}
}
public static Set<Path> descendants(Path p) throws IOException {
try (Stream<Path> entries = Files.walk(p)) {
return entries.filter(Files::isRegularFile).collect(Collectors.toSet());
}
}
public static void main(String[] args) throws InterruptedException, ExecutionException, IOException {
int processors = Runtime.getRuntime().availableProcessors();
ExecutorService executor = Executors.newFixedThreadPool(processors);
Path pathToRoot = Paths.get("..");
for (Path p : descendants(pathToRoot)) {
executor.execute(() -> process(p));
}
executor.shutdown();
executor.awaitTermination(10, TimeUnit.MINUTES);
System.out.println(map);
}
}
Update:
I tried
return entries.filter(Files::isRegularFile).filter(((Predicate<? super Path>) Files::isExecutable).negate()).collect(Collectors.toSet());
but that returns no output at all.