generics - Java 8 type inference involving Booleans -
consider following code:
class predicate { public boolean eval(evaluationcontext ec) { /* logic here */ } } // later ... list<predicate> preds = new list<>( /* predicates here */ ); // let's use stream<> implement , logical connective: // version a: boolean resulta = preds.stream() .map(p -> p.eval(context)) .reduce(boolean.true, (a,b) -> boolean.logicaland(a,b)); // oops: code above doesn't compile ... // error: incompatible types: java.lang.object cannot converted boolean // version b: (add intermediate variable explicit type) stream<boolean> v = _children.stream().map(p -> p.eval(context)); boolean resultb = v.reduce(boolean.true, (a,b) -> boolean.logicaland(a, b) ); // compiles fine...
so, question is:
what wrong structure of version prevents java compiler correctly inferring type of result of map()? limitation of type-inference algorithm in java? if so, there better way write code type inference succeeds?
your code compiles fine jdk1.8.0_05
, jdk1.8.0_20
, jdk1.8.0_25
, , jdk1.8.0_40 (beta)
, there’s no reason assume there version having problems it. maybe helps when either fix other errors of made-up code or post real code gave compiler.
e.g. can’t new list<>
if list
refers java.util.list
, example code contains no declaration of context
. if context
cannot found, compiler indeed produce “incompatible types” follow-up error disappear once fixed other errors. it’s striking second example uses _children
rather preds
originates different context no such compiler errors exist.
by way, lambda expression (a,b) -> boolean.logicaland(a,b)
bit odd. either use expressions, e.g. (a,b) -> && b
or method reference boolean::logicaland
.
but either way, using reduction not recommended. can better performance using short-circuiting methods, e.g. _children.stream().allmatch(p -> p.eval(context))
logical and
or _children.stream().anymatch(p -> p.eval(context))
logical or
.
Comments
Post a Comment