Search code examples
javahashmapcomparatortreemapsortedmap

How do I sort a tree map using a comparator that uses both key and value


So I have this class where I'm trying to initialize a SortedMap using a Comparator I created in another class (separate files)

Why is this part not working?

Comparator<Map.Entry<Country, Pair<Integer, Integer>>> comparator = new SortCountryChargers();
countryChargers = new TreeMap<Country, Pair<Integer, Integer>>(comparator);

File 1:

public class Ex4 {

    private static SortedMap<Country, Pair<Integer, Integer>> countryChargers;
    
    public static void setCountryChargers(Set<ChargingStation> chargingStationSet, int Kw){
        Comparator<Map.Entry<Country, Pair<Integer, Integer>>> comparator = new SortCountryChargers();
        countryChargers = new TreeMap<Country, Pair<Integer, Integer>>(comparator);
    
        for(ChargingStation chargingStation : chargingStationSet){
            // get the charging station's country
            Country country = chargingStation.getCountry();
    
            // check if the country is already part of the hashmap
            // if not, add it
            if(!countryChargers.containsKey(country)){
                Pair<Integer, Integer> newPair = new Pair<>(0,0);
                countryChargers.put(country, newPair);
            }
    
            // update the hashmap
            // the first member of the pair is the charging stations > kw
            // the second member is the charging stations <= kw
            // first + second = total
            if(chargingStation.getkW() > Kw){
                int increment = countryChargers.get(country).getFirst() + 1 ;
                countryChargers.get(country).setFirst(increment);
            } else {
                int increment = countryChargers.get(country).getSecond() + 1 ;
                countryChargers.get(country).setSecond(increment);
            }
        }
    }

}

File 2:

public class SortCountryChargers implements Comparator<Map.Entry<Country, Pair<Integer, Integer>>> {

public int compare(Map.Entry<Country,Pair<Integer, Integer>> object1, Map.Entry<Country,Pair<Integer, Integer>> object2){

        //get the total charging station num for objects 1 and 2
        int pair1 = sumPairs(object1.getValue());
        int pair2 = sumPairs(object2.getValue());
    
        //compare total chargig station num
        if(pair1 > pair2) return 1;
        else if (pair1 < pair2) return -1;
    
        //if the total charging station num is equal, compare country names
        String country1 = object1.getKey().getName();
        String country2 = object2.getKey().getName();
        return country1.compareTo(country2);
    }
    
    //get the sum of the two members of an <integer, interger> pair
    public int sumPairs(Pair<Integer, Integer> p){
        return p.getFirst() + p.getSecond();
    }

}

I have tried reading multiple articles, but I haven't found an answer till now.


Solution

  • A TreeMap can only be sorted based on its keys, not on its entries. You are trying to use a Comparator<Map.Entry<County, Pair<Integer, Integer>>>, but this is not how TreeMap works. (It would, on the other hand, accept a Comparator<Country>.)

    If you want to sort entries based on both the key and the value, you can't do that built into the map; you must do it separately on the entrySet of a map.