[英]How to optimise this filtering of list in Java
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.这里
ValidationUtil.getColorfulValues
为列表中的每个值调用三次。 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.如果您没有将代码表示为 lambda 表达式,但作为块语句,您将能够进一步简化它。
.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.当然,您可以根据使用情况将块抽象为它自己的
Predicate
。 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?目前,在您的问题中,例如,如果它是
java.lang.String
,则关联的方法color.getRGBValue()
来自哪里?
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.请注意,我使用var因为我不清楚
color.getRGBValue()
返回什么以及ValidationUtil.getColorfulValues()
返回什么。
CollectionUtils.isEmpty
considers null elements non-existing.CollectionUtils.isEmpty
认为 null 元素不存在。ValidationUtil.getColorfulValues(start, color.getRGBValue()))
only once requires mapping to it.ValidationUtil.getColorfulValues(start, color.getRGBValue()))
的过滤条件,仅需要映射一次。 But one needs to conserve the color too, to collect it in a list.record ColorWithValues
.record ColorWithValues
。 The record
class is intended for such kind of uses. record
class 旨在用于此类用途。||
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());
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.