Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> java

Java 8: Полное справочное руководство (Quick Reference)

Java 8 — Обзор

Java 8 — мажорный релиз языка Java, вышедший 18 марта 2014 года. Он принес поддержку функционального программирования, новый движок JavaScript (Nashorn), новые API для работы с датой/временем, Stream API и многое другое.

Ключевые новые возможности

Пример: Сортировка в Java 7 vs Java 8

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<>();
        names1.add("Mahesh ");
        names1.add("Suresh ");
        names1.add("Ramesh ");
        names1.add("Naresh ");
        names1.add("Kalpesh ");

        List<String> names2 = new ArrayList<>();
        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);
    }

    // Стиль 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);
            }
        });
    }

    // Стиль 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 SE бесплатно с официального сайта Oracle. Выберите версию под вашу ОС, запустите .exe и следуйте инструкциям. После установки настройте переменные окружения.

Windows (настройка PATH)

Предположим, Java установлена в c:\Program Files\java\jdk:

Linux/UNIX/Solaris/FreeBSD

Добавьте в .bashrc (или другой shell-конфиг):

export PATH=/path/to/java:$PATH

Популярные редакторы и IDE

Lambda-выражения в Java 8

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

Синтаксис

parameter -> expression body

Характеристики

Пример лямбд

public class Java8Tester {
    public static void main(String args[]) {
        Java8Tester tester = new Java8Tester();

        // С объявлением типа
        MathOperation addition = (int a, int b) -> a + b;
        // Без типа
        MathOperation subtraction = (a, b) -> a - b;
        // С return и скобками
        MathOperation multiplication = (int a, int b) -> { return a * b; };
        // Без return и скобок
        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));

        // Без скобок у параметра
        GreetingService greetService1 = message -> System.out.println("Hello " + message);
        // Со скобками
        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);
    }
}

Результат

10 + 5 = 15
10 - 5 = 5
10 x 5 = 50
10 / 5 = 2
Hello Mahesh
Hello Suresh

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

Область видимости (Scope)

Лямбда может ссылаться на final или effectively final переменные (присваиваемые только один раз). При повторном присваивании — ошибка компиляции.

Пример Scope

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); }
}

Вывод: Hello! Mahesh

Ссылки на методы (Method References)

Ссылки на методы позволяют ссылаться на методы по имени через символ ::. Поддерживаются:

Пример

import java.util.List;
import java.util.ArrayList;

public class Java8Tester {
    public static void main(String args[]) {
        List<String> names = new ArrayList<>();
        names.add("Mahesh");
        names.add("Suresh");
        names.add("Ramesh");
        names.add("Naresh");
        names.add("Kalpesh");

        names.forEach(System.out::println); // Статическая ссылка на метод
    }
}

Вывод: каждый элемент списка на новой строке.

Функциональные интерфейсы

Функциональный интерфейс — интерфейс с единственным абстрактным методом. Java 8 определяет множество таких интерфейсов в пакете java.util.function.

Список основных функциональных интерфейсов (нажмите для раскрытия)
№ Интерфейс и описание
1BiConsumer<T,U> — операция с двумя аргументами, без результата.
2BiFunction<T,U,R> — функция с двумя аргументами и результатом.
3BinaryOperator<T> — операция над двумя операндами одного типа.
4BiPredicate<T,U> — предикат с двумя аргументами.
5BooleanSupplier — поставщик boolean-значений.
6Consumer<T> — операция с одним аргументом, без результата.
7DoubleBinaryOperator — операция над двумя double.
8DoubleConsumer — операция с одним double.
9DoubleFunction<R> — функция от double к R.
10DoublePredicate — предикат для double.
11DoubleSupplier — поставщик double.
12DoubleToIntFunction — double → int.
13DoubleToLongFunction — double → long.
14DoubleUnaryOperator — унарная операция над double.
15Function<T,R> — функция T → R.
16IntBinaryOperator — операция над двумя int.
17IntConsumer — операция с одним int.
18IntFunction<R> — функция int → R.
19IntPredicate — предикат для int.
20IntSupplier — поставщик int.
21IntToDoubleFunction — int → double.
22IntToLongFunction — int → long.
23IntUnaryOperator — унарная операция над int.
24LongBinaryOperator — операция над двумя long.
25LongConsumer — операция с одним long.
26LongFunction<R> — функция long → R.
27LongPredicate — предикат для long.
28LongSupplier — поставщик long.
29LongToDoubleFunction — long → double.
30LongToIntFunction — long → int.
31LongUnaryOperator — унарная операция над long.
32ObjDoubleConsumer<T> — операция над объектом и double.
33ObjIntConsumer<T> — операция над объектом и int.
34ObjLongConsumer<T> — операция над объектом и long.
35Predicate<T> — предикат с одним аргументом.
36Supplier<T> — поставщик результатов.
37ToDoubleBiFunction<T,U> — (T,U) → double.
38ToDoubleFunction<T> — T → double.
39ToIntBiFunction<T,U> — (T,U) → int.
40ToIntFunction<T> — T → int.
41ToLongBiFunction<T,U> — (T,U) → long.
42ToLongFunction<T> — T → long.
43UnaryOperator<T> — унарная операция T → T.

Пример с Predicate

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);

        System.out.println("Print all numbers:");
        eval(list, n -> true);

        System.out.println("Print even numbers:");
        eval(list, n -> n % 2 == 0);

        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 + " ");
            }
        }
    }
}

Результат

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

Методы по умолчанию (Default Methods)

