1

I have list of http query params in NamveValuePair format and a WebTarget (javax/ws/rs/client/WebTarget.java). Then I am simply attaching those query params to WebTarget one by one using imperative approach.

I know that it's easy to apply stream when all the elements are in the data type. But I failed to apply the same solution when they are not.

This is the code I wan to rewrite using Java Streams API


 public WebTarget attachQueryParams(List<NameValuePair> queryParams, WebTarget webTarget) {

    for (NameValuePair param : queryParams) {
      webTarget = webTarget.queryParam(param.getName(), param.getValue());
    }
    return webTarget;
  }

I tried to rewrite it using stream reduce function as follows with no luck so far:

queryParams.stream().reduce(webTarget,((webTarget1, pair) -> webTarget1.queryParam(pair.getName(),pair.getValue())))
Turdaliev Nursultan
  • 2,538
  • 1
  • 22
  • 28
  • What is the problem, the error ? – azro Apr 10 '20 at 07:50
  • `webTarget1`s data type is `NameValuePair` instead of `WebTarget`. Therefore applying `queryParam` is not possible. – Turdaliev Nursultan Apr 10 '20 at 07:51
  • What's wrong with the for loop? Why do you want to rewrite it? – Olivier Apr 10 '20 at 07:51
  • I prefer more `pure function` approach, and this for loop is modifying webTarget on each loop. – Turdaliev Nursultan Apr 10 '20 at 07:56
  • Keep your for loop that is much more readable and elegant. – Ravindra Ranwala Apr 10 '20 at 08:10
  • I honestly love the functional approach most of the times but in Java it seems a bit...off. Sometimes it seems it's making me jump through hoops for something that should be trivial. Not *all* stream operations are like that, mind you, but `reduce` certainly is. The process of "reduce a bunch of type `A`s reduce them to type `B`" is pretty much idiomatic. Yet in Java, you either need to use the three parameter method (which I always have to lookup how exactly it expects to work) or do something like cascading Collectors to get the same result. I find it ugly. I'd also suggest keeping the loop. – VLAZ Apr 10 '20 at 08:24

1 Answers1

3

You can try something like this:

queryParams.stream()
        .reduce(webTarget,
                (webTarget1, pair) -> webTarget1.queryParam(pair.getName(),pair.getValue()),
                (v1, v2) -> v1);

Why you need third parameter you can find out here

lczapski
  • 4,026
  • 3
  • 16
  • 32