Search code examples
javafunctional-programmingjax-rsjava-streampurely-functional

Repeated application of parameters from a stream to a fluent builder method


I'm writing a REST service client using the Jax-RS. For a request I'd like to add query parameters. The according method in Jax-RS is webTarget.queryParam(name, value) returning a new WebTarget instance (so webtarget is immutable).

Further, I have a stream of name-value-pairs: Stream<Tuple<String,String>> queryParams with a varying number of elements.

Now I'd like to repeatedly apply the parameters from the stream to the queryParam() method, using the result as invocation target on the next application:

As rolled out invocation it would look like this:

WebTarget original = ...
WebTaragt wt1 = original.queryParam(t1.name,t1.value);
WebTaragt wt2 = wt1.queryParam(t2.name,t2.value);
...
WebTarget wtFinal = wtNminus1.queryParam(tN.name,tN.value);

Is there a way to efficiently implement this as pure function?


Solution

  • I can not yet make a statement about the efficiency, but, you may want to look into Stream.reduce. The following solution assumes that you have at least one WebTarget which you can use to carry out the reduction. Moreover I this solution doesn't allow parallelization (for that an appropriate combiner would be needed and I do not know how the WebTargets need to be combined).

    Stream<Tuple<String, String>> queryParamStream = ...
    WebTarget wtFinal = queryParamStream.reduce(original,
                            (webtarget, tuple) -> webtarget.queryParam(tuple.name, tuple.value),
                            (webtarget1, webtarget2) -> /* what would be needed to combine those when you use a parallel stream? */ webtarget2);