使用流映射和过滤java中对象集合的最佳实践
我有一个自定义实体列表,我想从中使用一种方法计算字段,
接下来我要过滤。我对java流相当陌生,
我不知道是使用map和filter更好,还是使用更传统的forEach
。
以下是我的第一次尝试:
public List<Restaurant> findRestaurantsWithin(Double latitude, Double longitude, Integer radius) {
log.info("Searching restaurants {} km to point {} lat., {} long.", radius, latitude, longitude);
List<Restaurant> restaurants = this.restaurantRepository.findAll();
restaurants.forEach(restaurant ->
{
if (restaurant.getLatitude() != null) {
restaurant.setDistance(
this.getDistance(Double.parseDouble(restaurant.getLatitude()),
Double.parseDouble(restaurant.getLongitude()), latitude, longitude)
);
}
}
);
return restaurants.stream()
.filter(restaurant -> restaurant.getDistance() <= radius)
.sorted(Comparator.comparing(Restaurant::getDistance))
.skip(size * page - 1)
.limit(size)
.collect(Collectors.toList());
下面是第二点:
return this.restaurantRepository.findAll().stream()
.filter(restaurant ->
{
if (restaurant.getLatitude() != null) {
Double distance = this.getDistance(Double.parseDouble(restaurant.getLatitude()), Double.parseDouble(restaurant.getLongitude()), latitude, longitude);
if (distance <= radius) {
restaurant.setDistance(distance);
return true;
}
}
return false;
})
.sorted(Comparator.comparing(Restaurant::getDistance))
.skip(size * page - 1)
.limit(size)
.collect(Collectors.toList());
在第二个问题上,我可能应该首先使用.map
,但我不确定性能是否会有差异。有没有更好的练习或更优雅的方式来达到这个目的?
谢谢
# 1 楼答案
我想说
Restaunt::setDistance
是这里最大的代码味道。每家餐厅都有能力拥有一处房产,上面写着它离其他任意地点有多远。我们不知道这一点在哪里或什么地方,也不知道它是何时设定的。这不是一家餐厅的真正财产,它只是一个黑客副作用和函数式编程通常也不能很好地结合在一起,这也是你觉得两个例子都很笨拙的另一个原因
下面是我如何使用一个通用的
Pair
类(有很多,但具体的实现应该无关紧要。Java FX在我认为Java 11中被删除了,但是如果您使用的是之前的Java版本,javafx.util.Pair
不需要依赖项)