2016-10-27 2 views
0

Можно ли передать ссылку на метод в качестве параметра?Передача ссылок функций как параметров

Например:

public static void main(String[] args) { 
    String data = "name: John, random text, address: leetStreet"; 
    Person person; 

    //if regex matches, use method reference, to send the result. 
    applyDataToPerson(data, "name: (\\w+)", person, Person::setName); 
    applyDataToPerson(data, "address: (\\w+)", person, Person::setAddress); 
} 

private static void applyDataToPerson(String data, String regex, Person person, 
Function<Person> f) { 
    Matcher match = Pattern.compile(regex).matcher(data); 
    if (match.matches()) person.f(match.group(1)); 
} 

class Person { 
    private String name; 
    private String address; 

    public void setName(String name) { 
     this.name = name; 
    } 

    public void setAddress(String address) { 
     this.address = address; 
    } 
} 

Если нет, то что было бы альтернативой дать ссылку на метод? Конструкция коммутационного корпуса?

+2

В Java 8 вы можете [передать ссылки метода] (https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html) на существующие методы (между прочим) – Tibrogargan

+0

@Tibrogargan, как бы выглядела подпись метода? 'Компаратор ' для меня не имеет смысла. – JasperJ

+1

Что означает 'Function ', который должен представлять? Если мы говорим о ['java.util.function.Function'] (https://docs.oracle.com/javase/8/docs/api/java/util/function/Function.html), у него есть 2 общие типы, а не 1. Так что код не может скомпилироваться для начала ... (не говоря уже о 'person.f (...)'). Перед запросом _alternatives_, убедитесь, что у вас есть рабочий код ... – Tunaki

ответ

5

Я думаю, что вы ищете BiConsumer:

private static void applyDataToPerson(String data, String regex, Person person, BiConsumer<Person, String> action) { 
    Matcher match = Pattern.compile(regex).matcher(data); 
    if (match.matches()) action.accept(person, match.group(1)); 
} 

В качестве альтернативы, вы можете сократить подпись метода и использовать один-аргумент Consumer, который улавливает ваш person ссылка:

public static void main(String[] args) { 
    String data = "name: John, random text, address: leetStreet"; 
    Person person; 

    //if regex matches, use method reference, to send the result. 
    applyData(data, "name: (\\w+)", person::setName); 
    applyData(data, "address: (\\w+)", person::setAddress); 
} 

private static void applyData(String data, String regex, Consumer<String> action) { 
    Matcher match = Pattern.compile(regex).matcher(data); 
    if (match.matches()) action.accept(match.group(1)); 
} 
+0

И в вашем основном методе напишите функцию biconsumer: 'applyDataToPerson (data," name: (\\ w +) ", person, (Person p, String s) - > p.setName (s)); applyDataToPerson (data, "address: (\\ w +)", person, (Person p, String s) -> p.setAddress (s)); ' – gaston

+2

@gaston Нет, основной метод точно такой же, как у OP. – shmosel

+2

Лично мне нравится второй вариант. –

Смежные вопросы