Статьи

Пятница Java 8: Давайте устареть эти старые библиотеки

В Data Geekery мы любим Java. И так как мы действительно входим в свободный API jOOQ и запросы DSL , мы абсолютно взволнованы тем, что Java 8 принесет в нашу экосистему.

Ява 8 Пятница

Каждую пятницу мы показываем вам пару замечательных новых функций Java 8 в виде учебника, в которых используются лямбда-выражения, методы расширения и другие замечательные вещи. Вы найдете исходный код на GitHub .

В течение прошлых двух пятниц мы были на наших пасхальных каникулах, но теперь мы вернулись с другой забавной статьей:

Давайте откажемся от этих старых библиотек

d8938bef47ea2f62ed0543dd9e35a483 Помимо Lambdas и методов расширения, JDK также был дополнен большим количеством нового библиотечного кода, например, Streams API и многим другим. Это означает, что мы можем критически пересмотреть наши стеки и — к великой радости доктора Депрекатора — выбросить весь мусор, который нам больше не нужен.

Вот пара из них, просто назвать несколько:

Библиотеки в стиле LINQ

Есть много библиотек, которые пытаются эмулировать LINQ (то есть часть LINQ-to-Collections). Сертификация Oracle Certified Streams Developer висит у нас на стенах.

Не пойми меня неправильно. Дело не в том, что LINQ или Streams лучше. Они почти одинаковые. Но так как у нас теперь есть потоки в JDK, зачем беспокоиться о LINQ? Кроме того, синтаксис SQLesque для запросов к коллекциям в любом случае вводил в заблуждение. LambdaJ

Это была забавная попытка эмулировать замыкания в Java с помощью тайных и неприятных трюков, таких как ThreadLocal . Рассмотрим следующий фрагмент кода ( взятый отсюда ):

1
2
3
4
5
6
7
8
9
// This lets you "close over" the
// System.out.println method
Closure println = closure(); {
  of(System.out).println(var(String.class));
}
 
// in order to use it like so:
println.apply("one");
println.each("one", "two", "three");

Хорошая идея, хотя эта точка с запятой после закрытия (); и перед этим блоком реализации псевдо-замыкания, который на самом деле не является замыкающим телом … все это выглядит довольно странно!

Теперь мы напишем:

1
2
3
4
Consumer<String> println = System.out::println;
 
println.accept("one");
Stream.of("one", "two", "three").forEach(println);

Никакой магии здесь, просто Java 8.

Давайте послушаем это в последний раз для Марио Фуско и Лямбдажа .

Linq4j

Видимо, это все еще активно развивается … Почему? Обратите внимание, что в дорожной карте также есть реализация LINQ-to-SQL, в том числе:

Поддержка парсера. Либо измените синтаксический анализатор Java (например, OpenJDK), либо напишите препроцессор. Генерация Java-кода, который включает деревья выражений.

Да, мы хотели бы иметь такой парсер и для jOOQ . Это позволило бы нам действительно встраивать SQL в Java, похожий на SQLJ , но безопасный. Но если у нас есть Streams API, почему бы просто не реализовать что-то вроде Linq4j Джулиана Хайда , поскольку он все еще продолжает работать. Но мы считаем, что он инвестирует не в тот угол.

Coolection

Это библиотека с забавным названием, и она позволяет делать такие вещи, как …

1
2
3
4
5
6
7
from(animals).where("name", eq("Lion"))
             .and("age", eq(2))
             .all();
 
from(animals).where("name", eq("Dog"))
             .or("age", eq(5))
             .all();

Но зачем это делать, когда ты можешь написать:

1
2
3
4
5
6
7
8
9
animals.stream()
       .filter(a -> a.name.equals("Lion")
                 && a.age == 2)
       .collect(toList());
 
animals.stream()
       .filter(a -> a.name.equals("Dog")
                 || a.age == 5)
       .collect(toList());

Давайте послушаем это для Вагнера Андраде . А затем в мусорное ведро

Половина гуавы

Гуава была в значительной степени дампом для всех видов логики, которые должны были быть в JDK в первую очередь. Возьмите com.google.guava.base.Joiner например. Используется для соединения строк:

1
2
3
Joiner joiner = Joiner.on("; ").skipNulls();
. . .
return joiner.join("Harry", null, "Ron", "Hermione");