Java 8 позволяет добавлять реализацию методов в интерфейсы через ключевое слово default. Это сделано для обратной совместимости: старые интерфейсы (например, Collection) могут получить новые методы (forEach) без нарушения существующих реализаций.

Синтаксис

public interface Vehicle {
    default void print() {
        System.out.println("I am a vehicle!");
    }
}

Решение конфликтов множественных default-методов

Если класс реализует два интерфейса с одинаковым default-методом, нужно разрешить неоднозначность:

Вариант 1: Переопределить метод

public class Car implements Vehicle, FourWheeler {
    public void print() {
        System.out.println("I am a four wheeler car vehicle!");
    }
}

Вариант 2: Явный вызов через super

public class Car implements Vehicle, FourWheeler {
    public void print() {
        Vehicle.super.print();
    }
}

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

С Java 8 интерфейсы могут иметь статические helper-методы:

public interface Vehicle {
    default void print() { System.out.println("I am a vehicle!"); }
    static void blowHorn() { System.out.println("Blowing horn!!!"); }
}

Полный пример

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!");
    }
}

Результат

I am a vehicle!
I am a four wheeler!
Blowing horn!!!
I am a car!

Stream API

Stream — новый абстрактный слой в Java 8 для декларативной обработки данных (как SQL). Позволяет использовать многоядерные процессоры без явного параллельного кода.

Что такое Stream?

Создание стримов

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
List<String> filtered = strings.stream()
    .filter(s -> !s.isEmpty())
    .collect(Collectors.toList());

Основные операции

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);
List<Integer> squaresList = numbers.stream()
    .map(i -> i * i)
    .distinct()
    .collect(Collectors.toList());

filter

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
long count = strings.stream().filter(String::isEmpty).count();

limit

random.ints().limit(10).forEach(System.out::println);

sorted

random.ints().limit(10).sorted().forEach(System.out::println);

Parallel Processing

long count = strings.parallelStream().filter(String::isEmpty).count();

Collectors

List<String> filtered = strings.stream()
    .filter(s -> !s.isEmpty())
    .collect(Collectors.toList());

String mergedString = strings.stream()
    .filter(s -> !s.isEmpty())
    .collect(Collectors.joining(", "));

Statistics

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
IntSummaryStatistics stats = numbers.stream()
    .mapToInt(x -> x)
    .summaryStatistics();
System.out.println("Max: " + stats.getMax());
System.out.println("Min: " + stats.getMin());
System.out.println("Sum: " + stats.getSum());
System.out.println("Average: " + stats.getAverage());

Полный пример Stream API

import java.util.*;
import java.util.stream.Collectors;
import java.util.IntSummaryStatistics;

public class Java8Tester {
    public static void main(String args[]) {
        List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
        List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
        List<Integer> integers = Arrays.asList(1,2,13,4,15,6,17,8,19);

        // Java 7 style (omitted for brevity)
        System.out.println("Using Java 8:");

        long count = strings.stream().filter(String::isEmpty).count();
        System.out.println("Empty Strings: " + count);

        count = strings.stream().filter(s -> s.length() == 3).count();
        System.out.println("Strings of length 3: " + count);

        List<String> filtered = strings.stream()
            .filter(s -> !s.isEmpty())
            .collect(Collectors.toList());
        System.out.println("Filtered List: " + filtered);

        String merged = strings.stream()
            .filter(s -> !s.isEmpty())
            .collect(Collectors.joining(", "));
        System.out.println("Merged String: " + merged);

        List<Integer> squares = numbers.stream()
            .map(i -> i * i)
            .distinct()
            .collect(Collectors.toList());
        System.out.println("Squares List: " + squares);

        IntSummaryStatistics stats = integers.stream()
            .mapToInt(x -> x)
            .summaryStatistics();
        System.out.println("Max: " + stats.getMax());
        System.out.println("Min: " + stats.getMin());
        System.out.println("Sum: " + stats.getSum());
        System.out.println("Average: " + stats.getAverage());

        new Random().ints().limit(10).sorted().forEach(System.out::println);

        // Параллельная обработка
        count = strings.parallelStream().filter(String::isEmpty).count();
        System.out.println("Empty Strings (parallel): " + count);
    }
}

Результат показывает идентичные результаты для Java 7 и Java 8, но код Java 8 лаконичнее и декларативнее.

Optional Class (повторно)

Описание класса Optional дублируется из предыдущей статьи. См. статью Mastering Java 8 Optional.

Nashorn JavaScript (повторно)

Описание Nashorn дублируется из статьи Java 8 Nashorn.

New Date/Time API (повторно)

Описание нового Date/Time API дублируется из статьи Java 8 Date/Time API.

Base64 (повторно)

Описание Base64 дублируется из статьи Java 8 Base64.

java

  1. Понимание Java Vector: использование, особенности и сравнение с ArrayList
  2. Основы ЧПУ-фрезерования: краткий справочник профессионального оператора
  3. Мастерство профилактического и состояния-ориентированного обслуживания: практическое руководство по разра…
  4. Защитите свою цепь поставок: комплексные страховые стратегии
  5. Станки для гибки профильных труб: экспертное руководство
  6. Холодные прессы: полное руководство по эффективной металлоформовке
  7. Планетарный редуктор: компактность, высокий крутящий момент и снижение оборотов
  8. Сверлильно-фрезерный станок Jet: полное профессиональное руководство
  9. Сервопрессовые станки: принцип работы и преимущества над механическими прессами
  10. Профессиональное руководство по пневматическим цилиндрам: быстро и надежно