1

Can someone tell why doReduce compiles but doReduce2 doesn't:

List<String> strings = List.of("a", "bb", "cc", "ddd");
Map<Integer,ObjStr2> result2 = strings.stream()
                .map(ObjStr1::new)
                .collect(Collectors.groupingBy(ObjStr1::getLen
                        , Collectors.reducing(new ObjStr2(), ObjStr1::to2, ObjStr2::doReduce)));

class ObjStr1{
    String str = "";

    ObjStr1(String str) {
        this.str = str;
    }

    static ObjStr2 to2(ObjStr1 o){
        return new ObjStr2(o.str);
    }

    Integer getLen(){return str.length(); };
}

class ObjStr2{
    String str = "";

    ObjStr2(){}

    ObjStr2(String str) {
        this.str = str;
    }

    static BinaryOperator<ObjStr2> doReduce2(){
        return (a,b) -> new ObjStr2(a.str + b.str);
    }

    static ObjStr2 doReduce(ObjStr2 a, ObjStr2 b){
        return new ObjStr2(a.str + b.str);
    }

    @Override
    public String toString(){
        return str;
    }
}

I can even copy the contents of doReduce2 directly into the lambda and it will compile.
reducing is supposed to accept BinaryOperator

11
  • 1
    what is the compile error? Commented Apr 24, 2020 at 8:30
  • Incompatible parameter types in method reference expression Commented Apr 24, 2020 at 8:32
  • 1
    @Andreas he means this: return (a,b) -> new ObjStr2(a.str + b.str); Commented Apr 24, 2020 at 8:38
  • Surely you're reducing a stream of ObjStr1? So you can't apply a BinaryOperator<ObjStr2> to it? Commented Apr 24, 2020 at 8:39
  • @Andy I'm transforming ObjStr1 to ObjStr2 Commented Apr 24, 2020 at 8:40

2 Answers 2

1

You should try calling the method doReduce2 without the use of method reference and it should work -

Map<Integer, ObjStr2> result2 = strings.stream()
        .map(ObjStr1::new)
        .collect(Collectors.groupingBy(ObjStr1::getLen,
                Collectors.reducing(new ObjStr2(),
                        ObjStr1::to2, ObjStr2.doReduce2())));
Sign up to request clarification or add additional context in comments.

Comments

1

doReduce() is a BinaryOperator.

doReduce2() returns a BinaryOperator.

Since reduce() expects a BinaryOperator, you can give doReduce as a method reference, or you can call doReduce2().

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.