Как привязать поставщика Java к экземпляру объекта?
Как я могу привязать Java Supplier
к существующему экземпляру объекта? Например, если я хочу написать свой собственный метод compareTo()
с этим заголовком:
public static int myCompareTo(Object o1, Object o2, Supplier<Comparable> supplier) {...}
Я хочу иметь возможность называть это так:
myCompareTo("Hello", "Hello2", String::length);
Где String
(с большой буквы) - это класс, а не объект. Итак, как я могу привязать экземпляр o1
к поставщику?
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; }
с помощью этого, например, вы можете сортировать список людей по фамилии, и если два из них идентичны, вы можете использовать имя для сортировки. С помощью этого решения вы можете изменить сортировку во время выполнения.