Какие элементы функционального программирования появились в Java 8
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Функциональное программирование в 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+.