В Data Geekery мы любим Java. И так как мы действительно входим в свободный API jOOQ и запросы DSL , мы абсолютно взволнованы тем, что Java 8 принесет в нашу экосистему. Мы пару раз писали о приятных вкусностях Java 8 , и теперь мы чувствуем, что пришло время начать новую серию блогов,…
Ява 8 Пятница
Каждую пятницу мы показываем вам пару замечательных новых функций Java 8 в виде учебника, которые используют лямбда-выражения, методы расширения и другие замечательные вещи. Вы найдете исходный код на GitHub .
Java 8 Goodie: java.io с лямбдами
Взаимодействие с файловой системой было немного болезненным в Java. CTMMC показывает нам пример того, как скопировать файл с помощью Java . Хотя некоторые проблемы все еще остаются, по крайней мере, теперь мы можем использовать лямбды и новый Streams API для обхода файловой системы и списков файлов ! Вот пример FileFilterGoodies, который мы добавили в наш репозиторий GitHub:
public class FileFilterGoodies {
public static void main(String args[]) {
listRecursive(new File("."));
}
/**
* This method recursively lists all
* .txt and .java files in a directory
*/
private static void listRecursive(File dir) {
Arrays.stream(dir.listFiles((f, n) ->
!n.startsWith(".")
&&
(f.isDirectory()
|| n.endsWith(".txt")
|| n.endsWith(".java"))
))
.forEach(unchecked((file) -> {
System.out.println(
file.getCanonicalPath()
.substring(new File(".")
.getCanonicalPath()
.length()));
if (file.isDirectory()) {
listRecursive(file);
}
}));
}
/**
* This utility simply wraps a functional
* interface that throws a checked exception
* into a Java 8 Consumer
*/
private static <T> Consumer<T>
unchecked(CheckedConsumer<T> consumer) {
return t -> {
try {
consumer.accept(t);
}
catch (Exception e) {
throw new RuntimeException(e);
}
};
}
@FunctionalInterface
private interface CheckedConsumer<T> {
void accept(T t) throws Exception;
}
}
Вывод вышеуказанной программы:
\jOOQ's Java 8 Goodies.iml \LICENSE.txt \out \out\production \out\production\jOOQ's Java 8 Goodies \out\production\jOOQ's Java 8 Goodies\org \out\production\jOOQ's Java 8 Goodies\org\jooq \out\production\jOOQ's Java 8 Goodies\org\jooq\java8 \out\production\jOOQ's Java 8 Goodies\org\jooq\java8\goodies \out\production\jOOQ's Java 8 Goodies\org\jooq\java8\goodies\io \out\production\jOOQ's Java 8 Goodies\org\jooq\java8\goodies\io\FileFilterGoodies$CheckedConsumer.class \out\production\jOOQ's Java 8 Goodies\org\jooq\java8\goodies\io\FileFilterGoodies.class \README.txt \src \src\org \src\org\jooq \src\org\jooq\java8 \src\org\jooq\java8\goodies \src\org\jooq\java8\goodies\io \src\org\jooq\java8\goodies\io\FileFilterGoodies.java
Now, that’s really awesome, isn’t it? Let’s decompose the abovelistRecursive() method:
// With this method, we wrap the File[] array
// into a new Java 8 Stream, which has awesome
// new methods.
Arrays.stream(
// The Java 1.2 File.listFiles() method luckily
// accepts a @FunctionalInterface, which can be
// instantiated using a lambda expression
// ...
// In this example, we'll just ignore the fact
// that listFiles can return null
dir.listFiles((f, n) ->
!n.startsWith(".")
&&
(f.isDirectory()
|| n.endsWith(".txt")
|| n.endsWith(".java"))
))
// Each Stream (and also java.util.List) has this
// awesome forEach method, that accepts a Consumer
.forEach(
// Unfortunately, Java 8 Consumers don't allow
// throwing checked exceptions. So let's quickly
// wrap it (see details below) ...
unchecked(
// ... and pass another lambda expression to it,
// which prints the local path and recurses
(file) -> {
System.out.println(
file.getCanonicalPath()
.substring(new File(".")
.getCanonicalPath()
.length()));
if (file.isDirectory()) {
listRecursive(file);
}
}));
More goodies next week
Stay tuned for next week, when we show you how Java 8 improves using XML with jOOX