Все нововведения java 8

Что Java 8 нам готовит

В Java 8 по-прежнему ничего не отбирают, но предлагают «декларативный» подход, значит, мы декларируем что мы хотим сделать, а всю механику — возлагаем на JVM.

 numbers.forEach(value -> System.out.println(value)); 

Заметим что в примере используется лямбда-выражение. О нем в следующем абзаце. Многие уже видели forEach во многих языках и библиотеках. Итак, forEach нам позволяет в одной строке выразить «вот тебе коллекция, примени-ка данное выражение ко всем ее элементам» (декларативный подход), а не «начиная с первого, и заканчивая последним, перебери один за другим и используй каждый элемент».

Теперь о лямбда выражениях.

Очень вкусное нововведение, позволяющее заменить анонимные классы на функции.

рассмотрим пример, уже приведенный выше:

 numbers.forEach(value -> System.out.println(value)); 

если бы не было ламбда-выражений, то даный пример выглядел бы так:

numbers.forEach(new Consumer() < @Override public void accept(Integer integer) < System.out.println(integer); >@Override public Consumer andThen(Consumer after) < return null; >>); 

Сложновато, не так ли. Но вернемся к простому однострочному выражению, и здесь все еще можно кое-что упростить: зачем нам упоминать value дважды, если и так ясно, что никакой другий переменной там быть не может.

numbers.forEach(System.out::println); 

Да-да, мы передали метод в качестве функции(*). Таким образом мы сказали: «вот тебе метод, примени его в цикле».

Вот еще пару примерчиков замены анонимных классов функциями:

new Thread(SomeClass::runSomething).start(); 

Сортировка с компаратором

Collections.sort(numbers, (o1, o2)-> o2.compareTo(o1)); 
Изменения в Collections Framework

Поразмявшись лямбда-выражениями, перейдем к новинкам в Collections Framework. Допустим, нам нужно посчитать сумму всех чисел в списке, умноженных на два. Недолго думая, мы создаем кусочек кода:

 List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); int sum = 0; for (int num : numbers)

Теперь обратимся к декларативному подходу:

int result = numbers.stream(). mapToInt(value->value*2). sum(); 

Постойте-ка, не map-reduce ли это? Он самый. Разберем по порядку. Итак mapToInt проводит map операцию, в результате которой элементы становятся умноженными на два. sum — это reduce преобразование, доступное лишь для целых чисел.

Допустим, поступил заказ модифицировать код и обрабатывать лишь четные, а нечетные отфильтровывать.

 System.out.println(numbers.stream(). filter(value -> value % 2 == 0). mapToInt(value -> value * 2). sum()); 

теперь наоборот, нечетные считать, а четные выбросить:

 System.out.println(numbers.stream(). filter(value -> value % 2 != 0). mapToInt(value -> value * 2). sum()); 
еще одна новая особенность языка

Мы привыкли что интерфейс нам говорит «что мы будем делать», но ничего не делает сам. В Java 8 интерфейс иногда что-то делает.

public interface IFly < public void takeOff(); public default void cruise() < System.out.println("IFly.cruise"); >; public void turn(); public void land(); > 

Кто программировал на С++ и читал Бьерна Стауструпа, тот задаст вопрос: «а как же diamond problem?». Вопрос интересный. И ответ есть.

Допустим, класс наследует два интерфейса, и в каждом из них есть default метод. При компиляции возникнет ошибка.

 public interface A < default void hello() < System.out.println("Hello World from A"); >> public interface B < default void hello() < System.out.println("Hello World from B"); >public class D implements A,B <> 

Разберем другой пример: треугольник

 public interface A < default void hello() < System.out.println("Hello World from A"); >> public interface B extends A < default void hello() < System.out.println("Hello World from B"); >> public class C implements B, A < public static void main(String. args) < new C().hello(); >> 

В данном случае победит ближайший в иерархии, то есть интерфейс B. Ну а если хочется использовать метод интерфейса А, то нужно явно указать

Разберем третий пример: есть конфликтующий метод у абстрактного класса и интерфейса. Правило — побеждает всегда класс.

  • если конфликт на одном уровне иерархии — компилятор не даст сему случиться
  • если на разных уровнях — победит ближайший
  • если интерфейс против класса — побеждает класс
Еще пару вкусняшек

Base64, как долго компилятор нам выдавал грозные сообщения об устаревшем sun.misc.Base64 и приходилось пользовать апачевские библиотеки для простой, казалось бы, вещи.
теперь вопрос решен: java.util.Base64

Base64.getEncoder().encode(new byte[]); 

Новый API по работе с датами и временами. Если кому не подуше старый добрый GregorianCallendar, то можете попробовать новые классы Clock, Time, LocalTime

 import java.time.LocalDate; import java.time.Period; . LocalDate time = LocalDate.now(); Period period = Period.ofDays(2); LocalDate newDate = time.plus(period); System.out.println("year:"+newDate.getYear()); System.out.println("month:"+newDate.getMonth()); System.out.println("day:"+newDate.getDayOfMonth()); 

Источник

Читайте также:  Восьмое задание егэ информатика питон
Оцените статью