functional programming - Reducing a list of UnaryOperators in Java 8 -


what preferred way of reducing list of unaryoperators in java 8 till represent 1 unaryoperator can call apply on? example have following

interface myfilter extends unaryoperator<myobject>{};  public myobject filterit(list<myfilter> filters,myobject obj){ optional<myfilter> mf = filters                            .stream()                            .reduce( (f1,f2)->(myfilter)f1.andthen(f2));  return mf.map(f->f.apply(obj)).orelse(obj);  } 

but code throws classcastexception @ (myfilter)f1.andthen(f2). want effect of code in end:

myobject o = obj; for(myfilter f:filters){   o = f.apply(o); } return o; 

but curious of how can reduce collection of functions 1 function, using compose or andthen.

the problem using compose or andthen they're built function interface , type -- both compile-time , runtime types -- of functions return function , not unaryoperator or subinterface such you've defined. example, suppose have

unaryoperator<string> = s -> s + "bar"; unaryoperator<string> b = s -> s + s; 

one might think write

unaryoperator<string> c = a.compose(b); 

but doesn't work! instead, 1 has write

function<string, string> c = a.compose(b); 

for work, unaryoperator have provide covariant overrides of andthen , compose. (arguably bug in api.) you'd same in subinterface. or, it's simple enough write out lambdas hand. example,

interface myoperator extends unaryoperator<string> { }  public static void main(string[] args) {     list<myoperator> list =         arrays.aslist(s -> s + "bar",                       s -> "[" + s + "]",                       s -> s + s);      myoperator composite =         list.stream()             .reduce(s -> s, (a, b) -> s -> b.apply(a.apply(s)));      system.out.println(composite.apply("foo")); } 

this prints out [foobar][foobar]. note i've used two-arg form of reduce in order avoid having deal optional.

alternatively, if you're doing function composition lot, reimplement methods need in own interface. it's not hard. these based on implementations in java.util.function concrete string type i've been using in example substituted generics.

interface myoperator extends unaryoperator<string> {     static myoperator identity() {         return s -> s;     }      default myoperator andthen(myoperator after) {         objects.requirenonnull(after);         return s -> after.apply(this.apply(s));     }      default myoperator compose(myoperator before) {         objects.requirenonnull(before);         return s -> this.apply(before.apply(s));     } } 

this used follows:

myoperator composite =     list.stream()         .reduce(myoperator.identity(), (a, b) -> a.andthen(b)); 

whether bulking interface in order write andthen instead of nested lambda matter of taste, guess.


Comments

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

ios - Change Storyboard View using Seague -