Страницы

Поиск по вопросам

пятница, 2 ноября 2018 г.

Передача метода в качестве параметра в java

Читал новые фичи в java 8, но так и не понял, можно ли в java передать метод в качестве параметра другому методу?


Ответ

Насколько я понимаю, речь всё-таки не о лямбда-выражениях, а о ссылках на методы (method references). Они ходят рядом с лямбда-выражениями, но всё же это отдельная штука.
Предположим, у вас есть метод, которому зачем-то посреди работы нужно преобразование строки в строку. Для этого можно воспользоваться готовым функциональным интерфейсом UnaryOperator
public void myMethod(UnaryOperator stringTransformer) { // где-то в середине метода, возможно даже в цикле String transformedString = stringTransformer.apply(str); ... }
Теперь в этот метод вы можете передать ссылки на подходящие методы. Тут подходят некоторые методы класса String, которые не принимают аргументов и возвращают новую строку. Например, можно вызвать так:
myMethod(String::trim);
Или так:
myMethod(String::toUpperCase);
Тогда, когда вы вызываете stringTransformer.apply(str), это волшебным образом превратится в str.trim() или str.toUpperCase()
Ещё тут вариант — передать ссылку на статический метод с одним параметром. Например, у вас в проекте есть такое:
public class StringUtils { public static String removeDots(String str) { return str.replace(".", ""); } }
Тогда вы можете и ссылкой на такой метод воспользоваться:
myMethod(StringUtils::removeDots);
И stringTransformer.apply(str) волшебным образом превратится в StringUtils.removeDots(str). Ещё можно сделать instance-bound ссылку, привязанную к конкретному объекту. Например:
myMethod(Pattern.compile("foo").matcher("[foo]")::replaceFirst);
Тут уже stringTransformer.apply(str) волшебным образом возьмёт str в квадратные скобки (а точнее — заменит в [foo] подстроку foo на str).
Есть ещё ссылки на методы, создающие объект (типа ArrayList::new) или массив (типа int[]::new). В этом случае функциональный интерфейс должен соответствовать параметрам конструктора (в случае массива подразумевается один целый параметр — его длина). Ссылки на методы — мощная и красивая штука, но нередко всё-таки нужно полноценное лямбда-выражение. Например, последний пример яснее написать так:
myMethod(str -> "["+str+"]");

Комментариев нет:

Отправить комментарий