Top 10 фич java 8 про які не говорять

Про нові фічах Java 8 було сказано вже досить багато. В основному обговорюють замикання, Stream'и, нове API для роботи з часом, default-методи в інтерфейсах, клас Optional і відсутність Permanent Generation.

Але крім жирних фич, в Java 8 сильно змінилася стандартна бібліотека по периферійних. Зокрема, до вже існуючих класи було додано багато методів істотно спрощують щоденні завдання. Про це ми сьогодні і поговоримо.

Отже, Top 10 не самих обговорюваних фіч Java 8. Поїхали.

String.join ()

Але краще пізно ніж ніколи. Раніше доводилося або танцювати зі StringBuilder 'ом. Ну або, самий розумний варіант, використовувати Guava або commons-lang.

Ще один варіант використовувати Stream і Collectors.joining ():

В цьому випадку, з'являється можливість попередньо відфільтрувати порожні рядки.

Map.computeIfAbsent () / getOrDefault () / merge () / putIfAbsent ()

Даю голову на відсіч, якщо ви пишете на Java, то у вас в проекті є код схожий на цей:

Суть проста. Є відображення з рядка в лічильник, скільки разів ми зустріли цей рядок. Треба тільки не забувати форматувати позиції Map 'а нулем, а то віртуальна машина в вас NullPointerException кине.

В Java 8 ця ж задача вирішується простіше:

Meтод merge приймає ключ, значення і функцію яка об'єднує задане значення і вже існуюче в відображенні, якщо таке є. Якщо у відображенні під заданим ключем значення немає, то покладає туди вказане значення.

Для любителів однострочнікі, є варіант похардкорней:

Аналогічну функціональність, але в іншому контексті, дають методи:

  • computeIfAbsent () - повертає або значення з відображення по ключу, або створює його, якщо його не було;
  • putIfAbsent () - додає значення в відображення, тільки якщо його там не було. Цей метод раніше був тільки у ConcurrentMap. тепер з'явився і у Map 'а;
  • getOrDefault () - назва досить красномовно. Повертає значення з відображення або передане значення за замовчуванням. На мій погляд, метод досить НЕ ідіоматічен. Для роботи з відсутніми значеннями був доданий тип Optional. його і слід було використовувати. Тому, я б додав метод: Optional getOptional (K key). Але хто я такий ...

ThreadLocal.withInitial ()

Тих, хто щільно працює з багатопоточність, нічим не пройняти. Вони як ветерани В'єтнаму, і навіть флешбеки ночами так само мучать. І цією конструкцією їх не налякаєш:

Але тепер, за рахунок замикань, стало простіше:

Files.lines () / readAllLines () / BufferedReader.lines ()

В Java 8 стало можливим набагато простіше виконати таку просту задачу як прочитати через підрядник файл. Це ще одна задача, яка раніше вимагала досить багато коду. Тепер так:

Хвилинка зануди. Метод повертає арифметичне середнє в класах * SummaryStatistics називається getAverage (). хоча більш точним було б ім'я getMean (). Термін mean описує саме арифметичне середнє, в той час як термін average відноситься до поняття середнього значення в цілому і може відноситься до будь-які заходи центральної тенденції (арифметичне середнє, медіана, геометричне середнє, мода і т.д.). Примітно, що навіть в документації до методу getAverage () фігурує саме поняття mean: "Returns the arithmetic mean of values ​​recorded".

Аналогічний метод був доданий в клас BufferedReader. тому тепер Stream'и доступні поверх будь-якого InputStream 'а.

парадокс Comparator'а

Припустимо вам треба написати імплементацію Comparator 'а для сортування об'єктів по-зростанню. Зазвичай, компаратор виглядає наступним чином:

Питання лише в тому, що від чого треба забирати, щоб отримати вірний порядок сортування? Наука каже, що якщо ви будете вибирати варіант випадково, то вгадаєте приблизно в половині випадків. Зрештою, варіанти всього два: або від u2 відняти u1 або навпаки.

Парадокс полягає в тому, що написати компаратор правильно з першого разу не виходить практично ніколи. Закінчується все завжди однаково, - флегматичним зауваженням: "Ах да, я ж тут відняв невірно!".

Благо, тепер це і не потрібно. Компаратор можна зібрати з гівна і палиць, а точніше з посилань на методи, які повертають Comparable типи або примітиви за якими ми хочемо сортувати.

PrimitiveIterator

