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

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

Функциональные типы и лямбды в Kotlin #

Презентацию можно посмотреть по ссылке.

Видео-запись на Rutube

Документация #

Задача № 1: Обработка функционального типа #

Реализуйте функцию, которая принимает функциональный тип в качестве аргумента и вызывает его несколько раз.

Сигнатура функционального типа:

(Int) -> Unit

Сигнатура функции:

fun callTwice(expression: (Int) -> Unit) { }

Данная функция должна вызывать функциональное выражение дважды. В первый раз передавать число 4, во второй раз — 41.

Вызовите функцию callTwice три раза, передав ей разные лямбда-выражения.

  1. В первый раз передайте лямбда-выражение, которое выводит переданный аргумент на стандартный поток вывода. Ожидаемый вывод:
    4
    41
  2. Во второй раз передайте лямбда-выражение, которое умножает переданный аргумент на 2 и выводит результат на стандартный поток вывода. Ожидаемый вывод:
    8
    82
  3. В третий раз передайте лямбда-выражение, которое выводит на стандартный поток слово «нечётное», если в качестве аргумента было передано нечётное число, и «чётное» в остальных случаях. Ожидаемый вывод:
    чётное
    нечётное

Задача № 2: Обработка результатов вызова функционального типа #

Реализуйте, функцию, которая будет вызывать функциональное выражение и выводить результат обработки данных на стандартный поток вывода. Сигнатура функционального типа:

(Double) -> Double

Сигнатура функции:

fun callAndPrint(expression: (Double) -> Double) {}

Данная функция должна вызывать передаваемое ей функциональное выражение трижды. С аргументами: 25, 16, 157.

  1. Вызовите функцию callAndPrint, передав ей лямбда-выражение, которое вычисляет остаток от деления аргумента на 13. Ожидаемый вывод:
    12
    3
    1
  2. Вызовите функцию callAndPrint, передав ей лямбда-выражение, которое возводит аргумент во вторую степень и возвращает его в качестве результата. Ожидаемый вывод:
    625
    256
    24649

Задача № 3: Динамическое создание лямбда-выражений #

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

(Double) -> Double

Создаваемые лямбда-выражения должны умножать переданный им аргумент на значение, которое передаётся в качестве аргумента для функции-генератора.

Сигнатура функции-генератора:

fun createMultiplier(coefficient: Double): (Double) -> Double { ... }

Реализуйте данную функцию два раза. В первый раз для возвращения значения используйте return-выражения. Во второй раз не используйте return, т.к. функция состоит из одного выражения.

Используйте функцию-генератор и функцию callAndPrint, работающую с функциональными выражениями из задачи № 2.

  1. С помощью функции-генератора createMultiplier создайте лямбда-выражение, передав ей коэффициент равный 10. Вызовите функцию callAndPrint из задания № 2, передав ей созданное лямбда-выражение. Ожидаемый вывод:
    250
    160
    1570
  2. Объедините вызовы этих двух функций в одно выражение. При вызове функции callAndPrint в качестве аргумента сразу вызовите функцию createMultiplier с передачей ей аргумента. Ожидаемый вывод:
    250
    160
    1570
  3. Вызовите функцию callAndPrint из задачи № 2, передав ей лямбда-выражение, созданное путём вызова функции-генератора createMultiplier с коэффициентом, равным 7. Ожидаемый вывод:
    175
    112
    1099
  4. Создайте лямбда-выражение путём вызова функции-генератора createMultiplier с коэффициентом 1. Создайте ещё одно лямбда-выражение путём вызова функции-генератора createMultiplier с коэффициентом 1. Являются ли данные созданные лямбда-выражения одинаковыми? Будет ли результат вызова данных лямбда-выражений одинаковым?

Задача № 4: Определение функционального (SAM) интерфейса #

Определите функциональный интерфейс для описания функционального типа, который возвращает генератор и использует метод callAndPrint. Интерфейс может быть назван DoubleTransformer. Сигнатура единственного абстрактного метода может иметь следующий вид:

fun transform(number: Double): Double
  • В местах вхождения функционального типа (Double) -> Double замените его на использование функционального интерфейса.
  • Исправьте метод callAndPrint, чтобы он корректно вызывал метод объектов типа DoubleTransformer.
  • Удостоверьтесь, что приложение корректно функционирует.
  • Какие плюсы есть у определения типов через описание функционального типа, а когда следует использовать функциональный интерфейс?

Задача № 5: Наследование от функционального интерфейса в классах #

Определите класс, задачей которого является вычисление значения многочлена в определённой точке. В качестве данных конструктору класса передаётся список коэффициентов многочлена, начиная с наименьшего. Класс должен быть унаследован и реализовывать функциональный интерфейс, описанный в задаче № 4. Предположим, что данный класс называется PolynomialCalculator.

Создайте экземпляр данного класса, передав ему в качестве списка коэффициентов следующий список:

listOf(7, -5, 2)

Вызовите функцию calcAndPrint из задачи № 2, передав ей в качестве аргумента созданный экземпляр класса PolynomialCalculator. В результате работы метода должен получиться вывод:

1132
439
48520

© A. M. Васильев, 2024, CC BY-SA 4.0, andrey@crafted.su