I want to overwrite my objects status
value if a corresponding key/value pair can be found in my HashMap
.
Sample Model:
public class Url {
private String url;
private String status;
}
private List<Url> overwriteStatus(List<Url> myObjects) {
final var myChecklist = Map.of("www.foo.com", "blocked");
//if the key exists in `myChecklist`, then overwrite the status
myObjects.stream().forEach(item -> Optional.ofNullable(myChecklist.get(item.getUrl())).ifPresent(item::setStatus));
return myObjects;
}
My current approach with Optional
s feels very messy.
What is the best approach to check if the value exists in a HashMap
, and if so, use that value in a next step?
Documentation for the Stream API warns't against the usage of stateful streams.
Functions used in streams has to be pure, i.e. don't cause mutations of the stream elements, don't modify objects outside the stream (that's what basically happens in your code).
Your task can be fulfilled with streams without violating the guidelines mentioned above. For that, instead of changing the state if a new status
has to be applied, a new object needs to be created.
I also suggest to Url
objects immutable. So that the same instances could be safely reused in different parts of the application.
private List<Url> overwriteStatus(List<Url> myObjects,
Map<String, String> myChecklist) {
return myObjects.stream()
.map(item -> !myChecklist.containsKey(item.getUrl()) ? item :
new Url(item.getUrl(), myChecklist.get(item.getUrl())))
.collect(Collectors.toList());
}
Immutable class Url
(no setters, all fields are final
)
public class Url {
private final String url;
private final String status;
// constructor and getters
}
Note:
Optional
type, it was introduced in the JDK for only one particular purpose: to represent the return type of methods that could potentially yield null
and that's it. The practice of utilizing the Optional
just in order of chaining methods on it is considered to be an antipattern.