1

I have a class (Filter) that has several variables:

class Filter {
    Integer intVal;
    Double doubleVal;
    String strVal;

    public Integer getIntVal() {
        return intVal;
    }

    public void setIntVal(Integer intVal) {
        this.intVal = intVal;
    }

    public Double getDoubleVal() {
        return doubleVal;
    }

    public void setDoubleVal(Double doubleVal) {
        this.doubleVal = doubleVal;
    }

    public String getStrVal() {
        return strVal;
    }

    public void setStrVal(String strVal) {
        this.strVal = strVal;
    }
}

And a class (Handler) that needs to contain a lambda Function and BiConsumer to get and set the value:

class Handler {
    Function<Filter, Object> getter;
    BiConsumer<Filter, Object> setter;
    public Handler(Function<Filter, Object> getter, BiConsumer<Filter, Object> setter) {
        this.getter = getter;
        this.setter = setter;
    }
}

(I used BiConsumer because of this SO answer: https://stackoverflow.com/a/27759997/963076).

Implemented like this:

Filter filter = new Filter();

Handler handler1 = new Handler(Filter::getIntVal, Filter::setIntVal);
Object o = handler1.getter.apply(filter);
handler1.setter.accept(filter, o);
Handler handler2 = new Handler(Filter::getDoubleVal, Filter::setDoubleVal);
Handler handler3 = new Handler(Filter::getStrVal, Filter::setStrVal);

But the setter doesn't work. Compiler throws an error:

error: incompatible types: invalid method reference
Handler handler1 = new Handler(Filter::getIntVal, Filter::setIntVal);
incompatible types: Object cannot be converted to Integer

error: incompatible types: invalid method reference
Handler handler2 = new Handler(Filter::getDoubleVal, Filter::setDoubleVal);
incompatible types: Object cannot be converted to Double

error: incompatible types: invalid method reference
Handler handler3 = new Handler(Filter::getStrVal, Filter::setStrVal);
incompatible types: Object cannot be converted to String

So the BiConsumer can't force-cast the Object to String, etc. So how do I get around this? How do I write this so that I can set the values of the Filter with a lambda function?

Pretty sure the answer has to do with generics which I have a hard time wrapping my head around sometimes.

ryvantage
  • 13,064
  • 15
  • 63
  • 112

1 Answers1

3

Generify your handler

class Handler<E> {
    Function<Filter, E> getter;
    BiConsumer<Filter, E> setter;
    public Handler(Function<Filter, E> getter, BiConsumer<Filter, E> setter) {
        this.getter = getter;
        this.setter = setter;
    }
}

Here is sample usage

    Handler<Integer> handler1 = new Handler<>(Filter::getIntVal, Filter::setIntVal);
    Integer i1 = handler1.getter.apply(filter);
    handler1.setter.accept(filter, i1);
gagan singh
  • 1,591
  • 1
  • 7
  • 12