☕ Java

Функции и рекурсия в Java 17: подробное руководство

Функции и рекурсия в Java

Введение: зачем нужны функции?

Представь, что ты пишешь программу для управления семейным бюджетом. Тебе нужно несколько раз складывать доходы от разных источников. Каждый раз писать одно и то же: int result = a + b; — это скучно и неудобно. А если ты ошибёшься в одном месте? Придётся исправлять везде.

Функции (или методы) — это как маленькие помощники. Ты один раз пишешь инструкцию, даёшь ей имя, а потом просто вызываешь её по имени, когда нужно. Это делает код короче, понятнее и безопаснее.

Рекурсия — это особый приём, когда функция вызывает саму себя. Звучит странно, но это очень помогает решать задачи, которые можно разбить на такие же, но более простые (например, перевернуть строку или пройтись по всем элементам списка).

Основной синтаксис функций в Java 17

Функция в Java выглядит так:

public static типВозврата имяФункции(тип параметр1, тип параметр2) {
    // тело функции — инструкции
    return результат; // если тип не void
}

Разберём по частям:

  • public static — пока просто запомни, что это нужно, чтобы функция работала. Дальше на курсе узнаешь подробнее.
  • типВозврата — что функция отдаст наружу: int (число), String (строка), double (дробное). Если ничего не отдаёт — пишем void.
  • имяФункции — придумай понятное имя: sum, max, reverse.
  • параметры — данные, которые функция получает на вход.
  • return — команда, которая возвращает результат.

Пример 1: Функция сложения (семейный бюджет)

import java.util.Scanner;

public class Main {
    // Функция, которая складывает два числа
    public static int sum(int a, int b) {
        return a + b;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Введи первый доход: ");
        int income1 = scanner.nextInt();
        System.out.print("Введи второй доход: ");
        int income2 = scanner.nextInt();

        int total = sum(income1, income2);
        System.out.println("Общая сумма доходов: " + total);
    }
}

Как это работает: Мы создали функцию sum. В main читаем два числа с клавиатуры, передаём их в функцию, а она возвращает сумму.

Пример 2: Функция сравнения температур

import java.util.Scanner;

public class Main {
    public static double findMax(double t1, double t2) {
        if (t1 > t2) {
            return t1;
        } else {
            return t2;
        }
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Введи первую температуру: ");
        double temp1 = scanner.nextDouble();
        System.out.print("Введи вторую температуру: ");
        double temp2 = scanner.nextDouble();

        double maxTemp = findMax(temp1, temp2);
        System.out.println("Большая температура: " + maxTemp);
    }
}

Здесь функция возвращает то число, которое больше.

Пример 3: Проверка чётности (коробки на фабрике)

import java.util.Scanner;

public class Main {
    public static boolean isEven(int number) {
        return number % 2 == 0; // true — чётное, false — нечётное
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Сколько коробок произведено? ");
        int boxes = scanner.nextInt();

        if (isEven(boxes)) {
            System.out.println("Количество коробок чётное, можно упаковывать в пары.");
        } else {
            System.out.println("Количество нечётное, нужна проверка.");
        }
    }
}

Рекурсия: функция вызывает саму себя

Рекурсия полезна, когда задача похожа сама на себя, но чуть меньше. Например, перевернуть строку: можно взять последний символ и приклеить его к перевёрнутой строке без последнего символа.

Пример 4: Реверс строки (рекурсия)

import java.util.Scanner;

public class Main {
    public static String reverse(String str) {
        // Базовый случай: если строка пустая или из одного символа — возвращаем её
        if (str == null || str.length() <= 1) {
            return str;
        }
        // Рекурсивный случай: последний символ + reverse(строка без последнего)
        return str.charAt(str.length() - 1) + reverse(str.substring(0, str.length() - 1));
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Введи строку: ");
        String text = scanner.nextLine();

        String reversed = reverse(text);
        System.out.println("Перевёрнутая строка: " + reversed);
    }
}

Как это работает: reverse("привет") → 'т' + reverse("приве") → 'т' + 'е' + reverse("прив") и так далее, пока строка не станет пустой.

Пример 5: Поиск минимального элемента в списке (рекурсия)

import java.util.Scanner;

public class Main {
    // Функция ищет минимум в массиве, начиная с индекса index
    public static int findMin(int[] arr, int index) {
        // Базовый случай: если дошли до последнего элемента — это и есть минимум
        if (index == arr.length - 1) {
            return arr[index];
        }
        // Находим минимум в оставшейся части
        int minOfRest = findMin(arr, index + 1);
        // Сравниваем текущий элемент с минимумом из остатка
        if (arr[index] < minOfRest) {
            return arr[index];
        } else {
            return minOfRest;
        }
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Сколько измерений температуры? ");
        int n = scanner.nextInt();
        int[] temps = new int[n];
        System.out.println("Введи температуры через пробел:");
        for (int i = 0; i < n; i++) {
            temps[i] = scanner.nextInt();
        }

        int minTemp = findMin(temps, 0);
        System.out.println("Самая низкая температура: " + minTemp);
    }
}

Частые ошибки новичков

  • Забыть про return: Если функция обещает вернуть число (не void), она обязана это сделать. Иначе Java выдаст ошибку.
  • Бесконечная рекурсия: В рекурсии обязательно должен быть базовый случай (условие остановки). Иначе функция будет вызывать себя бесконечно, и программа упадёт с ошибкой StackOverflowError.
  • Путать параметры и аргументы: Параметры — это переменные в определении функции (в скобках). Аргументы — это конкретные значения, которые ты передаёшь при вызове.
  • Изменять входные данные внутри функции: Старайся не менять параметры, если это не нужно — это может запутать.

Итоговый пример: семейный бюджет с функциями

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

import java.util.Scanner;

public class Main {
    // Функция для суммы двух чисел
    public static int sum(int a, int b) {
        return a + b;
    }

    // Функция проверки бюджета
    public static String checkBudget(int total) {
        if (total > 100000) {
            return "Бюджет превышен!";
        } else {
            return "Бюджет в норме.";
        }
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Введи зарплату: ");
        int salary = scanner.nextInt();
        System.out.print("Введи подработку: ");
        int freelance = scanner.nextInt();
        System.out.print("Введи проценты по вкладу: ");
        int interest = scanner.nextInt();

        // Сначала складываем зарплату и подработку
        int part1 = sum(salary, freelance);
        // Потом добавляем проценты
        int totalIncome = sum(part1, interest);

        System.out.println("Общий доход: " + totalIncome);
        System.out.println(checkBudget(totalIncome));
    }
}

Мы использовали функцию sum дважды, но написали её один раз. Удобно, правда? А если бы понадобилось складывать 10 чисел, мы бы просто вызывали её несколько раз. Функции делают код понятным и помогают не повторяться!