Статьи

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

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

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

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

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

Есть много библиотек, которые пытаются эмулировать LINQ (то есть часть LINQ-to-Collections). Мы уже высказали свою точку зрения раньше, потому что теперь у нас есть замечательный Java 8 Streams API . Через 5 лет ни один Java-разработчик больше не будет скучать по LINQ, и мы все станем мастерами Streams с  сертификатами Oracle Certified Streams Developer,  висящими на наших стенах.

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

Итак, давайте перечислим пару API LINQesque, которые нам больше не нужны:

LambdaJ

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

// 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");

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

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

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, почему бы не реализовать что-то вроде  Streams-to-SQL ?

Мы пока не можем попрощаться  с  Linq4j Джулиана Хайда  , так как он все еще продолжает работать. Но мы считаем, что он инвестирует не в тот угол.

Coolection

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

from(animals).where("name", eq("Lion"))
             .and("age", eq(2))
             .all();
from(animals).where("name", eq("Dog"))
             .or("age", eq(5))
             .all();

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

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например. Используется для соединения строк:

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

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

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

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

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

Что о:

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

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

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

JodaTime

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

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

Apache Commons-IO

The java.nio packages got even better with new methods that nicely integrate with the Streams API (or not). One of the main reasons why anyone would have ever used Apache Commons IO was the fact that it is horribly tedious to read files prior to Java 7 / 8. I mean, who would’ve enjoyed this piece of code (from here):

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

Over this one?

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

But forget the latter. You can now use the new methods injava.nio.file.Files, e.g.

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

No need for third-party libraries any longer!

Serialisation

Throw it all out, for there is JEP 154 deprecating serialisation. Well, it wasn’t accepted, but we could’ve surely removed about 10% of our legacy codebase.

A variety of concurrency APIs and helpers

With JEP 155, there had been a variety of improvements to concurrent APIs, e.g. to ConcurrentHashMaps (we’ve blogged about it before), but also the awesome LongAdders, about which you can read a nice article over at the Takipi blog.

Haven’t I seen a whole com.google.common.util.concurrent package over at Guava, recently? Probably not needed anymore.

JEP 154 (Serialisation) wasn’t real

It was an April Fools’ joke, of course…

Base64 encoders

How could this take so long?? In 2003, we’ve had RFC 3548, specifying Base16, Base32, and Base64 data encodings, which was in fact based upon base 64 encoding specified in RFC 1521, from 1993, or RFC 2045from 1996, and if we’re willing to dig further into the past, I’m sure we’ll find earlier references to this simple idea of encoding binary data in text form.

Now, in 2014, we finally have JEP 135 as a part of the JavaSE8, and thus (you wouldn’t believe it): java.util.Base64.

Off to the trash can with all of these libraries!

… gee, it seems like everyone and their dog worked around this limitation, prior to the JDK 8…

More?

Provide your suggestions in the comments! We’re curious to hear your thoughts (with examples!)

Conclusion

As any Java major release, there is a lot of new stuff that we have to learn, and that allows us to remove third-party libraries. This is great, because many good concepts have been consolidated into the JDK, available on every JVM without external dependencies.

Disclaimer: Not everything in this article was meant seriously. Many people have created great pieces of work in the past. They have been very useful, even if they are somewhat deprecated now. Keep innovating, guys! 🙂

Want to delve more into the many new things Java 8 offers? Go have a look over at the Baeldung blog, where this excellent list of Java 8 resources is featured:

http://www.baeldung.com/java8

… and stay tuned for our next Java 8 Friday blog post, next week!