Try English version of Quizful



Раздаем бесплатные Q! подробности в группе Quizful.Alpha-test
Партнеры
Рекрутерам: Прескрининг кандидатов about
Топ контрибуторов
loading
loading
Знаете ли Вы, что

Свои вопросы для тестов можно добавлять на странице с информацией о тесте. При этом для некоторых тестов добавление вопросов закрыто

Лента обновлений
ссылка 20:57:36
Комментарий от Recrut_rf:
Спасибо, сохранил функцию, может пригодится когда - ни...
ссылка 20:53:59
Добавлен вопрос в тест ASP.NET - Основы
ссылка 08:41:09
Комментарий от Krosster:
Гарний сайт для новачків. Правда деякі питання підступн...
ссылка Apr 22 22:06
Добавлен вопрос в тест SQL - Средний уровень
ссылка Apr 22 10:13
Комментарий от Entrery:
вроде выбрал ООП в сишарпе, а тут вопросы по джаве...
Статистика

Тестов: 153, вопросов: 8596. Пройдено: 402470 / 1961088.

Новое в Java 8

head tail Статья
категория
Java
дата27.08.2013
авторFastttyOne
голосов28
В этой статье мы рассмотрим грядущие нововведения Java 8. Следующая версия JDK запланирована на март 2014, и она предложит разработчикам следующее:
  • Default методы в интерфейсах и функциональные интерфейсы
  • Лямбда-выражения
  • java.util.function и java.util.stream
  • API для работы с датами и временем – java.time
  • Nashorn JavaScript Engine
Обо всем по порядку.

Default методы в интерфейсах.
В интерфейсах теперь можно определять статичные методы. Дело в том, что до Java 8 для некоего интерфейса, скажем, Employee, существует класс Employees, содержащий статичные методы для генерации объектов Employee и работы с ними. Удобство нововведения в том, что эти самые методы будут находиться в самом интерфейсе, а про класс Employees разработчику можно будет забыть.
В качестве примера посмотрим на метод naturalOrder, который был добавлен в java.util.Comparator

public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {  
    return (Comparator)  
        Comparators.NaturalOrderComparator.INSTANCE;  
}  
В интерфейсах можно будет объявлять default методы. Взглянем на forEach в java.lang.Iterable:

public default void forEach(Consumer action) {  
    Objects.requireNonNull(action);  
    for (T t : this) {  
        action.accept(t);  
    }  
}
Default метод - это метод в интерфейсе с реализованной логикой, который не требуется обязательно определять в реализации этого интерфейса.
В предыдущих версиях JDK добавлять методы в интерфейсы стандартных библиотек не представлялось возможным, это разрушило бы весь пользовательский код, ведь для каждой реализации интерфейса пришлось бы дописывать реализацию недостающего нового метода. В Java 8 стандартные интерфейсы расширены большим количеством default методов.
Здесь стоит отметить, почему интерфейсы не реализуют default hashCode, equals и toString. Дело в том, что объекты, реализующие интерфейс, являются наследниками Object, в котором уже определены эти методы по умолчанию. Станет неясным, какой из default методов вызывать - тот, который определен в интерфейсе, или тот, что в родительском классе.

Функциональные интерфейсы.
Функциональный интерфейс - это тот интерфейс, который определяет только один абстрактный метод, как, например, java.lang.Runnable:

public abstract void run(); 
Чтобы точно определить интерфейс как функциональный, добавлена аннотация @FunctionalInterface, работающая по принципу @Override. Она обозначит замысел и не даст определить второй абстрактный метод в интерфейсе.
Заметим, интерфейс может включать сколько угодно default методов и при этом оставаться функциональным, потому что default методы - не абстрактные.

Лямбда-выражения
Самое значимое нововведение в Java 8 - это лямбда-выражения. Если сказать вообщем, то под ними понимаются анонимные методы, которые при этом еще представляют из себя объект, который можно присваивать переменной и передавать как аргумент в другие методы. Пример:

Runnable r = () -> System.out.println("hello");  
Thread th = new Thread(r);  
th.start(); 
Здесь благодаря такому лямбда-выражению мы значительно сокращаем код. Как бы это выглядело без лямбды:

Runnable r = new Runnable() {  
    public void run() {  
        System.out.println("hello");  
    }  
};  
Thread th = new Thread(r);  
th.start(); 
В новой версии также введен особый синтаксис ссылок на методы, который по сути - сокращенная форма некоторых лямбда-выражений:

Ссылка и соответствующее лямбда-выражение
String::valueOf       x -> String.valueOf(x)
Object::toString      x -> x.toString()
x::toString              () -> x.toString()
ArrayList::new        () -> new ArrayList<>()

java.util.function
Еще одно нововведение JDK - множество функциональных интерфейсов, которые будут весьма полезны. Рассмотрим некоторые из них:
Function<T, R> - интерфейс, с помощью которого реализуется функция, получающая на ввод экземпляр класса T и возвращающая на выходе экземпляр класса R. Далее не настолько подробно.
Predicate<T> - на ввод - T, возвращает результат типа boolean.
Consumer<T> - на ввод - T, производит некое действие и ничего не возвращает.
Supplier<T> - ничего не принимает на ввод, возвращает T
BinaryOperator<T> - на ввод - два экземпляра T, возвращает один T

