I am new to Java streams. I need to iterate over a list of objects and populate my list of errors based on my comparisons. I want to avoid using if else and use java stream. Is there a way I can do this?
public void compare(List<Tool> tools,Tool temp,List<String> error){
for(Tool t : tools){
if(!t.name.equals(temp.name() && !t.id.equals(temp.id())
errors.add(name id "not matches");
if(!t.name.equals(temp.name())
errors.add(name "not matches");
else if(!t.id.equals(temp.id())
errors.add(id "not matched");
}
class Tool{
String name;
String id;
}
CodePudding user response:
Unfortunately you need your if-else statements in this case. The stream approach would look something like this:
tools
.stream()
.filter(tool -> !tool.name.equals(temp.name) && !tool.id.equals(temp.id))
.forEach(tool -> {
errors.add(name id "not matches");
});
tools
.stream()
.filter(tool -> !tool.name.equals(temp.name))
.forEach(tool -> {
errors.add(name "not matches");
});
by this approach the exclusion of having only "errors.add(name id "not matches");" and not also "errors.add(name "not matches");" in your errors list would be gone.
The correct approach using streams therefore would look quite similar to your original implementation
tools.forEach(tool -> {
if (!tool.name.equals(temp.name) && !tool.id.equals(temp.id)) {
errors.add(name id "not matches");
} else if (!tool.name.equals(temp.name)) {
errors.add(name "not matches");
} else if (!tool.id.equals(temp.id)) {
errors.add(id "not matched");
}
});
CodePudding user response:
The filter is id or name being different. All error messages can be constructed using 1 expression by using ternaries, so you can map non matching tools to a message in one step:
public void compare(List<Tool> tools, Tool temp, List<String> error) {
tools.stream()
.filter(t -> !t.id.equals(tool.id) || !t.name.equals(tool.name))
.map(t -> (t.name.equals(tool.name) ? "" : name) (t.id.equals(tool.id) ? "" : id) "not matches")
.forEach(error::add);
}