Tuesday, August 19, 2014

How to sort a Map in Java

Using a sorted map in java is fairly straight-forward. You simply use a TreeMap. A map that implements the SortedMap interface. A TreeMap is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.

All keys inserted into a sorted map must implement the Comparable interface, such as String and Date objects.

So if your map's key is a String then you are all set.

But if your map's key is a user-defined object, then what should you do?

It's simple. Use a Comparator class for your map's key.

Here's a usage example.

Let's create a Person class.

public class Person {

 private String name;
 private int age;
 
 public Person(String name, int age) {
  this.name = name;
  this.age = age;
 }
 public String getName() {
  return name;
 }
 
 public void setName(String name) {
  this.name = name;
 }
 
 public int getAge() {
  return age;
 }
 
 public void setAge(int age) {
  this.age = age;
 }
}

 Create a Comparator for the Person class.

 public class PersonComparator implements Comparator<Person> {
     
     public PersonComparator() {}
        
     public int compare(Person person1, Person person2) {
         String name1 = person1.getName().toUpperCase();
         String name2 = person2.getName().toUpperCase();
         //ascending order        
         if ( (name1 == null || "".equals(name1.trim())) && (name2 == null || "".equals(name2.trim())) ) {
             //both names are empty 
             return 0;
         } else if ( (name1 == null || "".equals(name1.trim())) ) {
             // first bean has no name -- second should come before
             return 1;
         } else if ( (name2 == null || "".equals(name2.trim())) ) {
             // second bean has no name -- first should come before
             return -1;
         }
         if (name1 != null && !"".equals(name1.trim()) && name2 != null && !"".equals(name2.trim())) {
             return name1.compareToIgnoreCase(name2);
             //use below for descending order - also change conditions above
             //return name2.compareToIgnoreCase(name1);
         } 
         return 0;
     }
     
 }

Now, to have a sorted map with the Person class as the key, instantiate your map using the TreeMap constructor that accepts a Comparator argument - "TreeMap(Comparator<? super K> comparator)".

Here's the usage example.

public class TestSortedMap {
 
  public static void main(String[] args) {
 
  // instantiate a TreeMap 
  Map<Person, String> personCityMap = new TreeMap<Person, String>(new PersonComparator());
  map.put(new Person("Bianca", 18), "Torrance");
  map.put(new Person("Raymond", 10), "Los Angeles");
  map.put(new Person("Juancho", 14), "San Diego");

  // print the Person's name and age (properties of map's key) and the city (map's value) 
  for (Map.Entry<Person, String> entry : personCityMap.entrySet()) {
   System.out.println("Key : " + entry.getKey().getName() + " - " + entry.getKey().getAge() + " Value : "
    + entry.getValue());
  } 
  } 
}

The resulting map will be sorted by the Person.name property in ascending order.

Output.

Key: Bianca - 18  Value : Torrance
Key: Juancho - 14  Value : San Diego
Key: Raymond - 10  Value : Los Angeles

Resources:
Java TreeMap



No comments:

Post a Comment