В этой статье я указал и обсудил пять особенностей Java 8, которые кажутся мне более интересными.

  • Трансляция и другие специальные функции
  • Лямбда-выражения
  • Параллельные операции
  • движок JavaScript
  • Новые API даты/времени

  • Трансляция и другие специальные функции

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

List<String> myList =    Arrays.asList("a1", "a2", "b1", "c2", "c1");
myList
    .stream()
    .filter(s -> s.startsWith("c"))
    .map(String::toUpperCase)
    .sorted()
    .forEach(System.out::println);      // C1 C2

-Потоковые операции бывают промежуточными или терминальными. Промежуточные операции возвращают поток, поэтому мы можем объединить несколько промежуточных операций без использования точки с запятой. Терминальные операции либо недействительны, либо возвращают непотоковые результаты. В приведенном выше примере filter, map и sorted являются промежуточными операциями, тогда как forEach — терминальной операцией.

Разные виды потоков
Потоки можно создавать из различных источников данных, особенно коллекций. Списки и наборы поддерживают новые методы stream() и parallelStream() для создания последовательного или параллельного потока.

//Prepare stream from collection
List<String> myList = Arrays.asList("a1", "a2", "b1", "c2", "c1");
myList.stream()
//Create a stream from a bunch of object references
Stream.of("d2", "a2", "b1", "b3", "c")
//Primitive streams (IntStream,LongStream and DoubleStream)
IntStream.range(1, 4)

Другая особенность

Поддержка расширенных аннотаций
Можно аннотировать практически все: локальные переменные, универсальные типы, суперклассы и интерфейсы реализации, даже объявление исключений метода.

public class Annotations {
@Retention( RetentionPolicy.RUNTIME )
@Target( { ElementType.TYPE_USE, ElementType.TYPE_PARAMETER } )
public @interface NonEmpty {
}
public static class Holder< @NonEmpty T > extends @NonEmpty Object {
  public void method() throws @NonEmpty Exception {
  }
}
public static void main(String[] args) {
 final Holder< String > holder = new @NonEmpty Holder< String >();
 @NonEmpty Collection< @NonEmpty String > strings = new ArrayList<>();
 }
}

Внутренняя и внешняя итерация

Внешняя итерация (java7) - где коллекция должна быть реализована с помощью Iterable, чтобы итератор мог перечислять свои элементы, а клиенты использовали это для последовательного прохождения элементов коллекции.

List<String> alphabets = Arrays.asList(new String[]{"a","b","b","d"});
Iterator<String> iterator = alphabets.listIterator();
while(iterator.hasNext()){
System.out.println(iterator.next().toUpperCase());
}
for(String letter: alphabets){
System.out.println(letter.toUpperCase());
}

У внешних итераторов могут быть вещи для очистки (например, поток, переменная итератора)
Внутренняя итерация (java8):

alphabets.forEach(l -> l.toUpperCase());

Преимуществом внутреннего итератора является возможность реализации атомарной групповой операции над элементами коллекции.

Ссылки на методы

Ссылки на методы предоставляют полезный синтаксис для прямого обращения к существующим методам или конструкторам классов или объектов Java (экземпляров).

class Car {
public static Car create( final Supplier< Car > supplier ) {
return supplier.get();
}
public void running() {
System.out.println( "Repaired " + this.toString() );
}
}
        Car car = Car.create( Car::new );
        List< Car > cars = Arrays.asList( car );
        cars.forEach(Car::running);

Лямбда-выражения (,) –›{ ; }

Какими могут быть параметры метода?
java7: экземпляр любого класса, тип класса, переменная, константа, примитивы, объекты.
java8: функциональное выражение + параметры java7
Эти функциональные выражения мы назовем его лямбда-выражением.
Лямбда-выражения позволяют более компактно выражать экземпляры интерфейсов с одним методом (другое имя: функциональные интерфейсы).

@FunctionalInterface public interface Operation{
 public Object doOperation(Object param1,Object param2);
 }

