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

Следишь ли за обновлениями Java

1.7 Middle🔥 181 комментариев
#Docker, Kubernetes и DevOps#JVM и управление памятью#ORM и Hibernate

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

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

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

Функция высшего порядка

Функция высшего порядка (Higher-Order Function, HOF) — это функция, которая принимает другие функции как аргументы или возвращает функцию как результат. Это мощный инструмент функционального программирования для написания универсального и переиспользуемого кода.

Основной принцип

Вместо того, чтобы писать разные функции для разных задач, пишем обобщённую функцию, которая принимает поведение как параметр:

# ❌ Без HOF: дублирование кода
def sum_numbers(numbers):
    total = 0
    for n in numbers:
        total += n
    return total

def multiply_numbers(numbers):
    total = 1
    for n in numbers:
        total *= n
    return total

def concatenate_strings(strings):
    result = ""
    for s in strings:
        result += s
    return result

# ✅ С HOF: одна универсальная функция
from functools import reduce
import operator

def fold(sequence, operation, initial):
    """Универсальная функция высшего порядка"""
    return reduce(operation, sequence, initial)

# Использование с разными функциями
sum_result = fold([1, 2, 3], operator.add, 0)  # 6
mult_result = fold([1, 2, 3], operator.mul, 1)  # 6
str_result = fold(['a', 'b', 'c'], operator.add, '')  # 'abc'

Тип 1: Функция принимает функцию как аргумент

Пример 1: map() — преобразование каждого элемента

def square(x):
    return x ** 2

def double(x):
    return x * 2

numbers = [1, 2, 3, 4]

# Функция высшего порядка map
result1 = list(map(square, numbers))  # [1, 4, 9, 16]
result2 = list(map(double, numbers))  # [2, 4, 6, 8]

# Или через lambda
result3 = list(map(lambda x: x ** 3, numbers))  # [1, 8, 27, 64]

Пример 2: filter() — фильтрация элементов

def is_even(x):
    return x % 2 == 0

def is_positive(x):
    return x > 0

numbers = [-2, -1, 0, 1, 2, 3, 4]

# filter принимает функцию-условие
even_nums = list(filter(is_even, numbers))  # [0, 2, 4]
pos_nums = list(filter(is_positive, numbers))  # [1, 2, 3, 4]

Пример 3: sorted() с ключом

students = [
    {'name': 'Alice', 'grade': 85},
    {'name': 'Bob', 'grade': 92},
    {'name': 'Charlie', 'grade': 78}
]

# Сортируем по разным ключам, используя HOF
by_grade = sorted(students, key=lambda s: s['grade'])
by_name = sorted(students, key=lambda s: s['name'])
by_grade_desc = sorted(students, key=lambda s: s['grade'], reverse=True)

Тип 2: Функция возвращает функцию

Пример 1: Функция-генератор функций

def make_multiplier(n):
    """Возвращает функцию, которая умножает на n"""
    def multiplier(x):
        return x * n
    return multiplier

# Создаём специализированные функции
multiply_by_2 = make_multiplier(2)
multiply_by_10 = make_multiplier(10)

print(multiply_by_2(5))  # 10
print(multiply_by_10(5))  # 50

Пример 2: Декоратор (самая практичная HOF)

def timer_decorator(func):
    """Возвращает функцию, которая профилирует время выполнения"""
    import time
    
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} выполнена за {end - start:.4f}с")
        return result
    
    return wrapper

# Используем декоратор
@timer_decorator
def slow_function():
    time.sleep(1)
    return "Done"

slow_function()  # "slow_function выполнена за 1.0001с"

Пример 3: Частичное применение (Currying)

from functools import partial

def multiply(a, b):
    return a * b

def add(a, b):
    return a + b

# Создаём специализированные функции через partial
add_10 = partial(add, 10)  # Фиксируем первый аргумент
multiply_by_5 = partial(multiply, 5)

print(add_10(5))  # 15
print(multiply_by_5(3))  # 15

Практические примеры

Пример 1: Валидатор-генератор

def make_validator(min_val, max_val):
    """Возвращает функцию для валидации чисел в диапазоне"""
    def validate(value):
        if not isinstance(value, (int, float)):
            return False
        return min_val <= value <= max_val
    return validate

# Создаём разные валидаторы
age_validator = make_validator(0, 150)
percentage_validator = make_validator(0, 100)

print(age_validator(25))  # True
print(age_validator(200))  # False
print(percentage_validator(85))  # True

Пример 2: Композиция функций

def compose(*functions):
    """Возвращает функцию, которая применяет все функции по порядку"""
    def composed(x):
        result = x
        for func in reversed(functions):
            result = func(result)
        return result
    return composed

def add_one(x):
    return x + 1

def double(x):
    return x * 2

def square(x):
    return x ** 2

# Комбинируем функции: (x+1)*2 затем ^2
transform = compose(square, double, add_one)

print(transform(3))  # ((3+1)*2)^2 = (4*2)^2 = 8^2 = 64

Пример 3: Pipeline обработки данных

def apply_pipeline(data, *transformers):
    """Применяет последовательность трансформаций"""
    result = data
    for transform in transformers:
        result = transform(result)
    return result

def clean_whitespace(text):
    return text.strip()

def to_lowercase(text):
    return text.lower()

def remove_punctuation(text):
    import string
    return text.translate(str.maketrans('', '', string.punctuation))

def split_words(text):
    return text.split()

# Pipeline
text = "  Hello, World!!!  "
words = apply_pipeline(
    text,
    clean_whitespace,
    to_lowercase,
    remove_punctuation,
    split_words
)

print(words)  # ['hello', 'world']

Встроенные HOF в Python

map, filter, reduce

from functools import reduce

numbers = [1, 2, 3, 4, 5]

# map: преобразование
squares = list(map(lambda x: x ** 2, numbers))  # [1, 4, 9, 16, 25]

# filter: фильтрация
evens = list(filter(lambda x: x % 2 == 0, numbers))  # [2, 4]

# reduce: свёртка в одно значение
total = reduce(lambda x, y: x + y, numbers)  # 15

sorted, min, max с ключом

data = [{'name': 'John', 'age': 30}, {'name': 'Jane', 'age': 25}]

# Все эти функции — HOF
oldest = max(data, key=lambda x: x['age'])
youngest = min(data, key=lambda x: x['age'])
sorted_by_name = sorted(data, key=lambda x: x['name'])

Лучшие практики

1. Используй встроенные HOF вместо циклов

# ❌ Плохо
result = []
for item in items:
    if item > 0:
        result.append(item * 2)

# ✅ Хорошо
result = list(map(lambda x: x * 2, filter(lambda x: x > 0, items)))

2. Создавай HOF для переиспользуемой логики

# ✅ Хорошо: одна функция для разных случаев
def apply_if(predicate, func):
    def wrapper(x):
        return func(x) if predicate(x) else x
    return wrapper

3. Предпочитай декораторы для внедрения функциональности

# Вместо обёртывания в коде
@log_execution
@validate_input
def my_function(x):
    pass

4. Используй typing для ясности

from typing import Callable, List

def apply_to_all(func: Callable[[int], int], items: List[int]) -> List[int]:
    return [func(item) for item in items]

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