Больше не нужно. Теперь мы можем написать:

1
2
3
Stream.of("Harry", null, "Ron", "Hermione")
      .filter(s -> s != null)
      .collect(joining("; "));

Также обратите внимание, что флаг skipNulls и все другие skipNulls утилиты больше не нужны, так как API-интерфейс Streams вместе с лямбда-выражениями позволяет очень хорошо отделить задачу соединения от задачи фильтрации.

Будучи убеждена? Нет?

Как насчет:

И затем, есть целый набор функциональных вещей, которые также могут быть выброшены в корзину:

https://code.google.com/p/guava-libraries/wiki/FunctionalExplained

Конечно, как только вы решили использовать Guava в своем приложении, вы не сможете быстро удалить его использование. Но, с другой стороны, будем надеяться, что части Guava скоро будут устаревшими, в пользу интеграции с Java 8.

JodaTime

Теперь эта задача проста , так как популярная библиотека JodaTime стала стандартизированной в пакетах java.time . Это отличные новости.

Давайте послушаем это для «Joda» Стивена Колебурна и его отличной работы для JSR-310 .

Apache Commons-IO

Пакеты java.nio стали еще лучше благодаря новым методам, которые приятно интегрируются с Streams API (или нет). Одной из главных причин, по которой кто-либо когда-либо использовал Apache Commons IO, было то, что читать файлы до Java 7/8 ужасно утомительно. Я имею в виду, кому бы понравился этот фрагмент кода ( отсюда ):

1
2
3
4
5
6
try (RandomAccessFile file =
     new RandomAccessFile(filePath, "r")) {
    byte[] bytes = new byte[size];
    file.read(bytes);
    return new String(bytes); // encoding?? ouch!
}

За это?

1
List<String> lines = FileUtils.readLines(file);

Но забудь последнее. Теперь вы можете использовать новые методы в java.nio.file.Files , например

1
List<String> lines = Files.readAllLines(path);

Больше не нужны сторонние библиотеки!

Сериализация

Выбросьте все это, потому что есть JEP 154, осуждающий сериализацию. Ну, это не было принято, но мы могли бы наверняка удалить около 10% нашей устаревшей кодовой базы.

Разнообразные API и помощники по параллелизму

В JEP 155 было множество улучшений в параллельных API, например, в ConcurrentHashMaps (мы уже писали об этом раньше) , а также в замечательных LongAdders, о которых вы можете прочитать хорошую статью в блоге Takipi .

Разве я недавно не видел целый пакет com.google.common.util.concurrent в Гуаве? Вероятно, не нужно больше.

JEP 154 (Сериализация) не была реальной

Конечно, это была первоапрельская шутка …

Кодеры Base64

Как это может занять так много времени ?? В 2003 году у нас был RFC 3548 , определяющий кодировки данных Base16, Base32 и Base64, которые фактически основывались на кодировке base 64, указанной в RFC 1521 от 1993 года или RFC 2045 от 1996 года, и если мы хотим копнем дальше в прошлое, я уверен, что мы найдем более ранние ссылки на эту простую идею кодирования двоичных данных в текстовой форме.

Теперь, в 2014 году, у нас наконец есть JEP 135 как часть JavaSE8, и, таким образом (вы не поверите): java.util.Base64 .

Прочь в корзину со всеми этими библиотеками!

… ну, кажется, что все и их собака обходили это ограничение до JDK 8 …

Больше?

Предоставьте свои предложения в комментариях! Нам любопытно услышать ваши мысли (с примерами!)

Вывод

Как и в любом другом основном выпуске Java, нам нужно изучить много нового, что позволяет нам удалять сторонние библиотеки. Это замечательно, потому что в JDK объединены многие хорошие концепции, доступные на каждой JVM без внешних зависимостей.

Отказ от ответственности: не все в этой статье было задумано серьезно. Многие люди создали великие произведения в прошлом. Они были очень полезны, даже если сейчас они несколько устарели. Продолжайте вводить новшества, ребята!

Хотите узнать больше о многих новинках, предлагаемых Java 8? Загляните в блог Baeldung, где представлен великолепный список ресурсов Java 8:

http://www.baeldung.com/java8

… И следите за обновлениями нашего следующего поста в пятницу, 8 января, на следующей неделе!