Пакет также снабжен примитивными реализациями данных интерфейсов для типов int, long и double.

java.util.stream
java.util.stream введен для поддержки распараллеливания вычислений в потоках. Теперь потоки делятся на последовательные и параллельные. Самая большая польза от этого - в работе с коллекциями:

Stream stream = collection.stream(); 
Stream снабжен гибким API для преобразования данных и оперирования над ними. Вот так мы, например, быстро найдем суммарный вес по отдельности красных и синих блоков в коллекции:

int sumOfRedWeights  = blocks.stream().filter(b -> b.getColor() == RED)  
                                     .mapToInt(b -> b.getWeight())  
                                     .sum();  
int sumOfBlueWeights = blocks.stream().filter(b -> b.getColor() == BLUE)  
                                     .mapToInt(b -> b.getWeight())  
                                     .sum(); 
Что происходит в коде: 
1) Из коллекции blocks мы получаем stream
2) Метод filter возвращает еще один stream, который уже содержит элементы только одного цвета. Это промежуточный (intermediate) метод класса Stream.
3) Метод mapToInt вызывается у stream'а, который получен в пункте 2), и возвращает stream, содержащий не сами элементы, а их свойства weight (то есть вес)
4) Метод sum вызывается у stream'а из пункта 3), он суммирует все weight и возвращает простой int. Это конечный (terminal) метод, он возвращает одиночный результат.
В целом, стиль очень похож на тот, что используется в функциональном программировании, и это хорошо, так как упростится решение широкого круга типовых задач.
Stream можно распараллелить, и тогда производительность операций над ним возрастет, ведь нагрузка распределится на все ядра процессора. Давайте сделаем подсчет элементов параллельным:

int sumOfWeights = blocks.parallelStream().filter(b -> b.getColor() == RED)  
                                        .mapToInt(b -> b.getWeight())  
                                        .sum(); 
Единственное отличие в том, что теперь вызывается метод parallelStream, и каждый следующий промежуточный метод вернет параллельный stream. Таким образом, весь блок вычислений распределится на все ядра процессора.
Сделать stream обратно последовательным можно вызвав метод sequential(). Это пригодиться, когда нам, к примеру, нужно, чтобы отбор элементов по цвету был параллельным, а вычисление суммы weight - последовательным:

int sumOfWeights = blocks.parallelStream().filter(b -> b.getColor() == RED)  
.sequential()//переключаемся в последовательное выполнение  
.mapToInt(b -> b.getWeight())  
.sum(); 
java.time
Если вы знакомы с Joda Time, то освоить новое API будет очень легко. Почти все в java.time является immutable. В отличие от старого API даты/времени, такие величины как месяцы и дни недели реализованы через enum. 
Основные классы java.time:
* LocalDateTime, LocalDate, LocalTime - представления даты и времени. Время хранится с точностью до наносекунды, так что в LocalTime можно хранить, например, величину "13:45.30.123456789". Есть множество удобных методов, таких как plusMinutes, plusHours, isAfter, toSecondOfDay и т.д.
* Year, Month, YearMonth, MonthDay, DayOfWeek - типы, связанные с датами, получили больший диапазон. Так, величина Year может быть от "-999,999,999" до "+999,999,999"
* Instant - почти тоже самое, что и java.util.Date, только основой исчисления служат величина long для количества секунд, прошедших с полуночи 1 января 1970, и int - для наносекунд в текущей секунде.
* Duration, Period - полезны, когда нужно выразить данные как "3 года, 2 месяца и 18 дней" или "3 часа, 45 минут и 8 секунд"

Nashorn JavaScript Engine
Nashorn - это движок JavaScript, разрабатываемый полностью на Java компанией Oracle. Он призван дать возможность встраивать код JavaScript в приложения Java. В сравнении с Rhino, который поддерживается Mozilla  Foundation, новый проект показывает более высокую производительность. Nashorn умеет компилировать код JavaScript и генерировать классы Java, которые загружаются специальным загрузчиком. Возможен вызов кода Java прямо из JavaScript. 

На этом новшества Java 8 не заканчиваются, а мы изучили самое ожидаемое в новой версии JDK. Все стандартные коллекции были расширены большим количеством удобных методов и получили возможность распараллеливания вычислений в них с java.util.stream. Вместе с java.util.function Java получила идиомы функционального программирования. Лямбда-выражения, безусловно, сократят объем кода, который разработчикам придется писать, а  новый API для работы с датами и временем пришел на замену порядком устаревшему старому.

Если Вам понравилась статья, проголосуйте за нее

Голосов: 28  loading...
admin   liberal4ik   AlexVovolka   maxiflash   annagrin007   ProteIne   alexanzer   vanya88   anastassia   d3m0n1c   nick_kryloff   Andrey_G   Cr0s   dydus0x14   AngryCellophane   AndrewRogovets   t1oo1   san   Basuliic   dmytro_p   Victor_MM   Diesel31ks   MrNikita   alekseysamoylov   swyd   Orthodox   nv_yunko   Alibek7000