Kristian Kraljić You may compare programming with poetry,
a harmonic script is a piece of creativity which will last forever.
- Kristian Kraljić

Generic ArrayComparator for Comparable Java types

by Kristian Kraljic, December 30, 2015

Another day, another post! The marathon continues. After watching “Star Wars: The Force Awakens” yesterday, let’s speak a few words about Open Source. Since I began releasing my projects, most of it has been released on a dedicated website or on this blog. Meanwhile GitHub is the main source for free and open source code, therefore I decided to create an own profile at: https://github.com/kristian (yay! xD)

I think GitHub is a great way to contribute to Open Source and collaborate between individuals. I’m going to release much of my stuff on GitHub, but add a few more words about it here in my blog. Some smaller snippets will stay though, such as one thing, that I was surprised is not part of the Java standard libraries yet: A generic ArrayComparator for Comparable Java types.

The task was quite simple, I wanted to sort a Collection of arrays in Java. To do so, I wanted to use a TreeMap to sort it’s elements, while adding elements to the SortedMap. Unfortunately arrays in Java do not implement the Compareable interface by default. So a Comparator was needed. Much to my surpise, I found no ArrayComparator, neither in the standard Java library code, nor on any source on the internet. Here’s my implementation of a generic ArrayComparator class:

public class ArrayComparator<T extends Comparable<T>> implements Comparator<T[]> {
	@Override public int compare(T[] arrayA, T[] arrayB) {
		if(arrayA==arrayB) return 0; int compare;
		for(int index=0;index<arrayA.length;index++)
			if(index<arrayB.length) {
				if((compare=arrayA[index].compareTo(arrayB[index]))!=0)
					return compare;
			} else return 1; //first array is longer
		if(arrayA.length==arrayB.length)
			   return 0; //arrays are equal
		else return -1; //first array is shorter 
	}
}

There is only one prerequisite for the comparator though, the generic base type of the array must implement the Comparable interface. Now sorting multi-dimensional arrays, Collections, or (Sorted)Maps really becomes a piece of cake! Let me share a few examples:

String[][] sorted = new String[][]{{"A","B"},{"B","C"},{"A","C"}};
Arrays.sort(sorted, new ArrayComparator<>());
List<String[]> sorted = new ArrayList<>();
sorted.add(new String[]{"A","B"});
sorted.add(new String[]{"B","C"});
sorted.add(new String[]{"A","C"});
sorted.sort(new ArrayComparator<>());
Map<String[],Object> sorted = new TreeMap<>(new ArrayComparator<>());
sorted.put(new String[]{"A","B"}, new Object());
sorted.put(new String[]{"B","C"}, new Object());
sorted.put(new String[]{"A","C"}, new Object());

I hope you find this little code snippet useful. Stay tuned for the forth post of my little coding marathon tomorrow.

2 Comments

  1. Harsh Gupta says:

    I wanted to sort a two dimensional array . The requirement is that it has to first sort on the basis of the first row and in case of collision look at the second row elements.
    For example,
    {5.0, 4.0}, {5.0, 1.0}, {4.0, 6.0},{5.0,10.0},{3.0,2.0}
    For this the result must be
    {3.0,2.0} {4.0,6.0} {5.0,1.0} {5.0,4.0} {5.0,10.0}

    • Hello Harsh, in case your array has only elements of length 2, you should be able to use the comparator as is. As you said it checks for the first index, just in case it is equal, it compares the second index. In case some elements have more than two values and you really only want to compare the first two, you’ll have to change arrayA.length in line 4 to 2 instead.

      Hope this helps. Regards,
      Kristian