foo.reverse()
фактически меняет элементы в контейнере. reversed()
фактически ничего не отменяет, он просто возвращает объект, который можно использовать для итерации по элементам контейнера в обратном порядке. Если это то, что вам нужно, оно часто быстрее, чем наоборот.
NameCreator::createName
подразумевает, что либо метод является статическим (вид №1 в таблице ниже), либо цель целевого интерфейса также принимает экземпляр класса (вид # 3, например BiFunction<NameCreator, String, String>
). Ваши методы не являются статическими, и поэтому, предположительно, ваша цель не принимает экземпляр, поэтому вы получаете ошибку «Can not solve method». Вероятно, вы захотите использовать ссылку метода на экземпляре (вид # 2). Изнутри класса вы можете использовать:
Function<String, String> func = this::createName
Из-за пределов класса, который вы можете использовать:
NameCreator creator = new NameCreator();
Function<String, String> func = creator::createName;
Что касается использования одно- или двухпараметрической версии , это зависит от того, какой целевой интерфейс используется. Вышеупомянутый будет использовать ваш первый метод, потому что Function<String, String>
берет строку и возвращает строку. Например, в следующем функциональном интерфейсе будет использоваться ваш второй метод:
NameCreator creator = new NameCreator();
BiFunction<String, String, String> func = creator::createName;
См. Function
, BiFunction
и весь пакет java.util.function
Вас также может заинтересовать учебник Java по ссылкам метода , в частности эта часть:
Существует четыре вида ссылок на методы:
Kind | Example
==============================================================================================
Reference to a static method | ContainingClass::staticMethodName
-------------------------------------------------------+--------------------------------------
Reference to an instance method of a particular object | containingObject::instanceMethodName
-------------------------------------------------------+--------------------------------------
Reference to an instance method of an arbitrary object | ContainingType::methodName
of a particular type |
-------------------------------------------------------+--------------------------------------
Reference to a constructor | ClassName::new
==============================================================================================
Ссылки на методы полагаются на вывод. Таким образом, без надлежащего контекста, из которого компилятор может вывести целевой функциональный интерфейс, эта ошибка разрешения повышается.
Вы должны назначить его типу интерфейса, который объявляет метод, соответствующий сигнатуре (или использовать его в контексте где задан тип цели, такой как аргумент метода).
Например:
interface INameCreator {
String create(String name);
}
interface INamesCreator {
String create(String firstName, String lastName);
}
И затем вы можете использовать ссылки метода:
//match NameCreator.createName(String)
INameCreator creator = this::createName //within the class
INameCreator creator = nameCreatorInstance::createName
И
//match NameCreator.createName(String, String)
INamesCreator creator = this::createName //within the class
INamesCreator creator = nameCreatorInstance::createName
Если этот метод был статическим, вы могли бы использовать синтаксис NameCreator::createName
в том же контексте.
Если вы хотите создать экземпляры типа NameCreator
на основе строк, используйте это:
public static class NameCreator {
public static String createName(String lastname) {
return lastname;
}
public static String createName(String lastname, String firstName) {
return lastname + " " + firstName;
}
}
, а затем выполните следующие вызовы:
List<String> items = new ArrayList<>();
//
items.forEach(NameCreator::createName);//uses the first method
Map<String, String> map = new HashMap<>();
//
map.forEach(NameCreator::createName); //uses the second method
Consumer<String> consumer = creator::createName
. ИлиFunction<String, String> consumer = ...
и так далее. Спасибо. – Mulgard 13 July 2018 в 10:19Consumer
илиBiConsumer
, в зависимости от того, какой метод вы хотите. Списки параметров всегда должны точно совпадать, но возвращаемые типы также можно игнорировать. (см. мой ответ здесь ) – Michael 13 July 2018 в 10:21NameCreator::createName
, они не обязательно должны быть статическими. Это просто означает, что они принимают дополнительный первый аргумент, который представляет экземпляр. напримерBiFunction<NameCreator, String, String> func = NameCreator::createName;
будет ссылаться на первый метод. – Jorn Vernee 13 July 2018 в 10:29