1

I have the following Map:

Map<Long, List<Address>> map = new HashMap<Long, List<Address>>();

which is filled with pairs of keys and values. For example: key = student id and

value = list of Address. In Address object I have country name(String). I want to sort the total map by the country name. I have tried many ways but not getting the Idea. Any ideas? Below is my tried code.

private static Map<Long, List<Address>> sortByValue(Map<Long, List<Address>> unsortMap) {

    // Convert Map to List of Map
        List<Map.Entry<Long, List<Address>>> unSortedList =
                new ArrayList<Map.Entry<Long, List<Address>>>(unsortMap.entrySet());

    // sort the List
        Collections.sort(unSortedList, new Comparator<Map.Entry<Long, List<Address>>>() {
            public int compare(Map.Entry<Long, List<Address>> object1,
                               Map.Entry<Long, List<Address>> object2) {
            // sort by country name
                return ???;
            }
        });

     // Loop the sorted list and put it into a new insertion order Map LinkedHashMap
        Map<Long, List<Address>> sortedMap = new LinkedHashMap<Long, List<Address>>();

            for (Map.Entry<Long, List<Address>> entry : unSortedList) {
            sortedMap.put(entry.getKey(), entry.getValue());

        }
    return sortedMap;
    }
ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
madhu
  • 51
  • 1
  • 3
  • Which one out of the list do you want to compare? And what's stopping you? – shmosel May 17 '17 at 07:21
  • I want sort the total map by countryName.But key should be id – P S M May 17 '17 at 07:22
  • I think little modify in domain object it will become simple.Create student object has id and address and sort that list and then populate in a map.Or treeMap you can pass your customize Comparator. – gati sahu May 17 '17 at 07:22
  • @gatisahu I can't able to change the object as it is using in many other places – P S M May 17 '17 at 07:24
  • Why are you sorting the map by countryName and keeping the ID as key... There has to be a better way to achieve what you are trying to do – bcosynot May 17 '17 at 07:24
  • http://stackoverflow.com/questions/109383/sort-a-mapkey-value-by-values-java Sorting a map by the key is easy, just use a TreeMap. Sorting by the values is slightly more complicated, but the link I'm sending contains an answer – Danilo M. Oliveira May 17 '17 at 07:24
  • @vr3690 Because later I want to retrieve the data by id only. – P S M May 17 '17 at 07:25
  • 1
    Why do you have a list of addresses? What if they contain different countries for a single student? – shmosel May 17 '17 at 07:25
  • @PSM So why do you want to sort it if you are retrieving by ID? – bcosynot May 17 '17 at 07:26
  • @shmosel No only different address like states but country is unique for every studentId – P S M May 17 '17 at 07:27
  • Then in ur customize comparator from two key value try to comp value there in Treemap – gati sahu May 17 '17 at 07:28
  • @DaniloM.Oliveira In that example return (o1.getValue()).compareTo( o2.getValue() ); gives two list (in my case) – P S M May 17 '17 at 07:28
  • Then just pull the first address from the list and compare the country. Where are you stuck? – shmosel May 17 '17 at 07:28
  • 1
    And why is the question posted by another user? – shmosel May 17 '17 at 07:29
  • @shmosel can u pls provide sample code.I am really out... – P S M May 17 '17 at 07:29
  • @shmosel My friend just posted.We both working on same stuff. – P S M May 17 '17 at 07:30
  • `entry1.getValue().get(0).getCountry().compareTo(entry2.getValue().get(0).getCountry())` – shmosel May 17 '17 at 07:31
  • You can also reduce that whole method to a few lines with streams, but that's an exercise for another time... – shmosel May 17 '17 at 07:32

1 Answers1

1

You can create a temporary TreeMap inside the method and store the reverse mappings (i.e. country -> keys) into it. Once done, you can iterate over it and fill the values in the result, e.g.:

public static Map<Long, List<Address>> sort(Map<Long, List<Address>> map){

    //Create temporary map, sorted by countries
    Map<String, List<Long>> countryMap = new TreeMap<>();

    map.entrySet().stream()
    .forEach(e -> {
        e.getValue()
        .stream()
        .map(a -> a.country)
        .forEach(c -> countryMap.computeIfAbsent(c, k -> new ArrayList<Long>()).add(e.getKey()));
    });

    //Iterate over treemap and populate the values in result
    Map<Long, List<Address>> sortedMap = new LinkedHashMap<>();
    countryMap.entrySet()
    .stream()
    .flatMap(e -> e.getValue().stream())
    .forEach(k -> sortedMap.put(k, map.get(k)));

    return sortedMap;
}
Darshan Mehta
  • 30,102
  • 11
  • 68
  • 102