Posts Tagged With: compareTo

Multi-value Sorting in #Java

I’ve been working on trying to figure out how to sorting Notes views on-the-fly as we’re exporting to Excel and my first thought was, “Oh, that will be in the POI documentation.” I assumed that there would be a simple function in the Apache POI documentation for XSSF to sort rows and that it would also allow us to do multiple column sorts, just like we can manually in Excel. Apparently, doing this is not high on the POI team’s list of tasks.

So, after coming up dry on POI, then on Stack Overflow, I decided to check the interwebs to see what I could find. Sorting collections in Java is actually not all that hard. There are built-in functions for it, so all you have to do is issue a Collections.sort(myObject). Where it gets interesting is in how you compare the objects in the collection.

In order to determine order within the collection, all you have to do is create an integer function within the class named compareTo. Then, it will sort them based on the result returned (comparing one object at to another, not jumping six or seven places at once). So, it you want to sort on multiple values, you return them in reverse order of significance. For example, if I want to sort based on Department, then roll number, then name, I would use the following code:

if ( alphaDepartment == 0 ) {
	if ( rolldifference == 0 ) {
		return alphaName;
	}
	return rolldifference;
}
return alphaDepartment;

When the Department does not match, we return the Department order. If Department matches, we check roll number, returning the difference if it does not match. Finally, if both Department and roll number matched, we return the name order. The bulk of the work is in setting up your compareTo. While this one is hard-coded, I’m sure we’ll be able to figure out how to use variables to identify which value we want to use in our own sorting.

(I’ve dispensed with listing the setters, as they are not needed in this example.)
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@SuppressWarnings({ "unchecked" })
public class Student implements Comparable {

	private String name;
	private String rollNumber;
	private String department;

	// Constructor for the class
	public Student(String name,String rollNumber,String department){
		this.name = name;
		this.rollNumber = rollNumber;
		this.department = department;
	}
	public String toString() {
		return name + ", " + rollNumber + ", " + department;
	}
	public String getName() {
		return this.name;
	}
	public String getRollNumber() {
		return rollNumber;
	}
	public String getDepartment() {
		return this.department;
	}

	//This Function is responsible for sorting.
	public int compareTo(Object student1) {
		if (!(student1 instanceof Student))
			throw new ClassCastException("A Student object expected.");

		Student studentInput = (Student) student1;
		String thisname = this.getName();
		String thatname = studentInput.getName();
		int alphaName = thisname.compareTo(thatname);

		int rollNumb = Integer.parseInt(studentInput.getRollNumber());
		int hostObjrollNumb = Integer.parseInt(this.getRollNumber());
		int rolldifference = hostObjrollNumb - rollNumb;

		String thisDepartment = this.getDepartment();
		String thatDepartment = studentInput.getDepartment();
		int alphaDepartment = thisDepartment.compareTo(thatDepartment);

		if ( alphaDepartment == 0 ) {
			if ( rolldifference == 0 ) {
				return alphaName;
			}
			return rolldifference;
		}
		return alphaDepartment;
	}

	public static void main(String[] args) {
		List<Student> studentList = new ArrayList<Student>();

		//Create our Student objects
		Student s1 = new Student("Tom","3","CS");
		Student s2 = new Student("Jerry","1","Electronics");
		Student s3 = new Student("Merry","4","IT");
		Student s4 = new Student("Tom","2","IT");
		Student s5 = new Student("Jerry","5","IT");
		Student s6 = new Student("Merry","6","Electronics");
		Student s7 = new Student("Tom","1","CS");
		Student s8 = new Student("Jerry","2","IT");
		Student s9 = new Student("Merry","3","Electronics");

		//Add Students to our ArrayList

		studentList.add(s1);
		studentList.add(s2);
		studentList.add(s3);
		studentList.add(s4);
		studentList.add(s5);
		studentList.add(s6);
		studentList.add(s7);
		studentList.add(s8);
		studentList.add(s9);

		//The actual sort command
		Collections.sort(studentList);

		System.out.println("\nThe student list in ascending sequence is:\n");
		for (Student person : studentList) {
			System.out.println(person);
		}
	}
}

As you can see, I included the data in the Java code, since I’m trying to keep it simple. When we move forward to trying this with either the Excel sheet we’ve produced or the data before we export it to Excel, things will be more complicated. Nonetheless, I am enthused about the start I’ve made here.

There are few places that were key in helping me understand this AND from which I borrowed much of the code. On Stack Overflow, there was a question about sorting a multi-dimensional array that got me started (I’ve submitted a correction to the OP’s self-answer, since his self-answer doesn’t actually work.) While that taught me some things, none of that code appeared here. The Student object and my first exposure to how compareTo functioned came in a post on sorting a list in ascending order in Java. Other pages had mentioned compareTo, but it made more sense when I saw it there. The final, clear understanding came with sorting a collection containing user-defined objects, which thankfully also made clear to me how to loop the output properly.

Advertisement
Categories: Java, Utilities | Tags: , , , , , , | 2 Comments

Blog at WordPress.com.

%d bloggers like this: