← Назад к вопросам

Какие элементы функционального программирования появились в Java 8

2.0 Middle🔥 171 комментариев
#Stream API и функциональное программирование

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Функциональное программирование в Java 8

Java 8 в 2014 году революционизировал язык, добавив несколько ключевых элементов функционального программирования. Это был переломный момент для Java экосистемы.

Ключевые элементы

Lambda выражения Первый и самый очевидный элемент — это lambda выражения:

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

Runnable r = () -> System.out.println("Hello");

names.forEach(name -> System.out.println(name));

names.forEach(name -> {
    String upper = name.toUpperCase();
    System.out.println(upper);
});

Lambda синтаксис: (parameters) -> expression или (parameters) -> { statements }.

Functional Interfaces Lambda могут реализовывать только интерфейсы с одним абстрактным методом. Java 8 добавила встроенные функциональные интерфейсы:

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}

@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
}

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

Consumer<String> printer = name -> System.out.println(name);
Function<String, Integer> length = str -> str.length();
Predicate<Integer> isPositive = num -> num > 0;

Stream API Stream API — это самый мощный элемент Java 8. Это функциональный способ работы с коллекциями:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

int sum = numbers.stream()
    .filter(num -> num % 2 == 0)
    .map(num -> num * 2)
    .reduce(0, Integer::sum);

int sum = numbers.stream()
    .filter(num -> num % 2 == 0)
    .mapToInt(num -> num * 2)
    .sum();

Intermediate vs Terminal операции

List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");

Stream<String> filtered = names.stream()
    .filter(name -> name.length() > 3);

List<String> result = names.stream()
    .filter(name -> name.length() > 3)
    .collect(Collectors.toList());

long count = names.stream()
    .filter(name -> name.length() > 3)
    .count();

Method References Method reference — это краткий способ ссылаться на существующие методы:

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

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

Function<String, Integer> length = String::length;
Predicate<String> isEmpty = String::isEmpty;

Supplier<List<String>> listSupplier = ArrayList::new;
List<String> list = listSupplier.get();

Optional Optional — это контейнер, который может содержать null или значение:

String name = getName();
if (name != null && name.length() > 0) {
    System.out.println(name.toUpperCase());
}

Optional<String> name = Optional.ofNullable(getName());
name
    .filter(n -> n.length() > 0)
    .map(String::toUpperCase)
    .ifPresent(System.out::println);

Default методы в интерфейсах Java 8 позволяет добавлять методы с реализацией в интерфейсы:

public interface Animal {
    void eat();
    
    default void sleep() {
        System.out.println("Zzz");
    }
}

public class Dog implements Animal {
    @Override
    public void eat() {
        System.out.println("Eating");
    }
}

Примеры функционального подхода

Композиция функций

Function<Integer, Integer> addTwo = x -> x + 2;
Function<Integer, Integer> multiplyByThree = x -> x * 3;

Function<Integer, Integer> composed = addTwo.andThen(multiplyByThree);
System.out.println(composed.apply(5)); // 21

Parallel streams

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

int sum = numbers.stream()
    .filter(num -> num % 2 == 0)
    .mapToInt(num -> num * num)
    .sum();

int sumParallel = numbers.parallelStream()
    .filter(num -> num % 2 == 0)
    .mapToInt(num -> num * num)
    .sum();

Reduce для сложных операций

List<String> words = Arrays.asList("Hello", "World", "Java", "8");

String result = words.stream()
    .reduce("", (acc, word) -> acc + " " + word)
    .trim();

Map<String, Integer> wordLengths = words.stream()
    .collect(Collectors.toMap(
        word -> word,
        String::length
    ));

Практические рекомендации

Используй Stream API вместо for loops

List<Integer> evens = numbers.stream()
    .filter(n -> n % 2 == 0)
    .collect(Collectors.toList());

Будь осторожен с side effects в Stream

List<Integer> doubled = numbers.stream()
    .map(num -> num * 2)
    .collect(Collectors.toList());

Используй Optional правильно

Optional<String> opt = Optional.of("hello");
String value = opt.orElse("default");
opt.ifPresent(System.out::println);

Итого: Java 8 добавила lambda выражения, functional interfaces, Stream API, method references и Optional. Это коренным образом изменило то, как пишется Java код. Современный Java — это гибрид imperative и functional парадигм. Понимание этих концепций критично для разработчика Java 8+.

Какие элементы функционального программирования появились в Java 8 | PrepBro