Лямбда-выражения для обобщенных функциональных интерфейсов. Примеры
Содержание
- 1. Особенности использования обобщений (шаблонов) в функциональных интерфейсах
- 2. Решения задач на построение лямбда-выражений, реализующих обобщенные функциональные интерфейсы. Примеры
- Связанные темы
Поиск на других ресурсах:
1. Особенности использования обобщений (шаблонов) в функциональных интерфейсах
Функциональный интерфейс может быть обобщенным (шаблонным). В этом случае целевой тип лямбда-выражения определяется на основании типа, указанного в ссылке на этот функциональный интерфейс.
Например. Пусть задан обобщенный функциональный интерфейс IValue
// Обобщенный (шаблонный) функциональный интерфейс. // Этот интерфейс оперирует обобщенным типом T. interface IValue<T> { T GetValue(); }
Интерфейс IValue<T> оперирует обобщенным типом T. В интерфейсе объявляется абстрактный метод GetValue(), который возвращает значение типа T. Следовательно, этот функциональный интерфейс совместим с любым лямбда-выражением, принимающим один параметр и возвращающим значение этого же типа.
При объявлении ссылки на функциональный интерфейс IValue<T> в аргументе типа нужно указать целевой тип лямбда-выражения:
// Объявить ссылку на функциональный интерфейс IValue, // который будет оперировать типом Float IValue<Float> refIValue;
После этого можно сформировать лямбда-выражение и вызвать метод GetValue()
// Установить лямбда-выражение с привязкой к типу Float refIValue = () -> 3.1415f; // вернуть значение типа float // Вызвать метод GetValue(), который возвращает 3.1415f float v = refIValue.GetValue(); // v = 3.1415
Если при формировании лямбда-выражения попытаться вернуть значение другого (несовместимого) типа
refIValue = () -> "Hello world!"; // здесь тип String а не Float
то компилятор выдаст ошибку типа
Type mismatch: cannot convert from String to Float
Чтобы лямбда-выражение возвращало тип String, нужно объявить новую ссылку на интерфейс IValue с аргументом типа String (IValue <String>).
⇑
2. Решения задач на построение лямбда-выражений, реализующих обобщенные функциональные интерфейсы. Примеры
2.1. Построение лямбда-выражения, возвращающего числовое значение
В примере демонстрируется:
- объявление обобщенного (шаблонного) функционального интерфейса IValue<T>, оперирующего типом T;
- создание лямбда-выражения и его использование для числового типа Float. Лямбда-выражение реализует обобщенный функциональный интерфейс IValue<T>.
// Обобщенный (шаблонный) функциональный интерфейс. // Этот интерфейс оперирует обобщенным типом T. interface IValue<T> { T GetValue(); } public class TrainLambda02 { public static void main(String[] args) { // Объявить ссылку на функциональный интерфейс IValue, // который будет оперировать типом Float IValue<Float> refIValue; // Установить лямбда-выражение с привязкой к типу Float refIValue = () -> 3.1415f; // вернуть значение типа float // Вызвать метод GetValue(), который вернет 3.1415f float v = refIValue.GetValue(); // v = 3.1415 System.out.println("v = " + v); } }
Результат работы программы
v = 3.1415
⇑
2.2. Лямбда-выражение, реализующее поэлементное суммирование массивов чисел
Условие задачи. Разработать программу, в которой осуществляется поэлементное суммирование массивов из 10 чисел. Тип чисел может быть любым числовым (int, double, float, …). Суммирование массивов реализовать с помощью лямбда-выражения.
Решение. Чтобы суммировать два массива чисел, нужно реализовать функциональный интерфейс ISumArrays, который содержит один метод SumArrays(). Этот метод должен получать два параметра — массивы чисел. Метод должен возвращать результат — массив чисел, который является суммой двух массивов-параметров.
В условии задачи сказано, что тип чисел может быть любым числовым (int, double, float, …). Это значит, что нужно разработать обобщенный (шаблонный) интерфейс ISumArrays для некоторого типа T. Поскольку тип T ограничивается числовыми типами, то его нужно ограничить типом Number.
В функции main() нужно протестировать работу созданного функционального интерфейса.
Ниже приведен текст программы, решающей данную задачу.
// Шаблонный функциональный интерфейс ISumArrays interface ISumArrays<T extends Number> { T[] SumArrays(T[] A, T[] B); } // Класс, содержащий методы, реализующие лямбда-выражение и // тестирующие работу программы. public class Lambda { public static void main(String[] args) { // 1. Объявить ссылку на ISumArrays для типа Double ISumArrays<Double> ref; // 2. Создать два массива типа double Double[] A1 = { 2.5, 1.4, 0.9, 1.1, 2.7, 2.9, 1.3, 2.0, 5.5, 1.2 }; Double[] A2 = { 1.5, 1.0, 0.6, 1.7, 0.7, 0.2, 0.3, 0.2, 1.1, 3.3 }; // 3. Сформировать лямбда-выражение для типа Double ref = (A, B) -> { Double[] C = new Double[A.length]; // числовой тип в массивах for (int i=0; i<A.length; i++) { // суммировать два числа как double C[i] = A[i].doubleValue() + B[i].doubleValue(); } return C; }; // 4. Вызвать метод функционального интерфейса Double[] A3 = (Double[])ref.SumArrays(A1, A2); // 5. Вывести результат System.out.print("A3: "); for (Double t : A3) System.out.print(" " + t); System.out.println(); } }
В вышеприведенном коде следует обратить внимание на то, как передаются массивы чисел в лямбда-выражение
... ref = (A, B) -> { Double[] C = new Double[A.length]; // числовой тип в массивах for (int i=0; i<A.length; i++) { // суммировать два числа как double C[i] = A[i].doubleValue() + B[i].doubleValue(); } return C; }; ...
Поскольку тип параметра лямбда-выражения определяется из целевого контекста, то массивы в лямбда выражение передаются как A и B. Параметр A ассоциируется с A[]. Параметр B ассоциируется с B[].
⇑
2.3. Вычисления количества вхождений заданного элемента в массиве
Условие задачи. Разработать программу, которая демонстрирует использование лямбда-выражения для поиска элемента в массиве. Программа должна содержать обобщенный функциональный интерфейс. Лямбда-выражение реализовать для типа String.
Решение. Текст программы, решающий данную задачу приведен ниже
// Шаблонный функциональный интерфейс IFindItem interface IFindItem<T> { // метод, вычисляющий количество вхождений // заданного элемента в массиве чисел int Search(T item, T[] items); } // Класс, который содержит методы, реализующие лямбда-выражение и // тестируют работу программы. public class Lambda { public static void main(String[] args) { // 1. Объявить ссылку на функциональный интерфейс // для типа String IFindItem<String> ref; // 2. Определить лямбда-выражение ref = (item, items) -> { int count=0; for (int i=0; i<items.length; i++) if (item==items[i]) count++; return count; }; // 3. Создать массив строк String[] AS = { "abc", "abd", "def", "acf", "abc", "afx" }; // 4. Протестировать лямбда-выражение int count = ref.Search("abc", AS); System.out.println("count = " + count); // count = 2 } }
Результат выполнения программы
count = 2
⇑
Связанные темы
- Лямбда-выражения. Основные понятия. Функциональный интерфейс. Примеры
- Передача лямбда-выражения в метод в качестве параметра. Примеры
- Генерирование исключений в лямбда-выражениях. Примеры
- Доступ к элементам класса в лямбда-выражениях. Захват переменных в лямбда-выражениях. Примеры
⇑