В 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