-1

i am expecting the result in sorted order. But the result is different. Please help me to sort by key.

Also i tried first to have a sorted list and then from that list to Map. Even that is not working as expected.

Am expecting like this

Key is GR Value is Germany Key is IN Value is India Key is UK Value is United Kingdom Key is US Value is United States

Country.java

public class Country {
    private String countryCode;
    private String countryName;

    
    public Country(String countryCode, String countryName) {
        super();
        this.countryCode = countryCode;
        this.countryName = countryName;
    }

    public String getCountryCode() {
        return countryCode;
    }

    public void setCountryCode(String countryCode) {
        this.countryCode = countryCode;
    }

    public String getCountryName() {
        return countryName;
    }

    public void setCountryName(String countryName) {
        this.countryName = countryName;
    }

    @Override
    public String toString() {
        return "Country [countryCode=" + countryCode + ", countryName=" + countryName + "]";
    }

}

Logic


public class Java8_2_ListToMap {
    public static void main(String[] args) {
        
        Map<String, String>  countryMaps1 = getSortedCountryMap(getCountryLists());
        countryMaps1.forEach((k, v) -> System.out.println("Key is " + k + " Value is " + v));

    }

    private static List<Country> getCountryLists() {
        return Arrays.asList(new Country("IN", "India"), new Country("US", "United States"),
                new Country("GR", "Germany"), new Country("UK", "United Kingdom"));
    }



    private static Map<String, String> getSortedCountryMap(List<Country> countryLists) {
        
        
        Map<String, String> countryMap  = countryLists.stream()
                .sorted(Comparator.comparing(Country::getCountryCode))
                .collect(Collectors.toMap(Country::getCountryCode, Country::getCountryName));
        return countryMap;
    }
}

Output is

Key is IN Value is India
Key is UK Value is United Kingdom
Key is GR Value is Germany
Key is US Value is United States

2 Answers2

1

By default Collectors.toMap creates a HashMap, which is not ordered. There are multiple Map implementations which are ordered and may be suitable to your use case.

You could for instance, opt to use TreeMap, which automatically sorts its keys in natural order, or by a comparator of your choice.

Another option is LinkedHashMap, which remembers the insertion order of your keys.

// TreeMap
Map<String, String> countryMap  = countryLists.stream()
        .sorted(Comparator.comparing(Country::getCountryCode))
        .collect(Collectors.toMap(Country::getCountryCode,Country::getCountryName, String::join, TreeMap::new));

// LinkedHashMap
Map<String, String> countryMap  = countryLists.stream()
        .sorted(Comparator.comparing(Country::getCountryCode))
        .collect(Collectors.toMap(Country::getCountryCode,Country::getCountryName, String::join, LinkedHashMap::new));
Jeroen Steenbeeke
  • 3,884
  • 5
  • 17
  • 26
  • Incorrect, the Map has String keys, therefore the sorting remains unchanged. Though we could leave out the `Stream.sorted` intermediate operation in that version – Jeroen Steenbeeke Nov 06 '20 at 08:45
  • 1
    ok forget what I said, you are right... sorry. – Hulk Nov 06 '20 at 08:50
  • 2
    The call to `sorted` is redundant in the first example, however - the result will be sorted by the natural ordering of the keys anyway. – Hulk Nov 06 '20 at 08:53
1

My version is very close to the first example in Jeroen's correct answer:

private static SortedMap<String, String> getSortedCountryMap(List<Country> countryLists) {        
    return countryLists.stream().collect(Collectors.toMap(
            Country::getCountryCode, Country::getCountryName, 
            String::join, TreeMap::new));
}

I've omitted the redundant call to sorted, however, and changed the retun type to SortedMap, to communicate the fact that the result is sorted through the type as well as the name of the method.


Just for comparison, this is a non-stream version:

private static SortedMap<String, String> getSortedCountryMap(List<Country> countryLists) {
    SortedMap<String, String> map = new TreeMap<>();
    countryLists.forEach(country -> map.put(country.getCountryCode(), country.getCountryName()));
    return map;
}
Hulk
  • 6,399
  • 1
  • 30
  • 52