Search code examples
javalistalgorithmcomparatorobserver-pattern

How to apply comparator to get the TOP 5 cities from a List sorted by population?


I have a class City

public final class City {
private final String name;
private final String state;
private final int    population;

public City(String name, String state, int population) {
    this.name       = name;
    this.state      = state;
    this.population = population;
}
public String getName() {
    return name;
}
public String getState() {
    return state;
}
public int getPopulation() {
    return population;
}
@Override
public String toString() {
    return "City [name=" + name + ", state=" + state + ", population=" + population + "]";
}
}

And a class that implements Observable (not needed for this). This observable class holds an arraylist List<City> cityList that has the data for all the cities that have been reported.

My class TopFiveCities is supposed to:

"implement a getter method getTopFive() returning a list with the five top cities (in terms of population) received. The list is sorted from higher to lower numbers. The returned list must be a copy of the list kept by the observer"

Aside from just getting the top 5 list, I also need to know how to make a copy of that list from the observer.

This is what I have:

public class TopFiveCities
implements Observer {

// THIS ALSO DOESN'T WORK UNLESS THE LIST IS STATIC
// SO HOW CAN I MAKE A COPY OF THE LIST FROM OBSERVER?
private List<City> list = new ArrayList<>(CensusOffice.cityList);

public List<City> getTopFive() {
    Collections.sort(list, new Comparator<City>() {

        @Override
        public int compare(City o1, City o2) {
            return Integer.compare(o1.getPopulation(), o2.getPopulation());
        }
        
    });
    return list;
}

public void update(Observable observable) {
    if (!(observable instanceof Observable)) {
        throw new IllegalArgumentException();
    }
}
}

With this, when one of the sample outputs should be:

City [name=Chicago, state=IL, population=2746388]

I just receive a list of all the cities, sorted by population from LOWEST to HIGHEST. What I'm doing wrong?


Solution

  • You can just use a Stream, use a Comparator to sort the stream, limit the number of element and convert the elements to a new list:

    List<City> top5citiesByPopulation = cities.stream()
            .sorted(Comparator.comparing(City::getPopulation).reversed())
            .limit(5)
            .collect(Collectors.toList());