I have the following code:
private List<String> validate(StartValue start, List<String> colors, Entity entity) {
if (!CollectionUtils.isEmpty(colors)) {
return colors.stream()
.filter(color -> ValidationUtil.getColorfulValues(start, color.getRGBValue()).isEmpty() ||
(!ValidationUtil.getColorfulValues(start, color.getRGBValue()).isEmpty() &&
ValidationUtil.getColorfulValues(start, color.getRGBValue()).contains(entity.getColor())))
.collect(Collectors.toList());
}
return colors;
}
Here ValidationUtil.getColorfulValues
is getting called thrice for each value in the list. Is there a way to optimize the filter so that we can save the value of the call?
If you would have not represented the code as a lambda expression, but as a block statement you would have been able to simplify it further.
.filter(color -> {
List<String> colourFulValues = ValidationUtil.getColorfulValues(start,
color.getRGBValue());
return colourFulValues.isEmpty() || colourFulValues.contains(entity.getColor())
}
Of course, you could abstract the block as a Predicate
of its own depending on its usage. The type of the Predicate would be the type you have chosen to represent the color. Currently, in your question, for example, if it's a java.lang.String
, where is the method color.getRGBValue()
associated from?
You can use a method reference :
private List<String> validate(StartValue start, List<String> colors, Entity entity) {
if (!CollectionUtils.isEmpty(colors)) {
return colors.stream()
.filter(this::filter)
.collect(Collectors.toList());
}
return colors;
}
private boolean filter(String color) {
var rgbVal = color.getRGBValue();
var cv = ValidationUtil.getColorfulValues(start, rgbVal);
boolean empty = cv.isEmpty();
return empty || (!empty && cv.contains(entity.getColor()));
}
Note that I use var since it is not clear to me what color.getRGBValue()
returns and also what ValidationUtil.getColorfulValues()
returns.
CollectionUtils.isEmpty
considers null elements non-existing.ValidationUtil.getColorfulValues(start, color.getRGBValue()))
only once requires mapping to it. But one needs to conserve the color too, to collect it in a list. So I introduced a record ColorWithValues
. The record
class is intended for such kind of uses. ||
is a short-circuit operator and does not need a negation of its first argument.So:
private List<String> validate(StartValue start, List<String> colors, Entity entity) {
record ColorWithValues(String color, Set<String> values) {}
return colors.stream()
.filter(Objects::nonNull)
.map(c ->
new ColorWithValues(c,
ValidationUtil.getColorfulValues(start, c.getRGBValue())))
.filter(cv -> cv.values.isEmpty() ||
cv.values.contains(entity.getColor()))
.map(cv -> cv.color)
.collect(Collectors.toList());
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.