Drunya
Drunya

Reputation: 121

Is it possible to use generic Consumer as function argument in Java?

Code:

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

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

Is it possible to make single method like public <T> void ifChanged(String key, Class<T> clazz, Consumer<T> consumer)?

Well obvious solution is public void ifChanged(String key, Consumer<Object> consumer) but I don't want to use Object as argument type, better to use several methods like above.

The problem is that for accept method I need ? super XXX and only super is Object. So is it possible at all?

Upvotes: 5

Views: 2137

Answers (3)

Iceberg
Iceberg

Reputation: 3372

In essence, you just break nested if/else condition checking into several methods. Why not change both the consumer and the supplier.

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

It's an example of Premature optimization in my opinion. Sometimes by leaving the nested if/else it is, you can get a simple and clear code style, although coupled.

Upvotes: 2

Naman
Naman

Reputation: 32028

Given the current code in question and close to what is mentioned in sully's answer, you can make use of a Function defined along with the generic Consumer to get the value to consume:

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

The implementation could be further used as:

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

With a sample implementation of the getBoolean/String and useBoolean/String methods as follows...

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);
}

The output generated would be:

String implementation!
key: naman
Boolean implementation!
true

Upvotes: 0

Ryuzaki L
Ryuzaki L

Reputation: 40078

You can create generic method that accepts type T object and Consumer of type T

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

    consumer.accept(t);

}

And you can call that method by passing any object with corresponding Consumer action

ifChanged("String", s->System.out.println(s.length()));
ifChanged(10, i->System.out.println(i.toString()));

Upvotes: 2

Related Questions