Реализация вышеуказанного интерфейса может быть написана следующим образом:

Operation instance= (value1,value2) -> { return param1 + param2; }

Lambda может быть представлена ​​в виде списка параметров, разделенных запятыми–›, символа и тела.
Java 8 расширяет объявления интерфейса двумя новыми концепциями: методы по умолчанию и статические методы.
Методы интерфейса по умолчанию

@FunctionalInterface public interface FunctionalDefaultMethods {
        void method();
        default void defaultMethod() {
            System.out.println("Default implementation");
        }
    }

FunctionalDefaultMethods functionDefaultMethods=()-›{ System.out.println("моя реализация"); };

Статические методы интерфейса

@FunctionalInterface
public interface FunctionalStaticMethods {
void method();
static void defaultMethod() {
System.out.println("Default implementation");
}
}

FunctionalStaticMethods functionStaticMethods=()-›{ System.out.println("моя реализация"); };

Параллелизм

В версии Java 8 добавлено множество новых методов, позволяющих обрабатывать параллельные массивы. Возможно, самым важным из них является parallelSort(), который может значительно ускорить сортировку на многоядерных машинах.

long[] arrayOfLong = new long [ 20000 ];
Arrays.parallelSetAll( arrayOfLong,
index -> ThreadLocalRandom.current().nextInt( 1000000 ) );
Arrays.stream( arrayOfLong ).limit( 10 ).forEach(
i -> System.out.print( i + " " ) );
Arrays.parallelSort( arrayOfLong );
Arrays.stream( arrayOfLong ).limit( 10 ).forEach(
i -> System.out.print( i + " " ) );

* метод parallelSetAll() для заполнения массивов 20000 случайных значений. После этого применяется parallelSort(). Программа выводит первые 10 элементов до и после сортировки, чтобы убедиться, что массив действительно упорядочен.

Параллелизм в коллекции

List<String> myList={..}
myList.parallelStream().<operation>
myList.stream().parallel()
IntStream.range(1,20000).parallel().filter( this::isPrime).count()

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

Общий пул ForkJoinPool = ForkJoinPool.commonPool();

движок Nashorn JavaScript

Java 8 поставляется с новым движком Nashorn JavaScript, который позволяет разрабатывать и запускать определенные виды приложений JavaScript на JVM. Движок Nashorn JavaScript — это просто еще одна реализация javax. script.ScriptEngine и следует тому же набору правил, что обеспечивает совместимость Java и JavaScript.

jjs – это автономный движок Nashorn, работающий из командной строки. Он принимает список файлов исходного кода JavaScript в качестве аргументов и запускает их.

API даты/времени

Новый API Date-Time в Java 8 находился под сильным влиянием Joda-Time и взял от него лучшее. Новый пакет java.time содержит все классы для работы с датой, временем, датой/временем, часовыми поясами, моментами времени, длительностью и часами.

LocalDate date = LocalDate.now();
LocalTime time = LocalTime.now();
LocalDateTime datetime = LocalDateTime.now();
ZonedDateTime zonedDatetime = ZonedDateTime.now();   /*ZoneId.of( "America/Los_Angeles" )*/
dateObject.plusDays(10);
dateObject.minusWeeks(3);
//Parsing
LocalDateTime dt = LocalDateTime.parse("27::Apr::2014 21::39::48",
DateTimeFormatter.ofPattern("d::MMM::uuuu HH::mm::ss"));
//Formating
dt.format(DateTimeFormatter.ofPattern("d::MMM::uuuu HH::mm::ss");

нажмите здесь, чтобы получить образец проекта, который я разработал с помощью Netbeans 8.0.2. Этот пример проекта охватывает почти все темы в этом блоге.

Что дальше?

Конечно, Java 9 (надеюсь, в 2016 г.)

Читайте похожие статьи от Келено

Следите за нами в Linkedin

Посетите Келено| Фейсбук | Твиттер