Статьи

Ява 8 пятница, вкусности: java.io наконец-то качается!

В 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:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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;
    }
}

Вывод вышеуказанной программы:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
\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

Это действительно круто, не правда ли? Разобьем вышеприведенный listRecursive() :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// 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);
          }
      }));

Больше вкусностей на следующей неделе

Следите за обновлениями на следующей неделе, когда мы покажем вам, как Java 8 улучшается благодаря использованию XML с jOOX