有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用流映射和过滤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) 个答案

  1. # 1 楼答案

    我想说Restaunt::setDistance是这里最大的代码味道。每家餐厅都有能力拥有一处房产,上面写着它离其他任意地点有多远。我们不知道这一点在哪里或什么地方,也不知道它是何时设定的。这不是一家餐厅的真正财产,它只是一个黑客

    副作用和函数式编程通常也不能很好地结合在一起,这也是你觉得两个例子都很笨拙的另一个原因

    下面是我如何使用一个通用的Pair类(有很多,但具体的实现应该无关紧要。Java FX在我认为Java 11中被删除了,但是如果您使用的是之前的Java版本,javafx.util.Pair不需要依赖项)

    return restaurantRepository.findAll().stream()
        .filter(restaurant -> restaurant.getLatitude() != null)
        .map(restaurant -> new Pair<>(restaurant, this.getDistance(/*blah blah*/)))
        .filter(resAndDistance -> resAndDistance.getValue() <= radius)       
        .sorted(Comparator.comparing(Pair::getValue))
        .skip(size * page - 1)
        .limit(size)
        .collect(Collectors.toList());