Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Method declaration with a function to extract fields of an object and a binary operator which will be applied to those fields

Given the following sample class Foo

@Getter
@AllArgsConstructor
@ToString
static class Foo {
    int field1;
    int field2;
    String field3;
}

I want to declare a method, let’s call it applyBinOperator, which accepts two Foo objects a key-extractor and a binary operator and apply that operator to the extracted fields of the Foo objects and returns the result. So basically I want to call the method in the following way or something similar:

Foo foo1      = new Foo(10, 20, "first");
Foo foo2      = new Foo(100, 200, "second");

int sum       = applyBinOperator(foo1, foo2, Foo::getField1, (a,b) -> a+b);

int prod      = applyBinOperator(foo1, foo2, Foo::getField2, (a,b) -> a*b);

String concat = applyBinOperator(foo1, foo2, Foo::getField3, (a,b) -> String.join(a,b));

//and get sum = 110, prod = 4000 and concat = firstsecond 

But I am struggling to find the correct syntax to define the method since I am not very familiar with generics. I have tried the following but it doesn’t compile yet:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

public  static <T> T applyBinOperator(Foo foo1, Foo foo2, 
       Function<? super T, ?> keyExtractor, BinaryOperator<T> binaryOperator) {

    return binaryOperator.apply(keyExtractor.apply(foo1), keyExtractor.apply(foo2));
}

Can someone help me with the correct syntax?

>Solution :

You seem to have just mixed up the order of the type parameters of Function. To write "a function that takes a Foo and returns a T", it is Function<Foo, T>:

public  static <T> T applyBinOperator(Foo foo1, Foo foo2,
                                      Function<Foo, T> keyExtractor, BinaryOperator<T> binaryOperator) {
    return binaryOperator.apply(keyExtractor.apply(foo1), keyExtractor.apply(foo2));
}

We can make the Foo part generic too, and also apply PECS:

public  static <T, U> T applyBinOperator(U foo1, U foo2,
                                      Function<? super U, ? extends T> keyExtractor, BinaryOperator<T> binaryOperator) {
    return binaryOperator.apply(keyExtractor.apply(foo1), keyExtractor.apply(foo2));
}

Also, String.join does not join "first" and "second" together. You probably meant String.concat, or just use +, which works with strings too.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading