Java 8 — Обзор
JAVA 8 является основной функциональной версией разработки языка программирования JAVA. Его первоначальная версия была выпущена 18 марта 2014 года. С выпуском Java 8 Java предоставила поддержку для функционального программирования, новый движок JavaScript, новые API для манипуляции датой, новый API потоковой передачи и т. Д.
Новые возможности
-
Лямбда-выражение — добавляет функциональные возможности обработки в Java.
-
Ссылки на методы — ссылки на функции по их именам вместо непосредственного их вызова. Использование функций в качестве параметра.
-
Метод по умолчанию — интерфейс для реализации метода по умолчанию.
-
Новые инструменты — добавлены новые инструменты и утилиты компилятора, такие как «jdeps», чтобы выяснить зависимости.
-
Stream API — новый потоковый API для облегчения обработки конвейера.
-
Date Time API — Улучшенный API даты и времени.
-
Необязательно — акцент на передовые практики для правильной обработки нулевых значений.
-
Nashorn, JavaScript Engine — Java-движок для выполнения кода JavaScript.
Лямбда-выражение — добавляет функциональные возможности обработки в Java.
Ссылки на методы — ссылки на функции по их именам вместо непосредственного их вызова. Использование функций в качестве параметра.
Метод по умолчанию — интерфейс для реализации метода по умолчанию.
Новые инструменты — добавлены новые инструменты и утилиты компилятора, такие как «jdeps», чтобы выяснить зависимости.
Stream API — новый потоковый API для облегчения обработки конвейера.
Date Time API — Улучшенный API даты и времени.
Необязательно — акцент на передовые практики для правильной обработки нулевых значений.
Nashorn, JavaScript Engine — Java-движок для выполнения кода JavaScript.
Рассмотрим следующий фрагмент кода.
import java.util.Collections; import java.util.List; import java.util.ArrayList; import java.util.Comparator; public class Java8Tester { public static void main(String args[]) { List<String> names1 = new ArrayList<String>(); names1.add("Mahesh "); names1.add("Suresh "); names1.add("Ramesh "); names1.add("Naresh "); names1.add("Kalpesh "); List<String> names2 = new ArrayList<String>(); names2.add("Mahesh "); names2.add("Suresh "); names2.add("Ramesh "); names2.add("Naresh "); names2.add("Kalpesh "); Java8Tester tester = new Java8Tester(); System.out.println("Sort using Java 7 syntax: "); tester.sortUsingJava7(names1); System.out.println(names1); System.out.println("Sort using Java 8 syntax: "); tester.sortUsingJava8(names2); System.out.println(names2); } // sort using java 7 private void sortUsingJava7(List<String> names) { Collections.sort(names, new Comparator<String>() { @Override public int compare(String s1, String s2) { return s1.compareTo(s2); } }); } // sort using java 8 private void sortUsingJava8(List<String> names) { Collections.sort(names, (s1, s2) -> s1.compareTo(s2)); } }
Запустите программу, чтобы получить следующий результат.
Sort using Java 7 syntax: [ Kalpesh Mahesh Naresh Ramesh Suresh ] Sort using Java 8 syntax: [ Kalpesh Mahesh Naresh Ramesh Suresh ]
Здесь метод sortUsingJava8 () использует функцию сортировки с лямбда-выражением в качестве параметра для получения критериев сортировки.
Java 8 — Настройка среды
Настройка локальной среды
Если вы хотите настроить собственную среду для языка программирования Java, то этот раздел проведет вас через весь процесс. Пожалуйста, следуйте инструкциям ниже, чтобы настроить вашу среду Java.
Java SE можно скачать бесплатно по следующей ссылке —
https://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html
Вы загружаете версию, основанную на вашей операционной системе.
Следуйте инструкциям для загрузки Java и запустите .exe для установки Java на вашем компьютере. После того, как вы установили Java на свой компьютер, вам нужно будет установить переменные окружения, чтобы они указывали на правильные каталоги установки.
Настройка пути для Windows 2000 / XP
Предполагая, что вы установили Java в каталог c: \ Program Files \ java \ jdk —
-
Щелкните правой кнопкой мыши «Мой компьютер» и выберите «Свойства».
-
Нажмите кнопку «Переменные среды» на вкладке «Дополнительно».
-
Теперь измените переменную Path, чтобы она также содержала путь к исполняемому файлу Java. Например, если в настоящий момент путь задан как «C: \ WINDOWS \ SYSTEM32», измените ваш путь на «C: \ WINDOWS \ SYSTEM32; c: \ Program Files \ java \ jdk \ bin».
Щелкните правой кнопкой мыши «Мой компьютер» и выберите «Свойства».
Нажмите кнопку «Переменные среды» на вкладке «Дополнительно».
Теперь измените переменную Path, чтобы она также содержала путь к исполняемому файлу Java. Например, если в настоящий момент путь задан как «C: \ WINDOWS \ SYSTEM32», измените ваш путь на «C: \ WINDOWS \ SYSTEM32; c: \ Program Files \ java \ jdk \ bin».
Настройка пути для Windows 95/98 / ME
Предполагая, что вы установили Java в каталог c: \ Program Files \ java \ jdk —
-
Отредактируйте файл ‘C: \ autoexec.bat’ и добавьте следующую строку в конце:
SET PATH =% PATH%; C: \ Program Files \ java \ jdk \ bin
Отредактируйте файл ‘C: \ autoexec.bat’ и добавьте следующую строку в конце:
SET PATH =% PATH%; C: \ Program Files \ java \ jdk \ bin
Настройка пути для Linux, UNIX, Solaris, FreeBSD
Переменная среды PATH должна указывать на то, где установлены двоичные файлы Java. Обратитесь к документации по вашей оболочке, если у вас возникли проблемы с этим.
Например, если вы используете bash в качестве оболочки, то вы добавили бы следующую строку в конец вашего .bashrc: export PATH = / path / to / java: $ PATH ‘
Популярные редакторы Java
Чтобы писать программы на Java, вам нужен текстовый редактор. На рынке доступны еще более сложные IDE. Но сейчас вы можете рассмотреть один из следующих —
-
Блокнот — на компьютере с Windows вы можете использовать любой простой текстовый редактор, например Блокнот (рекомендуется для этого урока) или TextPad.
-
Netbeans — это Java IDE с открытым исходным кодом и бесплатная. Его можно скачать с https://netbeans.org/index.html .
-
Eclipse — это также Java IDE, разработанная сообществом открытого исходного кода Eclipse, которую можно загрузить по адресу https://www.eclipse.org/ .
Блокнот — на компьютере с Windows вы можете использовать любой простой текстовый редактор, например Блокнот (рекомендуется для этого урока) или TextPad.
Netbeans — это Java IDE с открытым исходным кодом и бесплатная. Его можно скачать с https://netbeans.org/index.html .
Eclipse — это также Java IDE, разработанная сообществом открытого исходного кода Eclipse, которую можно загрузить по адресу https://www.eclipse.org/ .
Java 8 — лямбда-выражения
Лямбда-выражения введены в Java 8 и рекламируются как самая большая особенность Java 8. Лямбда-выражения облегчают функциональное программирование и значительно упрощают разработку.
Синтаксис
Лямбда-выражение характеризуется следующим синтаксисом.
parameter -> expression body
Ниже приведены важные характеристики лямбда-выражения.
-
Необязательное объявление типа — не нужно объявлять тип параметра. Компилятор может вывести то же самое из значения параметра.
-
Необязательные круглые скобки вокруг параметра — не нужно объявлять один параметр в круглых скобках. Для нескольких параметров требуются скобки.
-
Необязательные фигурные скобки — нет необходимости использовать фигурные скобки в теле выражения, если тело содержит один оператор.
-
Необязательное ключевое слово return — компилятор автоматически возвращает значение, если в теле есть одно выражение для возврата значения. Фигурные скобки необходимы, чтобы указать, что выражение возвращает значение.
Необязательное объявление типа — не нужно объявлять тип параметра. Компилятор может вывести то же самое из значения параметра.
Необязательные круглые скобки вокруг параметра — не нужно объявлять один параметр в круглых скобках. Для нескольких параметров требуются скобки.
Необязательные фигурные скобки — нет необходимости использовать фигурные скобки в теле выражения, если тело содержит один оператор.
Необязательное ключевое слово return — компилятор автоматически возвращает значение, если в теле есть одно выражение для возврата значения. Фигурные скобки необходимы, чтобы указать, что выражение возвращает значение.
Пример лямбда-выражений
Создайте следующую Java-программу, используя любой редактор по вашему выбору, например, в C: \> JAVA.
Java8Tester.java
public class Java8Tester { public static void main(String args[]) { Java8Tester tester = new Java8Tester(); //with type declaration MathOperation addition = (int a, int b) -> a + b; //with out type declaration MathOperation subtraction = (a, b) -> a - b; //with return statement along with curly braces MathOperation multiplication = (int a, int b) -> { return a * b; }; //without return statement and without curly braces MathOperation division = (int a, int b) -> a / b; System.out.println("10 + 5 = " + tester.operate(10, 5, addition)); System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction)); System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication)); System.out.println("10 / 5 = " + tester.operate(10, 5, division)); //without parenthesis GreetingService greetService1 = message -> System.out.println("Hello " + message); //with parenthesis GreetingService greetService2 = (message) -> System.out.println("Hello " + message); greetService1.sayMessage("Mahesh"); greetService2.sayMessage("Suresh"); } interface MathOperation { int operation(int a, int b); } interface GreetingService { void sayMessage(String message); } private int operate(int a, int b, MathOperation mathOperation) { return mathOperation.operation(a, b); } }
Проверьте результат
Скомпилируйте класс с помощью компилятора javac следующим образом:
C:\JAVA>javac Java8Tester.java
Теперь запустите Java8Tester следующим образом —
C:\JAVA>java Java8Tester
Он должен произвести следующий вывод —
10 + 5 = 15 10 - 5 = 5 10 x 5 = 50 10 / 5 = 2 Hello Mahesh Hello Suresh
Ниже приведены важные моменты, которые необходимо учитывать в приведенном выше примере.
-
Лямбда-выражения в основном используются для определения встроенной реализации функционального интерфейса, т. Е. Интерфейса только с одним методом. В приведенном выше примере мы использовали лямбда-выражения различных типов для определения метода работы интерфейса MathOperation. Затем мы определили реализацию sayMessage из GreetingService.
-
Лямбда-выражение устраняет необходимость в анонимном классе и дает Java очень простую, но мощную функциональную возможность программирования.
Лямбда-выражения в основном используются для определения встроенной реализации функционального интерфейса, т. Е. Интерфейса только с одним методом. В приведенном выше примере мы использовали лямбда-выражения различных типов для определения метода работы интерфейса MathOperation. Затем мы определили реализацию sayMessage из GreetingService.
Лямбда-выражение устраняет необходимость в анонимном классе и дает Java очень простую, но мощную функциональную возможность программирования.
Объем
Используя лямбда-выражение, вы можете ссылаться на любую конечную переменную или фактически конечную переменную (которая назначается только один раз). Лямбда-выражение выдает ошибку компиляции, если переменной присваивается значение во второй раз.
Пример области применения
Создайте следующую Java-программу, используя любой редактор по вашему выбору, например, в C: \> JAVA.
Java8Tester.java
public class Java8Tester { final static String salutation = "Hello! "; public static void main(String args[]) { GreetingService greetService1 = message -> System.out.println(salutation + message); greetService1.sayMessage("Mahesh"); } interface GreetingService { void sayMessage(String message); } }
Проверьте результат
Скомпилируйте класс с помощью компилятора javac следующим образом:
C:\JAVA>javac Java8Tester.java
Теперь запустите Java8Tester следующим образом —
C:\JAVA>java Java8Tester
Он должен произвести следующий вывод —
Hello! Mahesh
Java 8 — Ссылки на метод
Ссылки на методы помогают указывать на методы по их именам. Ссылка на метод описывается с помощью символа «::». Ссылка на метод может использоваться для указания следующих типов методов:
- Статические методы
- Методы экземпляра
- Конструкторы, использующие оператор new (TreeSet :: new)
Пример справочного метода
Создайте следующую Java-программу, используя любой редактор по вашему выбору, например, в C: \> JAVA.
Java8Tester.java
import java.util.List; import java.util.ArrayList; public class Java8Tester { public static void main(String args[]) { List names = new ArrayList(); names.add("Mahesh"); names.add("Suresh"); names.add("Ramesh"); names.add("Naresh"); names.add("Kalpesh"); names.forEach(System.out::println); } }
Здесь мы передали метод System.out :: println как ссылку на статический метод.
Проверьте результат
Скомпилируйте класс с помощью компилятора javac следующим образом:
C:\JAVA>javac Java8Tester.java
Теперь запустите Java8Tester следующим образом —
C:\JAVA>java Java8Tester
Он должен произвести следующий вывод —
Mahesh Suresh Ramesh Naresh Kalpesh
Java 8 — функциональные интерфейсы
Функциональные интерфейсы имеют единую функциональность для демонстрации. Например, для сравнения используется сопоставимый интерфейс с единственным методом «CompareTo». В Java 8 определено множество функциональных интерфейсов, которые будут широко использоваться в лямбда-выражениях. Ниже приведен список функциональных интерфейсов, определенных в пакете java.util.Function.
Sr.No. | Интерфейс и описание |
---|---|
1 |
BiConsumer <T, U> Представляет операцию, которая принимает два входных аргумента и не возвращает результата. |
2 |
BiFunction <Т, U, R> Представляет функцию, которая принимает два аргумента и выдает результат. |
3 |
BinaryOperator <Т> Представляет операцию над двумя операндами одного типа, производя результат того же типа, что и операнды. |
4 |
BiPredicate <T, U> Представляет предикат (булевозначная функция) двух аргументов. |
5 |
BooleanSupplier Представляет поставщика булевозначных результатов. |
6 |
Потребитель <T> Представляет операцию, которая принимает один входной аргумент и не возвращает результата. |
7 |
DoubleBinaryOperator Представляет операцию над двумя двухзначными операндами, которая приводит к получению двойного результата. |
8 |
DoubleConsumer Представляет операцию, которая принимает один аргумент с двойным значением и не возвращает результата. |
9 |
DoubleFunction <R> Представляет функцию, которая принимает аргумент с двойным значением и выдает результат. |
10 |
DoublePredicate Представляет предикат (булевозначная функция) одного аргумента с двойным значением. |
11 |
DoubleSupplier Представляет поставщика двойных результатов. |
12 |
DoubleToIntFunction Представляет функцию, которая принимает аргумент с двумя значениями и выдает результат со значениями типа int. |
13 |
DoubleToLongFunction Представляет функцию, которая принимает аргумент с двумя значениями и выдает результат с длинными значениями. |
14 |
DoubleUnaryOperator Представляет операцию с одним двойным операндом, который приводит к двойному результату. |
15 |
Функция <T, R> Представляет функцию, которая принимает один аргумент и выдает результат. |
16 |
IntBinaryOperator Представляет операцию над двумя int-значными операндами и выдает int-значный результат. |
17 |
IntConsumer Представляет операцию, которая принимает один аргумент с внутренним значением и не возвращает результата. |
18 |
IntFunction <R> Представляет функцию, которая принимает аргумент с внутренним значением и выдает результат. |
19 |
IntPredicate Представляет предикат (булевозначную функцию) одного аргумента с внутренним значением. |
20 |
IntSupplier Представляет поставщика ценных результатов. |
21 |
IntToDoubleFunction Представляет функцию, которая принимает аргумент с внутренним значением и выдает результат с двойным значением. |
22 |
IntToLongFunction Представляет функцию, которая принимает аргумент с внутренним значением и выдает долгосрочное значение. |
23 |
IntUnaryOperator Представляет операцию с одним int-значным операндом, который создает int-значный результат. |
24 |
LongBinaryOperator Представляет операцию над двумя долгосрочными операндами и дает долгосрочное значение. |
25 |
LongConsumer Представляет операцию, которая принимает один длинный аргумент и не возвращает результата. |
26 |
LongFunction <R> Представляет функцию, которая принимает длиннозначный аргумент и выдает результат. |
27 |
LongPredicate Представляет предикат (булевозначная функция) одного длиннозначного аргумента. |
28 |
LongSupplier Представляет поставщика долгосрочных результатов. |
29 |
LongToDoubleFunction Представляет функцию, которая принимает длиннозначный аргумент и выдает двузначный результат. |
30 |
LongToIntFunction Представляет функцию, которая принимает длиннозначный аргумент и выдает int-значный результат. |
31 |
LongUnaryOperator Представляет операцию с одним длиннозначным операндом, который приводит к длиннозначному результату. |
32 |
ObjDoubleConsumer <Т> Представляет операцию, которая принимает объектнозначный и двухзначный аргумент и не возвращает результата. |
33 |
ObjIntConsumer <Т> Представляет операцию, которая принимает объектно-значимый и int-значимый аргументы и не возвращает результата. |
34 |
ObjLongConsumer <Т> Представляет операцию, которая принимает объектный и длинный аргумент и не возвращает результата. |
35 |
Предиката <Т> Представляет предикат (булевозначная функция) одного аргумента. |
36 |
Поставщик <T> Представляет поставщика результатов. |
37 |
ToDoubleBiFunction <T, U> Представляет функцию, которая принимает два аргумента и выдает двузначный результат. |
38 |
ToDoubleFunction <Т> Представляет функцию, которая выдает двузначный результат. |
39 |
ToIntBiFunction <T, U> Представляет функцию, которая принимает два аргумента и выдает целочисленный результат. |
40 |
ToIntFunction <Т> Представляет функцию, которая выдает int-значный результат. |
41 |
ToLongBiFunction <T, U> Представляет функцию, которая принимает два аргумента и выдает долгосрочное значение. |
42 |
ToLongFunction <Т> Представляет функцию, которая выдает долгосрочное значение. |
43 |
UnaryOperator <Т> Представляет операцию с одним операндом, которая выдает результат того же типа, что и его операнд. |
BiConsumer <T, U>
Представляет операцию, которая принимает два входных аргумента и не возвращает результата.
BiFunction <Т, U, R>
Представляет функцию, которая принимает два аргумента и выдает результат.
BinaryOperator <Т>
Представляет операцию над двумя операндами одного типа, производя результат того же типа, что и операнды.
BiPredicate <T, U>
Представляет предикат (булевозначная функция) двух аргументов.
BooleanSupplier
Представляет поставщика булевозначных результатов.
Потребитель <T>
Представляет операцию, которая принимает один входной аргумент и не возвращает результата.
DoubleBinaryOperator
Представляет операцию над двумя двухзначными операндами, которая приводит к получению двойного результата.
DoubleConsumer
Представляет операцию, которая принимает один аргумент с двойным значением и не возвращает результата.
DoubleFunction <R>
Представляет функцию, которая принимает аргумент с двойным значением и выдает результат.
DoublePredicate
Представляет предикат (булевозначная функция) одного аргумента с двойным значением.
DoubleSupplier
Представляет поставщика двойных результатов.
DoubleToIntFunction
Представляет функцию, которая принимает аргумент с двумя значениями и выдает результат со значениями типа int.
DoubleToLongFunction
Представляет функцию, которая принимает аргумент с двумя значениями и выдает результат с длинными значениями.
DoubleUnaryOperator
Представляет операцию с одним двойным операндом, который приводит к двойному результату.
Функция <T, R>
Представляет функцию, которая принимает один аргумент и выдает результат.
IntBinaryOperator
Представляет операцию над двумя int-значными операндами и выдает int-значный результат.
IntConsumer
Представляет операцию, которая принимает один аргумент с внутренним значением и не возвращает результата.
IntFunction <R>
Представляет функцию, которая принимает аргумент с внутренним значением и выдает результат.
IntPredicate
Представляет предикат (булевозначную функцию) одного аргумента с внутренним значением.
IntSupplier
Представляет поставщика ценных результатов.
IntToDoubleFunction
Представляет функцию, которая принимает аргумент с внутренним значением и выдает результат с двойным значением.
IntToLongFunction
Представляет функцию, которая принимает аргумент с внутренним значением и выдает долгосрочное значение.
IntUnaryOperator
Представляет операцию с одним int-значным операндом, который создает int-значный результат.
LongBinaryOperator
Представляет операцию над двумя долгосрочными операндами и дает долгосрочное значение.
LongConsumer
Представляет операцию, которая принимает один длинный аргумент и не возвращает результата.
LongFunction <R>
Представляет функцию, которая принимает длиннозначный аргумент и выдает результат.
LongPredicate
Представляет предикат (булевозначная функция) одного длиннозначного аргумента.
LongSupplier
Представляет поставщика долгосрочных результатов.
LongToDoubleFunction
Представляет функцию, которая принимает длиннозначный аргумент и выдает двузначный результат.
LongToIntFunction
Представляет функцию, которая принимает длиннозначный аргумент и выдает int-значный результат.
LongUnaryOperator
Представляет операцию с одним длиннозначным операндом, который приводит к длиннозначному результату.
ObjDoubleConsumer <Т>
Представляет операцию, которая принимает объектнозначный и двухзначный аргумент и не возвращает результата.
ObjIntConsumer <Т>
Представляет операцию, которая принимает объектно-значимый и int-значимый аргументы и не возвращает результата.
ObjLongConsumer <Т>
Представляет операцию, которая принимает объектный и длинный аргумент и не возвращает результата.
Предиката <Т>
Представляет предикат (булевозначная функция) одного аргумента.
Поставщик <T>
Представляет поставщика результатов.
ToDoubleBiFunction <T, U>
Представляет функцию, которая принимает два аргумента и выдает двузначный результат.
ToDoubleFunction <Т>
Представляет функцию, которая выдает двузначный результат.
ToIntBiFunction <T, U>
Представляет функцию, которая принимает два аргумента и выдает целочисленный результат.
ToIntFunction <Т>
Представляет функцию, которая выдает int-значный результат.
ToLongBiFunction <T, U>
Представляет функцию, которая принимает два аргумента и выдает долгосрочное значение.
ToLongFunction <Т>
Представляет функцию, которая выдает долгосрочное значение.
UnaryOperator <Т>
Представляет операцию с одним операндом, которая выдает результат того же типа, что и его операнд.
Пример функционального интерфейса
Интерфейс Predicate <T> — это функциональный интерфейс с методом test (Object) для возврата логического значения. Этот интерфейс означает, что объект проверен на истинность или ложь.
Создайте следующую Java-программу, используя любой редактор по вашему выбору, например, в C: \> JAVA.
Java8Tester.java
import java.util.Arrays; import java.util.List; import java.util.function.Predicate; public class Java8Tester { public static void main(String args[]) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); // Predicate<Integer> predicate = n -> true // n is passed as parameter to test method of Predicate interface // test method will always return true no matter what value n has. System.out.println("Print all numbers:"); //pass n as parameter eval(list, n->true); // Predicate<Integer> predicate1 = n -> n%2 == 0 // n is passed as parameter to test method of Predicate interface // test method will return true if n%2 comes to be zero System.out.println("Print even numbers:"); eval(list, n-> n%2 == 0 ); // Predicate<Integer> predicate2 = n -> n > 3 // n is passed as parameter to test method of Predicate interface // test method will return true if n is greater than 3. System.out.println("Print numbers greater than 3:"); eval(list, n-> n > 3 ); } public static void eval(List<Integer> list, Predicate<Integer> predicate) { for(Integer n: list) { if(predicate.test(n)) { System.out.println(n + " "); } } } }
Здесь мы передали интерфейс Predicate, который принимает один вход и возвращает Boolean.
Проверьте результат
Скомпилируйте класс с помощью компилятора javac следующим образом:
C:\JAVA>javac Java8Tester.java
Теперь запустите Java8Tester следующим образом —
C:\JAVA>java Java8Tester
Он должен произвести следующий вывод —
Print all numbers: 1 2 3 4 5 6 7 8 9 Print even numbers: 2 4 6 8 Print numbers greater than 3: 4 5 6 7 8 9
Java 8 — Методы по умолчанию
Java 8 представляет новую концепцию реализации метода по умолчанию в интерфейсах. Эта возможность добавлена для обратной совместимости, так что старые интерфейсы могут использоваться для использования возможности лямбда-выражения в Java 8.
Например, интерфейсы «Список» или «Коллекция» не имеют объявления метода «forEach». Таким образом, добавление такого метода просто нарушит реализацию фреймворка коллекции. Java 8 представляет метод по умолчанию, так что интерфейс List / Collection может иметь реализацию по умолчанию для метода forEach, и класс, реализующий эти интерфейсы, не должен реализовывать то же самое.
Синтаксис
public interface vehicle { default void print() { System.out.println("I am a vehicle!"); } }
Несколько значений по умолчанию
При использовании функций по умолчанию в интерфейсах существует вероятность того, что класс реализует два интерфейса с одинаковыми методами по умолчанию. Следующий код объясняет, как можно устранить эту неоднозначность.
public interface vehicle { default void print() { System.out.println("I am a vehicle!"); } } public interface fourWheeler { default void print() { System.out.println("I am a four wheeler!"); } }
Первое решение — создать собственный метод, который переопределяет реализацию по умолчанию.
public class car implements vehicle, fourWheeler { public void print() { System.out.println("I am a four wheeler car vehicle!"); } }
Второе решение — вызвать метод по умолчанию для указанного интерфейса, используя super.
public class car implements vehicle, fourWheeler { default void print() { vehicle.super.print(); } }
Статические методы по умолчанию
Интерфейс также может иметь статические вспомогательные методы начиная с Java 8 и далее.
public interface vehicle { default void print() { System.out.println("I am a vehicle!"); } static void blowHorn() { System.out.println("Blowing horn!!!"); } }
Пример метода по умолчанию
Создайте следующую Java-программу, используя любой редактор по вашему выбору, например, в C: \> JAVA.
Java8Tester.java
public class Java8Tester { public static void main(String args[]) { Vehicle vehicle = new Car(); vehicle.print(); } } interface Vehicle { default void print() { System.out.println("I am a vehicle!"); } static void blowHorn() { System.out.println("Blowing horn!!!"); } } interface FourWheeler { default void print() { System.out.println("I am a four wheeler!"); } } class Car implements Vehicle, FourWheeler { public void print() { Vehicle.super.print(); FourWheeler.super.print(); Vehicle.blowHorn(); System.out.println("I am a car!"); } }
Проверьте результат
Скомпилируйте класс с помощью компилятора javac следующим образом:
C:\JAVA>javac Java8Tester.java
Теперь запустите Java8Tester следующим образом —
C:\JAVA>java Java8Tester
Он должен произвести следующий вывод —
I am a vehicle! I am a four wheeler! Blowing horn!!! I am a car!
Java 8 — потоки
Stream — это новый абстрактный слой, представленный в Java 8. Используя поток, вы можете обрабатывать данные декларативным способом, аналогичным инструкциям SQL. Например, рассмотрим следующий оператор SQL.
SELECT max(salary), employee_id, employee_name FROM Employee
Вышеупомянутое выражение SQL автоматически возвращает сведения о максимальном наемном сотруднике без каких-либо вычислений на стороне разработчика. Используя платформу коллекций в Java, разработчик должен использовать циклы и делать повторные проверки. Другая проблема — это эффективность; так как многоядерные процессоры доступны легко, разработчику Java приходится писать параллельную обработку кода, которая может быть довольно подвержена ошибкам.
Чтобы решить такие проблемы, Java 8 представила концепцию потока, которая позволяет разработчику декларативно обрабатывать данные и использовать многоядерную архитектуру без необходимости написания какого-либо специального кода для него.
Что такое стрим?
Поток представляет собой последовательность объектов из источника, которая поддерживает агрегатные операции. Ниже приведены характеристики потока —
-
Последовательность элементов — Поток предоставляет набор элементов определенного типа в последовательном порядке. Поток получает / вычисляет элементы по запросу. Он никогда не хранит элементы.
-
Источник — Stream принимает ресурсы коллекций, массивов или ввода / вывода в качестве источника ввода.
-
Агрегатные операции — Stream поддерживает агрегатные операции, такие как фильтрация, отображение, ограничение, уменьшение, поиск, сопоставление и т. Д.
-
Конвейерная передача — большинство потоковых операций возвращают сам поток, так что их результаты могут быть конвейерными. Эти операции называются промежуточными операциями, и их функция состоит в том, чтобы принимать ввод, обрабатывать его и возвращать вывод цели. Метод collect () — это терминальная операция, которая обычно присутствует в конце операции конвейерной передачи, чтобы отметить конец потока.
-
Автоматические итерации. Операции Stream выполняют итерации внутри предоставленных исходных элементов, в отличие от коллекций, где требуется явная итерация.
Последовательность элементов — Поток предоставляет набор элементов определенного типа в последовательном порядке. Поток получает / вычисляет элементы по запросу. Он никогда не хранит элементы.
Источник — Stream принимает ресурсы коллекций, массивов или ввода / вывода в качестве источника ввода.
Агрегатные операции — Stream поддерживает агрегатные операции, такие как фильтрация, отображение, ограничение, уменьшение, поиск, сопоставление и т. Д.
Конвейерная передача — большинство потоковых операций возвращают сам поток, так что их результаты могут быть конвейерными. Эти операции называются промежуточными операциями, и их функция состоит в том, чтобы принимать ввод, обрабатывать его и возвращать вывод цели. Метод collect () — это терминальная операция, которая обычно присутствует в конце операции конвейерной передачи, чтобы отметить конец потока.
Автоматические итерации. Операции Stream выполняют итерации внутри предоставленных исходных элементов, в отличие от коллекций, где требуется явная итерация.
Генерация потоков
В Java 8 интерфейс Collection имеет два метода для генерации потока.
-
stream () — возвращает последовательный поток, рассматривающий коллекцию в качестве источника.
-
parallelStream () — Возвращает параллельный поток, рассматривая коллекцию в качестве источника.
stream () — возвращает последовательный поток, рассматривающий коллекцию в качестве источника.
parallelStream () — Возвращает параллельный поток, рассматривая коллекцию в качестве источника.
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
для каждого
Stream предоставил новый метод forEach для итерации каждого элемента потока. В следующем фрагменте кода показано, как распечатать 10 случайных чисел с помощью forEach.
Random random = new Random(); random.ints().limit(10).forEach(System.out::println);
карта
Метод map используется для отображения каждого элемента на соответствующий результат. Следующий сегмент кода печатает уникальные квадраты чисел, используя карту.
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); //get list of unique squares List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
фильтр
Метод «фильтра» используется для исключения элементов на основе критериев. Следующий фрагмент кода печатает количество пустых строк с использованием фильтра.
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); //get count of empty string int count = strings.stream().filter(string -> string.isEmpty()).count();
предел
Метод limit используется для уменьшения размера потока. В следующем фрагменте кода показано, как печатать 10 случайных чисел с использованием предела.
Random random = new Random(); random.ints().limit(10).forEach(System.out::println);
отсортированный
Метод sorted используется для сортировки потока. В следующем фрагменте кода показано, как распечатать 10 случайных чисел в отсортированном порядке.
Random random = new Random(); random.ints().limit(10).sorted().forEach(System.out::println);
Параллельная обработка
parallelStream — это альтернатива stream для параллельной обработки. Взгляните на следующий сегмент кода, который печатает количество пустых строк с использованием parallelStream.
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); //get count of empty string long count = strings.parallelStream().filter(string -> string.isEmpty()).count();
Очень легко переключаться между последовательными и параллельными потоками.
Коллекторы
Коллекторы используются для объединения результата обработки на элементах потока. Коллекторы могут быть использованы для возврата списка или строки.
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList()); System.out.println("Filtered List: " + filtered); String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", ")); System.out.println("Merged String: " + mergedString);
Статистика
В Java 8 введены сборщики статистики для вычисления всей статистики, когда выполняется обработка потока.
List numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics(); System.out.println("Highest number in List : " + stats.getMax()); System.out.println("Lowest number in List : " + stats.getMin()); System.out.println("Sum of all numbers : " + stats.getSum()); System.out.println("Average of all numbers : " + stats.getAverage());
Пример потока
Создайте следующую Java-программу, используя любой редактор по вашему выбору, например, в C: \> JAVA.
Java8Tester.java
import java.util.ArrayList; import java.util.Arrays; import java.util.IntSummaryStatistics; import java.util.List; import java.util.Random; import java.util.stream.Collectors; import java.util.Map; public class Java8Tester { public static void main(String args[]) { System.out.println("Using Java 7: "); // Count empty strings List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); System.out.println("List: " +strings); long count = getCountEmptyStringUsingJava7(strings); System.out.println("Empty Strings: " + count); count = getCountLength3UsingJava7(strings); System.out.println("Strings of length 3: " + count); //Eliminate empty string List<String> filtered = deleteEmptyStringsUsingJava7(strings); System.out.println("Filtered List: " + filtered); //Eliminate empty string and join using comma. String mergedString = getMergedStringUsingJava7(strings,", "); System.out.println("Merged String: " + mergedString); List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); //get list of square of distinct numbers List<Integer> squaresList = getSquares(numbers); System.out.println("Squares List: " + squaresList); List<Integer> integers = Arrays.asList(1,2,13,4,15,6,17,8,19); System.out.println("List: " +integers); System.out.println("Highest number in List : " + getMax(integers)); System.out.println("Lowest number in List : " + getMin(integers)); System.out.println("Sum of all numbers : " + getSum(integers)); System.out.println("Average of all numbers : " + getAverage(integers)); System.out.println("Random Numbers: "); //print ten random numbers Random random = new Random(); for(int i = 0; i < 10; i++) { System.out.println(random.nextInt()); } System.out.println("Using Java 8: "); System.out.println("List: " +strings); count = strings.stream().filter(string->string.isEmpty()).count(); System.out.println("Empty Strings: " + count); count = strings.stream().filter(string -> string.length() == 3).count(); System.out.println("Strings of length 3: " + count); filtered = strings.stream().filter(string ->!string.isEmpty()).collect(Collectors.toList()); System.out.println("Filtered List: " + filtered); mergedString = strings.stream().filter(string ->!string.isEmpty()).collect(Collectors.joining(", ")); System.out.println("Merged String: " + mergedString); squaresList = numbers.stream().map( i ->i*i).distinct().collect(Collectors.toList()); System.out.println("Squares List: " + squaresList); System.out.println("List: " +integers); IntSummaryStatistics stats = integers.stream().mapToInt((x) ->x).summaryStatistics(); System.out.println("Highest number in List : " + stats.getMax()); System.out.println("Lowest number in List : " + stats.getMin()); System.out.println("Sum of all numbers : " + stats.getSum()); System.out.println("Average of all numbers : " + stats.getAverage()); System.out.println("Random Numbers: "); random.ints().limit(10).sorted().forEach(System.out::println); //parallel processing count = strings.parallelStream().filter(string -> string.isEmpty()).count(); System.out.println("Empty Strings: " + count); } private static int getCountEmptyStringUsingJava7(List<String> strings) { int count = 0; for(String string: strings) { if(string.isEmpty()) { count++; } } return count; } private static int getCountLength3UsingJava7(List<String> strings) { int count = 0; for(String string: strings) { if(string.length() == 3) { count++; } } return count; } private static List<String> deleteEmptyStringsUsingJava7(List<String> strings) { List<String> filteredList = new ArrayList<String>(); for(String string: strings) { if(!string.isEmpty()) { filteredList.add(string); } } return filteredList; } private static String getMergedStringUsingJava7(List<String> strings, String separator) { StringBuilder stringBuilder = new StringBuilder(); for(String string: strings) { if(!string.isEmpty()) { stringBuilder.append(string); stringBuilder.append(separator); } } String mergedString = stringBuilder.toString(); return mergedString.substring(0, mergedString.length()-2); } private static List<Integer> getSquares(List<Integer> numbers) { List<Integer> squaresList = new ArrayList<Integer>(); for(Integer number: numbers) { Integer square = new Integer(number.intValue() * number.intValue()); if(!squaresList.contains(square)) { squaresList.add(square); } } return squaresList; } private static int getMax(List<Integer> numbers) { int max = numbers.get(0); for(int i = 1;i < numbers.size();i++) { Integer number = numbers.get(i); if(number.intValue() > max) { max = number.intValue(); } } return max; } private static int getMin(List<Integer> numbers) { int min = numbers.get(0); for(int i= 1;i < numbers.size();i++) { Integer number = numbers.get(i); if(number.intValue() < min) { min = number.intValue(); } } return min; } private static int getSum(List numbers) { int sum = (int)(numbers.get(0)); for(int i = 1;i < numbers.size();i++) { sum += (int)numbers.get(i); } return sum; } private static int getAverage(List<Integer> numbers) { return getSum(numbers) / numbers.size(); } }
Проверьте результат
Скомпилируйте класс с помощью компилятора javac следующим образом:
C:\JAVA>javac Java8Tester.java
Теперь запустите Java8Tester следующим образом —
C:\JAVA>java Java8Tester
Это должно привести к следующему результату —
Using Java 7: List: [abc, , bc, efg, abcd, , jkl] Empty Strings: 2 Strings of length 3: 3 Filtered List: [abc, bc, efg, abcd, jkl] Merged String: abc, bc, efg, abcd, jkl Squares List: [9, 4, 49, 25] List: [1, 2, 13, 4, 15, 6, 17, 8, 19] Highest number in List : 19 Lowest number in List : 1 Sum of all numbers : 85 Average of all numbers : 9 Random Numbers: -1279735475 903418352 -1133928044 -1571118911 628530462 18407523 -881538250 -718932165 270259229 421676854 Using Java 8: List: [abc, , bc, efg, abcd, , jkl] Empty Strings: 2 Strings of length 3: 3 Filtered List: [abc, bc, efg, abcd, jkl] Merged String: abc, bc, efg, abcd, jkl Squares List: [9, 4, 49, 25] List: [1, 2, 13, 4, 15, 6, 17, 8, 19] Highest number in List : 19 Lowest number in List : 1 Sum of all numbers : 85 Average of all numbers : 9.444444444444445 Random Numbers: -1009474951 -551240647 -2484714 181614550 933444268 1227850416 1579250773 1627454872 1683033687 1798939493 Empty Strings: 2
Java 8 — необязательный класс
Необязательно — объект-контейнер, используемый для хранения ненулевых объектов. Необязательный объект используется для представления нулевого значения с отсутствующим значением. Этот класс имеет различные служебные методы, облегчающие коду обрабатывать значения как «доступные» или «недоступные» вместо проверки нулевых значений. Он введен в Java 8 и похож на то, что Optional есть в Guava.
Декларация класса
Ниже приводится объявление для класса java.util.Optional <T> —
public final class Optional<T> extends Object
Метод класса
Sr.No. | Метод и описание |
---|---|
1 |
статический <T> Необязательный <T> empty () Возвращает пустой необязательный экземпляр. |
2 |
логическое равенство (Object obj) Указывает, является ли какой-либо другой объект «равным» этому Необязательному. |
3 |
Необязательный фильтр <T> (предикат <? Super <T> предикат) Если значение присутствует и значение соответствует заданному предикату, он возвращает необязательный параметр, описывающий значение, в противном случае возвращается пустой необязательный. |
4 |
<U> Необязательный <U> flatMap (Функция <? Super T, Необязательный <U >> маппер) Если значение присутствует, оно применяет к нему предоставленную функцию сопоставления Optional-Bear, возвращает этот результат, в противном случае возвращает пустой Optional. |
5 |
T получить () Если значение присутствует в этом Необязательном, возвращает значение, в противном случае генерируется исключение NoSuchElementException. |
6 |
int hashCode () Возвращает значение хэш-кода текущего значения, если оно есть, или 0 (ноль), если значение не присутствует. |
7 |
void ifPresent (Потребитель <? super T> потребитель) Если значение присутствует, оно вызывает указанного потребителя со значением, в противном случае ничего не делает. |
8 |
логическое isPresent () Возвращает true, если присутствует значение, иначе false. |
9 |
<U> Необязательная <U> карта (функция <? Super T, extends U> mapper) Если значение присутствует, применяет к нему предоставленную функцию отображения и, если результат не равен нулю, возвращает необязательный параметр, описывающий результат. |
10 |
статическое <T> необязательное <T> of (значение T) Возвращает Optional с указанным текущим ненулевым значением. |
11 |
static <T> Необязательный <T> ofNullable (значение T) Возвращает Optional, описывающий указанное значение, если оно не равно NULL, в противном случае возвращает пустой Optional. |
12 |
T orElse (T другое) Возвращает значение, если присутствует, в противном случае возвращает другое. |
13 |
T orElseGet (Поставщик <? Расширяет T> другое) Возвращает значение, если оно присутствует, в противном случае вызывает other и возвращает результат этого вызова. |
14 |
<X extends Throwable> T orElseThrow (Поставщик <? Extends X> exceptionSupplier) Возвращает содержащееся значение, если оно присутствует, в противном случае генерируется исключение, которое будет создано предоставленным поставщиком. |
15 |
Строка toString () Возвращает непустое строковое представление этого Optional, подходящего для отладки. |
статический <T> Необязательный <T> empty ()
Возвращает пустой необязательный экземпляр.
логическое равенство (Object obj)
Указывает, является ли какой-либо другой объект «равным» этому Необязательному.
Необязательный фильтр <T> (предикат <? Super <T> предикат)
Если значение присутствует и значение соответствует заданному предикату, он возвращает необязательный параметр, описывающий значение, в противном случае возвращается пустой необязательный.
<U> Необязательный <U> flatMap (Функция <? Super T, Необязательный <U >> маппер)
Если значение присутствует, оно применяет к нему предоставленную функцию сопоставления Optional-Bear, возвращает этот результат, в противном случае возвращает пустой Optional.
T получить ()
Если значение присутствует в этом Необязательном, возвращает значение, в противном случае генерируется исключение NoSuchElementException.
int hashCode ()
Возвращает значение хэш-кода текущего значения, если оно есть, или 0 (ноль), если значение не присутствует.
void ifPresent (Потребитель <? super T> потребитель)
Если значение присутствует, оно вызывает указанного потребителя со значением, в противном случае ничего не делает.
логическое isPresent ()
Возвращает true, если присутствует значение, иначе false.
<U> Необязательная <U> карта (функция <? Super T, extends U> mapper)
Если значение присутствует, применяет к нему предоставленную функцию отображения и, если результат не равен нулю, возвращает необязательный параметр, описывающий результат.
статическое <T> необязательное <T> of (значение T)
Возвращает Optional с указанным текущим ненулевым значением.
static <T> Необязательный <T> ofNullable (значение T)
Возвращает Optional, описывающий указанное значение, если оно не равно NULL, в противном случае возвращает пустой Optional.
T orElse (T другое)
Возвращает значение, если присутствует, в противном случае возвращает другое.
T orElseGet (Поставщик <? Расширяет T> другое)
Возвращает значение, если оно присутствует, в противном случае вызывает other и возвращает результат этого вызова.
<X extends Throwable> T orElseThrow (Поставщик <? Extends X> exceptionSupplier)
Возвращает содержащееся значение, если оно присутствует, в противном случае генерируется исключение, которое будет создано предоставленным поставщиком.
Строка toString ()
Возвращает непустое строковое представление этого Optional, подходящего для отладки.
Этот класс наследует методы из следующего класса —
- java.lang.Object
Необязательный пример
Создайте следующую Java-программу, используя любой редактор по вашему выбору, например, в C: \> JAVA.
Java8Tester.java
import java.util.Optional; public class Java8Tester { public static void main(String args[]) { Java8Tester java8Tester = new Java8Tester(); Integer value1 = null; Integer value2 = new Integer(10); //Optional.ofNullable - allows passed parameter to be null. Optional<Integer> a = Optional.ofNullable(value1); //Optional.of - throws NullPointerException if passed parameter is null Optional<Integer> b = Optional.of(value2); System.out.println(java8Tester.sum(a,b)); } public Integer sum(Optional<Integer> a, Optional<Integer> b) { //Optional.isPresent - checks the value is present or not System.out.println("First parameter is present: " + a.isPresent()); System.out.println("Second parameter is present: " + b.isPresent()); //Optional.orElse - returns the value if present otherwise returns //the default value passed. Integer value1 = a.orElse(new Integer(0)); //Optional.get - gets the value, value should be present Integer value2 = b.get(); return value1 + value2; } }
Проверьте результат
Скомпилируйте класс с помощью компилятора javac следующим образом:
C:\JAVA>javac Java8Tester.java
Теперь запустите Java8Tester следующим образом —
C:\JAVA>java Java8Tester
Он должен произвести следующий вывод —
First parameter is present: false Second parameter is present: true 10
Java 8 — Нашорн JavaScript
В Java 8, Nashorn, представлен значительно улучшенный движок javascript для замены существующего Rhino. Nashorn обеспечивает в 2-10 раз лучшую производительность, так как он напрямую компилирует код в памяти и передает байт-код в JVM. Nashorn использует функцию динамического вызова, представленную в Java 7, для повышения производительности.
JJS
Для движка Nashorn JAVA 8 представляет новый инструмент командной строки, jjs, для выполнения JavaScript-кодов на консоли.
Интерпретация файла JS
Создайте и сохраните файл sample.js в папке c: \> JAVA.
sample.js
print('Hello World!');
Откройте консоль и используйте следующую команду.
C:\JAVA>jjs sample.js
Он выдаст следующий вывод:
Hello World!
JJS в интерактивном режиме
Откройте консоль и используйте следующую команду.
C:\JAVA>jjs jjs> print("Hello, World!") Hello, World! jjs> quit() >>
Передать аргументы
Откройте консоль и используйте следующую команду.
C:\JAVA> jjs -- a b c jjs> print('letters: ' +arguments.join(", ")) letters: a, b, c jjs>
Вызов JavaScript из Java
Используя ScriptEngineManager, код JavaScript можно вызывать и интерпретировать в Java.
пример
Создайте следующую Java-программу, используя любой редактор по вашему выбору, например, в C: \> JAVA.
Java8Tester.java
import javax.script.ScriptEngineManager; import javax.script.ScriptEngine; import javax.script.ScriptException; public class Java8Tester { public static void main(String args[]) { ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); ScriptEngine nashorn = scriptEngineManager.getEngineByName("nashorn"); String name = "Mahesh"; Integer result = null; try { nashorn.eval("print('" + name + "')"); result = (Integer) nashorn.eval("10 + 2"); } catch(ScriptException e) { System.out.println("Error executing script: "+ e.getMessage()); } System.out.println(result.toString()); } }
Проверьте результат
Скомпилируйте класс с помощью компилятора javac следующим образом:
C:\JAVA>javac Java8Tester.java
Теперь запустите Java8Tester следующим образом —
C:\JAVA>java Java8Tester
Это должно привести к следующему результату —
Mahesh 12
Вызов Java из JavaScript
В следующем примере объясняется, как импортировать и использовать классы Java в сценарии Java.
Создайте и сохраните sample.js в папке C: \> JAVA.
sample.js
var BigDecimal = Java.type('java.math.BigDecimal'); function calculate(amount, percentage) { var result = new BigDecimal(amount).multiply(new BigDecimal(percentage)).divide( new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_EVEN); return result.toPlainString(); } var result = calculate(568000000000000000023,13.9); print(result);
Откройте консоль и используйте следующую команду.
C:\JAVA>jjs sample.js
Он должен произвести следующий вывод —
78952000000000000003.20
Java 8 — новый API даты / времени
В Java 8 введен новый API Date-Time, чтобы покрыть следующие недостатки старого API даты и времени.
-
Не потокобезопасен — java.util.Date не является потокобезопасным, поэтому разработчикам приходится иметь дело с проблемой параллелизма при использовании даты. Новый API даты и времени является неизменным и не имеет методов установки.
-
Плохой дизайн — Дата по умолчанию начинается с 1900, месяц начинается с 1, а день начинается с 0, поэтому единообразия нет. У старого API были менее прямые методы для операций с датами. Новый API предоставляет множество вспомогательных методов для таких операций.
-
Сложная обработка часового пояса — разработчикам пришлось написать много кода для решения проблем с часовым поясом . Новый API был разработан с учетом специфики предметной области.
Не потокобезопасен — java.util.Date не является потокобезопасным, поэтому разработчикам приходится иметь дело с проблемой параллелизма при использовании даты. Новый API даты и времени является неизменным и не имеет методов установки.
Плохой дизайн — Дата по умолчанию начинается с 1900, месяц начинается с 1, а день начинается с 0, поэтому единообразия нет. У старого API были менее прямые методы для операций с датами. Новый API предоставляет множество вспомогательных методов для таких операций.
Сложная обработка часового пояса — разработчикам пришлось написать много кода для решения проблем с часовым поясом . Новый API был разработан с учетом специфики предметной области.
Java 8 представляет новый API даты и времени в пакете java.time. Ниже приведены некоторые важные классы, представленные в пакете java.time.
-
Локальный — упрощенный API даты и времени без сложности обработки часового пояса.
-
Zoned — специализированный API даты и времени для работы с различными часовыми поясами.
Локальный — упрощенный API даты и времени без сложности обработки часового пояса.
Zoned — специализированный API даты и времени для работы с различными часовыми поясами.
Локальный API даты и времени
Классы LocalDate / LocalTime и LocalDateTime упрощают разработку, где часовые пояса не требуются. Давайте посмотрим на них в действии.
Создайте следующую Java-программу, используя любой редактор на ваш выбор, скажем, C: \> JAVA.
Java8Tester.java
import java.time.LocalDate; import java.time.LocalTime; import java.time.LocalDateTime; import java.time.Month; public class Java8Tester { public static void main(String args[]) { Java8Tester java8tester = new Java8Tester(); java8tester.testLocalDateTime(); } public void testLocalDateTime() { // Get the current date and time LocalDateTime currentTime = LocalDateTime.now(); System.out.println("Current DateTime: " + currentTime); LocalDate date1 = currentTime.toLocalDate(); System.out.println("date1: " + date1); Month month = currentTime.getMonth(); int day = currentTime.getDayOfMonth(); int seconds = currentTime.getSecond(); System.out.println("Month: " + month +"day: " + day +"seconds: " + seconds); LocalDateTime date2 = currentTime.withDayOfMonth(10).withYear(2012); System.out.println("date2: " + date2); //12 december 2014 LocalDate date3 = LocalDate.of(2014, Month.DECEMBER, 12); System.out.println("date3: " + date3); //22 hour 15 minutes LocalTime date4 = LocalTime.of(22, 15); System.out.println("date4: " + date4); //parse a string LocalTime date5 = LocalTime.parse("20:15:30"); System.out.println("date5: " + date5); } }
Проверьте результат
Скомпилируйте класс с помощью компилятора javac следующим образом:
C:\JAVA>javac Java8Tester.java
Теперь запустите Java8Tester следующим образом —
C:\JAVA>java Java8Tester
Он должен произвести следующий вывод —
Current DateTime: 2014-12-09T11:00:45.457 date1: 2014-12-09 Month: DECEMBERday: 9seconds: 45 date2: 2012-12-10T11:00:45.457 date3: 2014-12-12 date4: 22:15 date5: 20:15:30
API зонированной даты и времени
Зональный API даты и времени должен использоваться при рассмотрении часового пояса. Давайте посмотрим на них в действии.
Создайте следующую Java-программу, используя любой редактор по вашему выбору, например, в C: \> JAVA.
Java8Tester.java
import java.time.ZonedDateTime; import java.time.ZoneId; public class Java8Tester { public static void main(String args[]) { Java8Tester java8tester = new Java8Tester(); java8tester.testZonedDateTime(); } public void testZonedDateTime() { // Get the current date and time ZonedDateTime date1 = ZonedDateTime.parse("2007-12-03T10:15:30+05:30[Asia/Karachi]"); System.out.println("date1: " + date1); ZoneId id = ZoneId.of("Europe/Paris"); System.out.println("ZoneId: " + id); ZoneId currentZone = ZoneId.systemDefault(); System.out.println("CurrentZone: " + currentZone); } }
Проверьте результат
Скомпилируйте класс с помощью компилятора javac следующим образом:
C:\JAVA>javac Java8Tester.java
Теперь запустите Java8Tester следующим образом —
C:\JAVA>java Java8Tester
Он должен произвести следующий вывод —
date1: 2007-12-03T10:15:30+05:00[Asia/Karachi] ZoneId: Europe/Paris CurrentZone: Etc/UTC
Единицы Chrono Enum
Перечисление java.time.temporal.ChronoUnit добавлено в Java 8, чтобы заменить целочисленные значения, используемые в старом API для представления дня, месяца и т. д. Давайте посмотрим на них в действии.
Создайте следующую Java-программу, используя любой редактор по вашему выбору, например, в C: \> JAVA.
Java8Tester.java
import java.time.LocalDate; import java.time.temporal.ChronoUnit; public class Java8Tester { public static void main(String args[]) { Java8Tester java8tester = new Java8Tester(); java8tester.testChromoUnits(); } public void testChromoUnits() { //Get the current date LocalDate today = LocalDate.now(); System.out.println("Current date: " + today); //add 1 week to the current date LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS); System.out.println("Next week: " + nextWeek); //add 1 month to the current date LocalDate nextMonth = today.plus(1, ChronoUnit.MONTHS); System.out.println("Next month: " + nextMonth); //add 1 year to the current date LocalDate nextYear = today.plus(1, ChronoUnit.YEARS); System.out.println("Next year: " + nextYear); //add 10 years to the current date LocalDate nextDecade = today.plus(1, ChronoUnit.DECADES); System.out.println("Date after ten year: " + nextDecade); } }
Проверьте результат
Скомпилируйте класс с помощью компилятора javac следующим образом:
C:\JAVA>javac Java8Tester.java
Теперь запустите Java8Tester следующим образом —
C:\JAVA>java Java8Tester
Это должно привести к следующему результату —
Current date: 2014-12-10 Next week: 2014-12-17 Next month: 2015-01-10 Next year: 2015-12-10 Date after ten year: 2024-12-10
Период и продолжительность
В Java 8 введены два специализированных класса для работы с разницей во времени.
-
Период — имеет дело с датой на основе времени.
-
Продолжительность — имеет дело с количеством времени на основе времени.
Период — имеет дело с датой на основе времени.
Продолжительность — имеет дело с количеством времени на основе времени.
Давайте посмотрим на них в действии.
Создайте следующую Java-программу, используя любой редактор по вашему выбору, например, в C: \> JAVA.
Java8Tester.java
import java.time.temporal.ChronoUnit; import java.time.LocalDate; import java.time.LocalTime; import java.time.Duration; import java.time.Period; public class Java8Tester { public static void main(String args[]) { Java8Tester java8tester = new Java8Tester(); java8tester.testPeriod(); java8tester.testDuration(); } public void testPeriod() { //Get the current date LocalDate date1 = LocalDate.now(); System.out.println("Current date: " + date1); //add 1 month to the current date LocalDate date2 = date1.plus(1, ChronoUnit.MONTHS); System.out.println("Next month: " + date2); Period period = Period.between(date2, date1); System.out.println("Period: " + period); } public void testDuration() { LocalTime time1 = LocalTime.now(); Duration twoHours = Duration.ofHours(2); LocalTime time2 = time1.plus(twoHours); Duration duration = Duration.between(time1, time2); System.out.println("Duration: " + duration); } }
Проверьте результат
Скомпилируйте класс с помощью компилятора javac следующим образом:
C:\JAVA>javac Java8Tester.java
Теперь запустите Java8Tester следующим образом —
C:\JAVA>java Java8Tester
Он должен произвести следующий вывод —
Current date: 2014-12-10 Next month: 2015-01-10 Period: P-1M Duration: PT2H
Временные Настройщики
TemporalAdjuster используется для выполнения математики даты. Например, получите «Вторая суббота месяца» или «Следующий вторник». Давайте посмотрим на них в действии.
Создайте следующую Java-программу, используя любой редактор по вашему выбору, например, в C: \> JAVA.
Java8Tester.java
import java.time.LocalDate; import java.time.temporal.TemporalAdjusters; import java.time.DayOfWeek; public class Java8Tester { public static void main(String args[]) { Java8Tester java8tester = new Java8Tester(); java8tester.testAdjusters(); } public void testAdjusters() { //Get the current date LocalDate date1 = LocalDate.now(); System.out.println("Current date: " + date1); //get the next tuesday LocalDate nextTuesday = date1.with(TemporalAdjusters.next(DayOfWeek.TUESDAY)); System.out.println("Next Tuesday on : " + nextTuesday); //get the second saturday of next month LocalDate firstInYear = LocalDate.of(date1.getYear(),date1.getMonth(), 1); LocalDate secondSaturday = firstInYear.with(TemporalAdjusters.nextOrSame( DayOfWeek.SATURDAY)).with(TemporalAdjusters.next(DayOfWeek.SATURDAY)); System.out.println("Second Saturday on : " + secondSaturday); } }
Проверьте результат
Скомпилируйте класс с помощью компилятора javac следующим образом:
C:\JAVA>javac Java8Tester.java
Теперь запустите Java8Tester следующим образом —
C:\JAVA>java Java8Tester
Это должно привести к следующему результату —
Current date: 2014-12-10 Next Tuesday on : 2014-12-16 Second Saturday on : 2014-12-13
Обратная совместимость
Метод toInstant () добавляется к исходным объектам Date и Calendar, которые можно использовать для преобразования их в новый API Date-Time. Используйте метод ofInstant (Insant, ZoneId), чтобы получить объект LocalDateTime или ZonedDateTime. Давайте посмотрим на них в действии.
Создайте следующую Java-программу, используя любой редактор по вашему выбору, например, в C: \> JAVA.
Java8Tester.java
import java.time.LocalDateTime; import java.time.ZonedDateTime; import java.util.Date; import java.time.Instant; import java.time.ZoneId; public class Java8Tester { public static void main(String args[]) { Java8Tester java8tester = new Java8Tester(); java8tester.testBackwardCompatability(); } public void testBackwardCompatability() { //Get the current date Date currentDate = new Date(); System.out.println("Current date: " + currentDate); //Get the instant of current date in terms of milliseconds Instant now = currentDate.toInstant(); ZoneId currentZone = ZoneId.systemDefault(); LocalDateTime localDateTime = LocalDateTime.ofInstant(now, currentZone); System.out.println("Local date: " + localDateTime); ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(now, currentZone); System.out.println("Zoned date: " + zonedDateTime); } }
Проверьте результат
Скомпилируйте класс с помощью компилятора javac следующим образом:
C:\JAVA>javac Java8Tester.java
Теперь запустите Java8Tester следующим образом —
C:\JAVA>java Java8Tester
Он должен произвести следующий вывод —
Current date: Wed Dec 10 05:44:06 UTC 2014 Local date: 2014-12-10T05:44:06.635 Zoned date: 2014-12-10T05:44:06.635Z[Etc/UTC]
Java 8 — Base64
С Java 8, Base64 наконец-то получил свое. Java 8 теперь имеет встроенный кодер и декодер для кодирования Base64. В Java 8 мы можем использовать три типа кодировки Base64.
-
Простой — вывод сопоставляется с набором символов, лежащих в A-Za-z0-9 + /. Кодер не добавляет какой-либо перевод строки в вывод, а декодер отклоняет любой символ, кроме A-Za-z0-9 + /.
-
URL — вывод сопоставляется с набором символов, лежащих в A-Za-z0-9 + _. Вывод URL и имя файла безопасны.
-
MIME — Выходные данные отображаются в формате MIME. Вывод представлен в строках длиной не более 76 символов и использует возврат каретки ‘\ r’, за которым следует перевод строки \ n в качестве разделителя строк. В конце закодированного вывода отсутствует разделитель строк.
Простой — вывод сопоставляется с набором символов, лежащих в A-Za-z0-9 + /. Кодер не добавляет какой-либо перевод строки в вывод, а декодер отклоняет любой символ, кроме A-Za-z0-9 + /.
URL — вывод сопоставляется с набором символов, лежащих в A-Za-z0-9 + _. Вывод URL и имя файла безопасны.
MIME — Выходные данные отображаются в формате MIME. Вывод представлен в строках длиной не более 76 символов и использует возврат каретки ‘\ r’, за которым следует перевод строки \ n в качестве разделителя строк. В конце закодированного вывода отсутствует разделитель строк.
Вложенные классы
Sr.No. | Вложенный класс и описание |
---|---|
1 |
статический класс Base64. Декодер Этот класс реализует декодер для декодирования байтовых данных с использованием схемы кодирования Base64, как указано в RFC 4648 и RFC 2045. |
2 |
статический класс Base64.Encoder Этот класс реализует кодер для кодирования байтовых данных с использованием схемы кодирования Base64, как указано в RFC 4648 и RFC 2045. |
статический класс Base64. Декодер
Этот класс реализует декодер для декодирования байтовых данных с использованием схемы кодирования Base64, как указано в RFC 4648 и RFC 2045.
статический класс Base64.Encoder
Этот класс реализует кодер для кодирования байтовых данных с использованием схемы кодирования Base64, как указано в RFC 4648 и RFC 2045.
методы
Sr.No. | Название и описание метода |
---|---|
1 |
статический Base64.Decoder getDecoder () Возвращает Base64.Decoder, который декодирует, используя схему кодирования base64 типа Basic. |
2 |
статический Base64.Encoder getEncoder () Возвращает Base64.Encoder, который кодирует, используя схему кодирования base64 типа Basic. |
3 |
статический Base64.Decoder getMimeDecoder () Возвращает Base64.Decoder, который декодирует, используя схему декодирования base64 MIME-типа. |
4 |
статический Base64.Encoder getMimeEncoder () Возвращает Base64.Encoder, который кодирует, используя схему кодирования base64 MIME-типа. |
5 |
статический Base64.Encoder getMimeEncoder (int lineLength, byte [] lineSeparator) Возвращает Base64.Encoder, который кодирует с использованием схемы кодирования base64 MIME-типа с заданной длиной строки и разделителями строк. |
6 |
статический Base64.Decoder getUrlDecoder () Возвращает Base64.Decoder, который декодирует с использованием схемы кодировки base64 URL и безопасного имени файла. |
7 |
статический Base64.Encoder getUrlEncoder () Возвращает Base64.Encoder, который кодирует с использованием схемы кодирования base64 безопасного URL-адреса и имени файла. |
статический Base64.Decoder getDecoder ()
Возвращает Base64.Decoder, который декодирует, используя схему кодирования base64 типа Basic.
статический Base64.Encoder getEncoder ()
Возвращает Base64.Encoder, который кодирует, используя схему кодирования base64 типа Basic.
статический Base64.Decoder getMimeDecoder ()
Возвращает Base64.Decoder, который декодирует, используя схему декодирования base64 MIME-типа.
статический Base64.Encoder getMimeEncoder ()
Возвращает Base64.Encoder, который кодирует, используя схему кодирования base64 MIME-типа.
статический Base64.Encoder getMimeEncoder (int lineLength, byte [] lineSeparator)
Возвращает Base64.Encoder, который кодирует с использованием схемы кодирования base64 MIME-типа с заданной длиной строки и разделителями строк.
статический Base64.Decoder getUrlDecoder ()
Возвращает Base64.Decoder, который декодирует с использованием схемы кодировки base64 URL и безопасного имени файла.
статический Base64.Encoder getUrlEncoder ()
Возвращает Base64.Encoder, который кодирует с использованием схемы кодирования base64 безопасного URL-адреса и имени файла.
Унаследованные методы
Этот класс наследует методы из следующего класса —
- java.lang.Object
Пример Base64
Создайте следующую Java-программу, используя любой редактор по вашему выбору, например, C: /> JAVA.
Java8Tester.java
import java.util.Base64; import java.util.UUID; import java.io.UnsupportedEncodingException; public class HelloWorld { public static void main(String args[]) { try { // Encode using basic encoder String base64encodedString = Base64.getEncoder().encodeToString( "TutorialsPoint?java8".getBytes("utf-8")); System.out.println("Base64 Encoded String (Basic) :" + base64encodedString); // Decode byte[] base64decodedBytes = Base64.getDecoder().decode(base64encodedString); System.out.println("Original String: " + new String(base64decodedBytes, "utf-8")); base64encodedString = Base64.getUrlEncoder().encodeToString( "TutorialsPoint?java8".getBytes("utf-8")); System.out.println("Base64 Encoded String (URL) :" + base64encodedString); StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < 10; ++i) { stringBuilder.append(UUID.randomUUID().toString()); } byte[] mimeBytes = stringBuilder.toString().getBytes("utf-8"); String mimeEncodedString = Base64.getMimeEncoder().encodeToString(mimeBytes); System.out.println("Base64 Encoded String (MIME) :" + mimeEncodedString); } catch(UnsupportedEncodingException e) { System.out.println("Error :" + e.getMessage()); } } }
Проверьте результат
Скомпилируйте класс с помощью компилятора javac следующим образом:
C:\JAVA>javac Java8Tester.java
Теперь запустите Java8Tester следующим образом —
C:\JAVA>java Java8Tester
Он должен произвести следующий вывод —