Одне з обмежень Java попередніх версій полягало в тому, що в них не було стандартних ітераторів над примітивними типами. Тільки над посилальними. Тепер такі з'явилися у вигляді інтерфейсу PrimitiveIterator. а також його спадкоємців: PrimitiveIterator.Of [Int | Long | Double]. Разом з функціональними інтерфейсами над примітивними типами це дає хорошу основу для роботи з колекціями примітивних типів без autobox'а.

List.replaceAll ()

Досить зручний метод, який дозволяє модифікувати всі елементи списку. Якщо ви хочете список рядків привести до нижнього регістра, раніше треба було писати щось на зразок:

Або більш просунутий варіант:

Зараз же можна зробити наступним чином:

Random.ints ()

Ще одна можливість, про яку практично немає згадок, - це те що Random може створювати Stream 'и випадкових чисел потрібного типу і діапазону:

Є методи для створення double 'ов (doubles ()) і long' ов (longs ()).

LongAccumulator / LongAdder

Два класи, які представляють собою більш продуктивні заміни для AtomicLong. Клас LongAdder дозволяє виконувати атомарні арифметичні операції над типом long. LongAccumulator приймає довільну функцію акумуляції результатів. Ця функція приймає поточне значення, аргумент переданий в метод accumulate () і повертає результат логічного об'єднання (accumulate) двох значень.

При отриманні результату все елементи редукуються в один загальний результат. Вся ця кухня натякає нам, що функція акумуляції повинна бути коммутативна і асоціативна. В іншому випадку результат буде залежати від фізичного порядку виконання операцій, який даний клас не гарантує.

При високому contention'е два даних класу будуть швидше AtomicLong 'а за рахунок того, що операції виконуються не над спільним елементом, а над групою елементів окремо. Завдяки чому, "гусари НЕ поб'ються через жінок".

Аналогічна пара класів є для типу Double (DoubleAdder. DoubleAccumulator).

Java Flight Recorder

Останнє по порядку, але не за важливістю, - це нові інструменти діагностики, які надала Oracle в Java 8. А саме, Java Flight Recorder. Технічно JFR з'явився у версії 7u40, але це настільки важливий інструмент, що не згадати про нього я не можу.

Flight Recorder являє собою інструментарій вбудований в JVM для збору і діагностики самої віртуальної машини, а також додатків запущених на ній. Запускається він командою jmc. У JFR є кілька цікавих особливостей:

  • в залежності від профілю, що збирається, витрати на роботу JFR можуть бути дуже низькими (менше 1% за твердженням Oracle, при конфігурації за замовчуванням). Це дозволяє використовувати цей інструмент в "бойових умовах" і під навантаженням;
  • JFR, на відміну від інструментів на кшталт VisualVM, може вести постійну запис діагностичної інформації в ring buffer, і має настроюються політики dump'а інформації на диск. Це дозволяє налаштувати віртуальну машину таким чином, щоб вона постійно вела діагностичний лог, а зберігала його тільки в разі виникнення проблем (наприклад, при систематичній нестачі CPU). Такий підхід дозволяє отримувати "чорні ящики" описують стан віртуальної машини і додатки безпосередньо в момент прояву проблеми. До JFR єдиний спосіб локалізувати проблему був, - зловити її на production'е що називається "за руку".

Яку інформацію може збирати JFR? Її дуже багато, основні моменти, які я вважаю корисними:

  • результати семплинга коду (які класи і методи зайняли найбільше процесорного часу, в яких потоках);
  • інформація за всіма GC циклам (скільки пам'яті було вивільнено, скільки часу зайняла кожна збірка сміття);
  • інформація по аллокации пам'яті (з якого потоку, класу і методу було виділено найбільше пам'яті, під який тип даних виділяли найбільше пам'яті, швидкість виділення за часом);
  • інформація з мережевого і дисковому вводу / виводу;
  • які Exception'и і Error'и були згенеровані додатком;
  • профіль блокування потоків (які потоки найчастіше блокуються, на яких локах / моніторах, які потоки на момент блокування володіють цими локами / моніторами найчастіше).

Top 10 фич java 8 про які не говорять

Top 10 фич java 8 про які не говорять

Top 10 фич java 8 про які не говорять

Список можна було б продовжити, але в рамках цього поста я не зможу досить повно описати JFR. Тому, всім зацікавленим особам настійно рекомендую витратити час на вивчення цього вкрай корисного інструменту.

висновок

Реальний список набагато більше. Якщо вам цікаво що ще додали в Java 8, я настійно рекомендую пошукати по стандартній бібліотеці Java наступним regexp'ом: @since \ s + 1.8 \ s * \ n. Ви знайдете більше 1000 входжень. Жоден блог пост цього не покриє.