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



Thursday, August 14, 2014

How to use Comparable and Comparator in Java

Comparable

A class that implements the Comparable interface can have its instances compared with each other. You use Comparable when you want to sort objects based on natural order. The class overrides the compareTo method and compares the this reference with another instance of the object.

Here is a usage example.

public class Person implements Comparable {

 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;
 }
 
 @Override
 public int compareTo(Person p) {
  if (this.getAge() > p.getAge()) 
   return 1;
  else if (this.getAge() < p.getAge())
   return -1;
  else 
   return 0;
 }
 
} 

Now, try this class using Arrays.sort as shown below.

public class SortPersonObjects {

 public static void main(String[] args) {
  
  Person p1 = new Person("Bianca", 18);
  Person p2 = new Person("Juancho", 14);
  Person p3 = new Person("Raymond", 10);
  
  Person[] persons = new Person[];
  
  persons[1] = p1;
  persons[2] = p2;
  persons[3] = p3;
  
  Arrays.sort(persons);
  
  for (Person person: persons) {
   System.out.println("Name: " + person.getName() + " " + person.getAge());
  }
 }
}

You will get the output below.

Name: Raymond 10
Name: Juancho 14
Name: Bianca 18


Comparator

A class that implements the Comparator interface will be a comparator for two objects provided to it. You use Comparator if you want to sort based on multiple properties of an object.

You use Comparator to sort objects by:

  • Passing the Comparator to a sort method such as Collections.sort() and Arrays.sort()
  • To allow precise control over the sort order
  • To control the order of some data structrures such as sorted sets and sorted maps

Here is a Comparator example 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;
     }
     
 }


Here is a usage example of the Comparator class.

public class SortPersonObjectsByComparator {

 public static void main(String[] args) {
  
  Person p1 = new Person("Bianca", 18);
  Person p2 = new Person("Juancho", 14);
  Person p3 = new Person("Raymond", 10);
  
  ArrayList<Person> persons = new ArrayList<Person>();
  
  persons.add(p1);
  persons.add(p2);
  persons.add(p3);
  
  Collections.sort(persons, new PersonComparator());
  
  for (Person person: persons) {
   System.out.println("Name: " + person.getName() + " " + person.getAge());
  }
 }
}

The new output you get is shown below.

Name: Bianca 18
Name: Juancho 14
Name: Raymond 10

Summary
By implementing Comparable, you're making sorting a fundamental part of the object (like integer and String objects). By implementing Comparator, you are creating a utility that sorts objects in a specific context (object properties used) to order them in a certain way.

Resources:
Comparable interface documentation
Comparator interface documentation

Examples:
Examples on java object sorting - embedded Comparator example
Comparator and Comparable examples
Comparator and Comparable examples

Saturday, August 2, 2014

CSS: How to make a DIV element float on a page

This post is nothing special. It's just basic CSS. Just a note for myself. If it helps you, then great!

You can make a block element like a DIV stay at a fixed position of the screen while the page scrolls making it look like the DIV is floating.

This is pretty simple. Just apply the following CSS properties below to the element.

position: fixed;
top: 100px;
right: 5px;