Using Java on Android, I want to merge an element into a Map with a custom remapping function.

Map<String, MyObject> map = new HashMap<String, MyObject>();
// init map with some values here....  then
MyObject xMyObject = new MyObject(123); // init this instance of MyObject
map.merge("key", xMyObject, myRemappingFunction);

I understand Android Java does not have Java 8 support for lambda expressions. So I think I need to implement myRemappingFunction as a BiFunction, but I'm having trouble with understanding the BiFunction interface declaration to get anything to compile.

public static BiFunction<? super MyObject,? super MyObject,? extends MyObject> remappingfunction()

Any hints please?

Answer
      • 1
    • A key fact that I didn't know, which contributed to my confusion prompting this question, is that the "" notation is called a "lower bound wildcard" for Java Generics.

The remappingFunction is an implementation of BiFunction<? super MyObject, ? super MyObject,? extends MyObject> which is evaluated using the apply method that you need to define here.

Consider an example when you would merge the integer attribute val (by summing) of your MyObject if they are mapped to the same key, the implementation would look like :

map.merge("key", xMyObject, new BiFunction<MyObject, MyObject, MyObject>() {
    // this is the definition of what to do for two such values
    @Override
    public MyObject apply(MyObject myObject1, MyObject myObject2) {
        return new MyObject(myObject1.getVal() + myObject2.getVal());
    }
});

this could also be represented in lambda as :

map.merge("key", xMyObject, 
                (myObject1, myObject2) -> new MyObject(myObject1.getVal() + myObject2.getVal()));
  • 1
Reply Report
      • 1
    • Yay, I appear to have understood your answer enough to use it. I also see my confusion in my above comment about BinaryOperator being a specialization of BiFunction, I wouldn't have understood this document link without your concrete code example here. Using BinaryOperator appears to work just as well. They could have used that in the docs for Map.merge(). After all, could there be any other BiFunction<> where the 3 parameter types are not equal for use in Map.merge()?
    • @LarryTseng well the difference in the use of BiFunction there is that it allows you ? super V, ? super V, ? extends V to get a return value of child type for input of parent types. While this won't have been possible using BinaryOperator, since that would have either been all ? super V or ? extends V.
      • 1
    • Do note, for your case, since the type is always MyObject a specific implementation of BinaryOperator which extends BiFunction works as well.
      • 2
    • Thanks! That gets to me a solution that compiles w/o error, and your first implementation answer is what I think I need to use, given the complex nature of my object merger. I'll approve as soon as I can verify my new code actually runs (shortly). Thanks for the quick answer.

Warm tip !!!

This article is reproduced from Stack Exchange / Stack Overflow, please click

Trending Tags

Related Questions