WebTarget in Jersey client is implemented as a immutable object, and any operations to change the state returns a new WebTarget. To add query params to it, which is coming in as a Map<>
the following code was written.
public WebTarget webTarget(String path, Map<String, String> queryMap) {
WebTarget webTarget = client.target(this.address.getUrl()).path(path);
if (queryMap != null)
queryMap.entrySet().forEach(e -> webTarget.queryParam(e.getKey(), e.getValue()));
return webTarget;
}
The problems here is every call to .queryParam()
returns a new WebTarget and I'm stuck at how to accumulate as the variables used inside a lambda expression has to be either final or implicitly final, without any reassignments.
EDIT: Reduce may not be an option in this case, as WebTarget lack the mechanism for reduction, that I cannot get the queryParam from one webtarget and set it into another. if the WebTarget api had better support for accumulation, it could have been used.
Used Jool to try and leverage foldLeft which is lacking in native Java 8 API, but still hit rock bottom as WebTarget api lacked the support for it.
EDIT2: foldLeft is the way the go as suggested in the answer below, did write a small blog on this
If you want functional approach you need foldLeft(right) or reduce.
foldLeft
is implemented in some libraries, for example Functionaljava and streamEx.Functionaljava:
StreamEx:
UPD stream-reduce
You can use the ol' array trick, which is not good for anything more than a proof of concept.
You could improve it by using an AtomicReference.