Zakhar Borisov
Zakhar Borisov

Reputation: 39

How to realize this method only with Streams?

    /**
     * Get all cities near current city in radius.
     *
     * @param cityName - city
     * @param radius   - radius in kilometers for search
     * @throws IllegalArgumentException if city with cityName city doesn't exist.
     */
    public List<String> getCitiesNear(String cityName, int radius) {

        List<String> nearCities = new ArrayList<>();

        List<Integer> distances = new ArrayList<>();
        for (int i = 0; i < this.citiesNames().size(); i++) {
            distances.add(this.getDistance(cityName, this.citiesNames().get(i)));

        }

        for (int i = 0; i < distances.size(); i++) {
            if (distances.get(i) <= radius) {
                if (!this.citiesNames().get(i).equals(cityName)) {
                    nearCities.add(this.citiesNames().get(i));
                }
            }
        }

        return nearCities;
    }

Method citiesNames() returns List<"String">. The names of cities.

Method "int getDistance(String srcCityName, String destCityName)" returns distance between srcCityName and srcCityName.

PS: It is forbidden to use loops, iterators inside this class. Only streams and methods that accept predicates can be used. You cannot declare other fields in the class.

This is my homework)

Upvotes: 1

Views: 71

Answers (2)

Oleg Cherednik
Oleg Cherednik

Reputation: 18245

What about using separate classes to store cityName and distance? This will get you ordered list of all cities that are closer than radius to the target city.

private final Set<String> cityNames = Set.of();

public List<String> getCitiesNear(String cityName, int radius) {
    class CityDistance {

        final String cityName;
        final int distance;

        public CityDistance(String cityName, int distance) {
            this.cityName = cityName;
            this.distance = distance;
        }

    }

    return cityNames.stream()
                    .map(curCityName -> new CityDistance(cityName, getDistance(cityName, curCityName)))
                    .filter(cityDistance -> cityDistance.distance <= radius)
                    .sorted(Comparator.comparingInt(one -> one.distance))
                    .map(cityDistance -> cityDistance.cityName)
                    .collect(Collectors.toList());
}

private int getDistance(String cityNameOne, String cityNameTwo) {
    return 0;
}

Upvotes: 1

Abra
Abra

Reputation: 20914

if (citiesNames().contains(cityName) {
    return citiesNames().stream()
                        .filter(city -> getDistance(cityName, city) <= radius)
                        .collect(Collectors.toList());
}
else {
    throw new IllegalArgumentException(cityName + " not found.");
}

filter method returns a stream that contains only the near cities.
collect method creates a List containing all the elements in the filtered stream.

Upvotes: 4

Related Questions