Можно ли передать параметры, используя ссылку на метод? Например, мне нужно создать TreeMap
, но используя reverseOrder()
. Существует ли что-то вроде TreeMap::new(reverseOrder())
?
параметры в справочнике по методу
Ответы (4)
Нет, вы не можете сделать это со ссылкой на метод.
Вместо этого вы можете использовать лямбда-выражения:
() -> new TreeMap<TheRelevantType>(reverseOrder())
or
() -> new TreeMap<>(reverseOrder())
если вы используете это выражение в контексте, где компилятор может вывести тип элемента TreeMap
.
Для этого вам нужно лямбда-выражение... вы, вероятно, думаете о Supplier
:
() -> new TreeMap<>(Comparator.reverseOrder())
В Java не может быть ссылок на методы с аргументами. Вместо этого вы должны использовать лямбда-выражение:
Supplier<Map<String, String>> factory = () ->
new TreeMap<>(Comparator.reverseOrder());
Но если по какой-либо причине вы все равно хотите/должны использовать ссылку на метод, вот способ сделать это с помощью вспомогательного метода:
public static <T, U> Supplier<T> withArg(
Function<? super U, ? extends T> methodRef,
U arg) {
return () -> methodRef.apply(arg);
}
Supplier<Map<String, String>> factory = withArg(
TreeMap::new,
Comparator.<String>reverseOrder());
Это не поддерживается самими ссылками на методы (сегодня), но во многих случаях ссылки на методы можно использовать с параметрами, используя Коллекции Eclipse API. Возьмем следующий пример:
Map<String, TreeSet<String>> jdkMap = new HashMap<>();
jdkMap.put("one", new TreeSet<>(Comparator.reverseOrder()));
jdkMap.computeIfAbsent("two", key -> new TreeSet<>(Comparator.reverseOrder()));
MutableMap<String, TreeSet<String>> ecMap =
Maps.mutable.with("one", new TreeSet<>(Comparator.reverseOrder()));
ecMap.getIfAbsentPutWith("two", TreeSet::new, Comparator.<String>reverseOrder());
Assert.assertEquals(jdkMap, ecMap);
Здесь я сравниваю использование метода Map.computeIfAbsent()
из JDK, который принимает Function
и передает ключ в качестве параметра, и метод MutableMap.getIfAbsentPutWith()
из Eclipse Collections, который также принимает Function
и передает дополнительный параметр. В примере с JDK я должен использовать лямбду. В примере EC я могу использовать ссылку на конструктор TreeSet::new
и указать Comparator.<String>reverseOrder()
в качестве параметра, который я хочу ему передать.
В Eclipse Collections доступно множество методов *With
(например, selectWith
, rejectWith
, collectWith
, detectWith
, anySatisfyWith
и т. д.). Эти методы увеличивают общее количество мест, которые можно использовать со ссылками на методы в Java 8.
Вы найдете примеры ссылок на методы, используемые с параметрами, в каталогах коллекций Eclipse.
Компания Kata -> Тест упражнения 2
Pet Kata -> Тест упражнения 2
Примечание. Я коммиттер Eclipse Collections.