Как привязать поставщика Java к экземпляру объекта?


Как я могу привязать Java Supplier к существующему экземпляру объекта? Например, если я хочу написать свой собственный метод compareTo() с этим заголовком:

public static int myCompareTo(Object o1, Object o2, Supplier<Comparable> supplier) {...}

Я хочу иметь возможность называть это так:

myCompareTo("Hello", "Hello2", String::length);

Где String (с большой буквы) - это класс, а не объект. Итак, как я могу привязать экземпляр o1 к поставщику?

4 10

4 ответа:

Вот то, что вы искали (я полагаю):

public static <T, U extends Comparable<U>> int compare(T o1, T o2, Function<T, U> mapper) {
    return mapper.apply(o1).compareTo(mapper.apply(o2));
}

Это можно назвать так:

compare("str1", "str2", String::length); // 0

На самом деле более правильным способом определения вашего метода было бы:

private static <T, U extends Comparable<? super U>> int myCompareTo(T left, T right, Function<T, U> fu) {
    return Comparator.comparing(fu).compare(left, right);
}

Вы можете использовать

Comparator.comparing(String::length);

Для получения экземпляра компаратора, который можно передать в метод.

Спасибо за ответы. На самом деле я понял это только сейчас. Я хотел иметь предоставленные экземпляры объекта (o1 и o2) для выполнения данного метода. Я обнаружил, что поставщик был неправильным интерфейсом, вместо этого мне пришлось использовать функцию. Здесь вы можете увидеть мой рабочий упрощенный пример:

public static <T> int myCompareTo(T o1, T o2, Function<T, Comparable> getter) {
        return getter.apply(o1).compareTo(getter.apply(o2));
}

Причина, по которой интерфейс должен быть функцией, а не поставщиком, заключается в том, что только функция эквивалентна лямбда-выражению, принимающему объект и вызывающему ссылочный метод на объект.

Для пример, если вы определяете ссылку на метод как:

Function<TypeOfInstance, ReturnTypeOfReferencedMethod> methodReference = TypeOfInstance::referencedMethod();

Тогда эквивалентное лямбда-выражение выполняется следующим образом:

(instance) -> instance.referencedMethod()

Дополнительная Информация:

Edit: я знаю, что мог бы сделать то же самое с помощью Comparator, но этот пример очень упрощен. В моем приложении функция такого рода необходима. Мне пришлось создать функцию compareTo, которая сортирует ArrayList по нескольким атрибутам, потому что главный атрибут сортировки может быть не единственным в списке. список. Я хочу поделиться своим кодом с вами, потому что я думаю, что это может быть интересным открытием для вас.

public static <T> int ultimateCompare(T o1, T o2, Function<T, Comparable>... getters) {
    for (Function<T, Comparable> getter : getters) {
        int result = getter.apply(o1).compareTo(getter.apply(o2));
        if (result != 0) return result;
    }
    return 0;
}

с помощью этого, например, вы можете сортировать список людей по фамилии, и если два из них идентичны, вы можете использовать имя для сортировки. С помощью этого решения вы можете изменить сортировку во время выполнения.