Можно ли использовать generi c Consumer в качестве аргумента функции в Java? - PullRequest
6 голосов
/ 25 января 2020

Код:

public void ifChangedString(String key, Consumer<String> consumer) {
    ...
    consumer.accept(getString(key));
}

public void ifChangedBoolean(String key, Consumer<Boolean> consumer) {
    ...
    consumer.accept(getBoolean(key));
}

Можно ли создать один метод, например public <T> void ifChanged(String key, Class<T> clazz, Consumer<T> consumer)?

Совершенно очевидным решением является public void ifChanged(String key, Consumer<Object> consumer), но я не хочу использовать Object в качестве типа аргумента лучше использовать несколько методов, как указано выше.

Проблема в том, что для accept метода мне нужно ? super XXX, и только super - это Object. Так возможно ли это вообще?

Ответы [ 3 ]

3 голосов
/ 25 января 2020

Вы можете создать обобщенный метод c, который принимает объект типа T и Consumer типа T

public <T> void ifChanged(T t, Consumer<T> consumer) {

    consumer.accept(t);

}

И вы можете вызвать этот метод, передав любой объект с Consumer действие

ifChanged("String", s->System.out.println(s.length()));
ifChanged(10, i->System.out.println(i.toString()));
2 голосов
/ 25 января 2020

По сути, вы просто разбиваете вложенную проверку условия if / else на несколько методов. Почему бы не изменить и потребителя, и поставщика.

public <T> void ifChangedT(String key, Consumer<T> consumer, Supplier<T> supp) {
    ...
    consumer.accept(supp.get());
}

На мой взгляд, это пример преждевременной оптимизации. Иногда, оставив вложенный if / else, вы можете получить простой и понятный стиль кода, хотя и связанный.

0 голосов
/ 26 января 2020

Учитывая текущий рассматриваемый код и близкий к тому, что упомянуто в ответе Салли , вы можете использовать Function, определенный вместе с обобщенным c Consumer, чтобы получить значение для потребление:

public static <T> void ifChangedGeneric(String key, Consumer<T> consumer, Function<String, T> function) {
    consumer.accept(function.apply(key));
}

Реализация может быть далее использована как:

public static void main(String[] args) {
    ifChangedGeneric("key", <Class>::useString, <Class>::getString);
    ifChangedGeneric("true", <Class>::useBoolean, <Class>::getBoolean);
}

С примером реализации методов getBoolean/String и useBoolean/String, как показано ниже ...

static Boolean getBoolean(String key) {
    return key.equalsIgnoreCase("true") ? Boolean.TRUE : Boolean.FALSE;
}

static void useBoolean(Boolean bool) {
    System.out.println("Boolean implementation!");
    System.out.println(bool.equals(Boolean.TRUE));
}

static String getString(String key) {
    return key + ": naman";
}

static void useString(String str) {
    System.out.println("String implementation!");
    System.out.println(str);
}

Сгенерированный вывод будет:

String implementation!
key: naman
Boolean implementation!
true
...