Как использовать java функцию как аргумент

Аватар пользователя Сергей Якимович
Сергей Якимович
22 января 2023

Использовать функцию как аргумент можно разными способами. Рассмотрим некоторые из них.

1) Воспользуемся функциональным интерфейсом Predicate :

import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class App {
    public static void main(String[] args) {
        List<String> list1 = List.of("1", "22", "333", "4444");
        List<String> filteredList1 = filterList(list1, x -> x.length() >= 3);
        System.out.println(filteredList1); // => [333, 4444]

        List<Integer> list2 = List.of(1, 2, 3, 4);
        List<Integer> filteredList2 = filterList(list2, x -> x >= 3);
        System.out.println(filteredList2); // => [3, 4]
    }

    public static <T> List<T> filterList(List<T> list, Predicate<T> rool) {
        return list.stream()
                .filter(x -> rool.test(x))
                .collect(Collectors.toList());
    }
}

2) Воспользуемся готовым функциональным интерфейсом UnaryOperator :

public static void superMethod(UnaryOperator<String> method) {
    String str = "Hexlet";
    String result = method.apply(str);
    System.out.println(result);
}

// вызов с передачей методов
public class App {
    public static void main(String[] args) throws Exception {
        // передадим стандартный метод
        superMethod(String::toUpperCase); // => HEXLET
        // передадим лямбда-функцию
        superMethod(s -> s + "!"); // => hexlet!
        // передадим собственный метод
        superMethod(App::reverse);  // => telxeh
    }

    public static String reverse(String str) {
        StringBuilder builder = new StringBuilder();
        builder.append(str);
        return builder.reverse().toString();
    }
}

3) Создадим собственный интерфейс и передадим объект этого типа в нашу функцию :

interface MyInterface {
    int count(int a, int b, int c);
}

public static void superMethodInterface(MyInterface method) {
    int a = 5, b = 10, c = 20;
    int result = method.count(a, b, c);
    System.out.println(result);
}

// вызов с передачей методов
public class App {
    public static void main(String[] args) throws Exception {
        MyInterface count = new MyInterface() {
            @Override
            public int count(int a, int b, int c) {
                return a + b + c;
            }
        };
        superMethodInterface(count); // => 35
        superMethodInterface((a,b,c) -> a * b * c); // => 1000
        superMethodInterface((a,b,c) -> a + b - c); // => -5
    }
}

4) Получим метод с помощью рефлексии и передадим его :

 public static void superMethodReflection(Object object, Method method) throws Exception {
    int a = 10;
    int b = 20;
    int result = (int) method.invoke(object, a, b);
    System.out.println(result);
}
// вызов с передачей методов
public class App {
    public static void main(String[] args) throws Exception {
        // передадим стандартный метод
        Method method = Integer.class.getDeclaredMethod("max", int.class, int.class);
        superMethodReflection(0, method); // => 20
        method = Integer.class.getDeclaredMethod("sum", int.class, int.class);
        superMethodReflection(0, method); // => 30
        // передадим собственный метод
        method = App.class.getDeclaredMethod("concate", int.class, int.class);
        superMethodReflection(new App(), method); // => 1020
    }

    public static int concate(int a, int b) {
        return Integer.parseInt("" + a + b);
    }
}
1 0