Резюме использования Java8

Java

Корпорация Oracle выпустила Java 8 18 марта 2014 года, которая предоставляет больше инструментов и концепций программирования для более быстрого и, что более важно, более лаконичного и удобного в сопровождении решения новых или существующих проблем. В этой статье в основном обобщаются концепции и использование потоковой обработки, лямбда-выражений и необязательных классов, в надежде помочь повысить эффективность разработки и уменьшить сложность кода.

потоковая обработка

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

Типичным примером является операция конвейера в системах Unix. Вывод одной команды может быть передан как ввод другой команды. Сложные функции могут быть выполнены с помощью коротких команд.

Например, следующая короткая строка команд реализует логику обработки чтения файлов, преобразования строчных букв, сортировки по словарю и получения последних трех букв.

cat file1 file2 | tr "[A-Z]"  "[a-z]"  |  sort  |  tail -3`
Работа трубопровода.png

структура

Потоки могут быть построены следующими распространенными способами:

Stream stream=Stream.of("H","E","L","L","O");

String [] strArray=new String[]{"H","E","L","L","O"};
stream=Stream.of(strArray);
stream=Arrays.stream(strArray);

List<String> list=Arrays.asList(strArray);
stream=list.stream();

действовать

Промежуточные операции: сопоставление, фильтрация, различение, сортировка, просмотр, ограничение, пропуск, параллельная, последовательная, неупорядоченная Терминальные операции: forEach, forEachOrdered, toArray, reduce, collect, min, max, count, anyMatch, allMatch, noneMatch, findFirst, findAny , итератор

пример

map

Операция карты может изменить содержимое или тип объекта, генерируя отображение один к одному, где каждый входной элемент преобразуется в другой элемент в соответствии с правилами. Например, преобразовать прописные буквы в строчные.

Java7

List<String> wordList=Arrays.asList("H","E","L","L","O");
List<String> outputList=new ArrayList<String>();
for(String word:wordList){
    outputList.add(word.toLowerCase());
}

Java8

List<String> wordList=Arrays.asList("H","E","L","L","O");
List<String> outputList=wordList.stream().map(String::toLowerCase).collect(Collectors.toList());
flatmap

flatmap обеспечивает сопоставление отношений «один ко многим».

List<String> hiList = Arrays.asList("hello", "hi", "你好");
List<String> nameList = Arrays.asList("Ted", "Bobo", "Alice");
hiList.stream().flatMap(hi -> nameList.stream().map(name -> hi + " " + name)).collect(Collectors.toList()).forEach(System.out::println);
filter

Фильтр дает тест для исходного потока, который остается для генерации нового потока через тестовый элемент.

Java7

Integer[] nums={0,1,2,3,4,5,6,7,8,9};
List<Integer> oddNums=new ArrayList<Integer>(); 
for(Integer num:nums){
    if((num&1)==1){
        oddNums.add(num);
    }
}

Java8

Integer[] nums={0,1,2,3,4,5,6,7,8,9};
List<Integer> oddNums= Stream.of(nums).filter(n->(n&1)==1).collect(Collectors.toList());
foreach

Метод forEach принимает лямбда-выражение и выполняет его для каждого элемента потока.

Java7

List<String> nameList = Arrays.asList("Ted", "Bobo", "Alice");
for(String name:nameList){
    System.out.println(name);
}

Java8

List<String> nameList = Arrays.asList("Ted", "Bobo", "Alice");
nameList.stream().forEach(System.out::println);
max

max находит наибольшее число.

Java7

List<String> nameList = Arrays.asList("Ted", "Bobo", "Alice");
Integer maxLen=Integer.MIN_VALUE;
for(String name:nameList){
    if(maxLen.compareTo(name.length())<0){
        maxLen=name.length();
    }
}

Java8

List<String> nameList = Arrays.asList("Ted", "Bobo", "Alice");
nameList.stream().mapToInt(String::length).max();

Лямбда-выражения

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

  • функция. Лямбда-функции не принадлежат к определенному классу, как это делают методы. Но, как и у методов, есть список параметров, тело функции, тип возвращаемого значения и, возможно, список исключений, которые могут быть выброшены.

  • передача. Лямбда-выражения можно передавать в качестве параметров методам или хранить в переменных.

  • краткий Не нужно писать много шаблонов, как анонимные классы.

Лямбда структура.png

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

Функциональный интерфейс — это интерфейс, определяющий только один абстрактный метод.

public interface Comparator<T>{
     int compare(T o1,T o2);
}

пример

Java7

List<String> nameList = Arrays.asList("Ted", "Bobo", "Alice");
nameList.sort(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o1.compareTo(o2);
    }
});

Java8

List<String> nameList = Arrays.asList("Ted", "Bobo", "Alice");
nameList.sort((String o1,String o2)->o1.compareTo(o2));

Необязательный класс

Основная проблема, которую решает класс Optional, — печально известное исключение NullPointerException.

По сути, необязательно - это класс обертки, который содержит необязательные значения, что означает, что дополнительный класс может либо содержать объекты, либо быть пустым.

структура

объявить пустой необязательный

Optional<Car> optCar=Optional.empty();

Создать необязательное значение из ненулевого значения

Optional<Car> optCar=Optional.of(car);

Необязательный, который принимает null

Optional<Car> optCar=Optional.ofNullable(car);

метод

get()

Если переменная существует, она возвращает инкапсулированное значение переменной напрямую, в противном случае создается исключение NoSuchElementException.

orElse(T other)

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

orElseGet(Supplier<? extends T> other)

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

orElseThrow(Supplier<? extends X> exceptionSupplier)

Это позволяет вам генерировать указанное исключение, если необязательный объект не содержит значения

ifPresent(Consumer<? super T>)

Выполняет метод, переданный в качестве параметра, если значение переменной существует, в противном случае ничего не делает.

пример

Java7

public static String getName(User u) {
    if (u == null)
        return "Unknown";
    return u.name;
}

Java8

public static String getName(User u) {
    return Optional.ofNullable(u)
                    .map(user->user.name)
                    .orElse("Unknown");
}

использованная литература

  1. "Java8 бой"
  2. Woohoo. IBM.com/developer Я…