0

I have a question regarding the Comparator interface. Below my class implements the interface to sort strings by length instead of by the default sort which sorts by character value.

After overriding the default compare, I used Arrays.sort() to sort my string array. Even though I have overridden the default method, if I use Arrays.sort, it calls the default compare instead of my overridden method. Is this because I am explicitly calling the super class method?

The other question is initializing the interface itself. I know you cannot initialize an interface and instead initialize a class object (that implements said interface) to reference the methods available to the interface. In this case, when I initialize a comparator, Arrays.sort(strArr, new Ideone()); the sort works correctly. How does the method know that I am passing it a comparator? I only initialized a class object and didn't call the compare(ob1, ob2) method explicitly.

Even if I do Comparator x = new Ideone();, how is the class object reduced to a comparator object? Any explanation on this would be helpful.

import java.util.*;
import java.lang.*;
import java.io.*;

/* Name of the class has to be "Main" only if the class is public. */
class Ideone implements Comparator
{

    static String ThirdGreatest(String[] strArr)
    { 
        Arrays.sort(strArr);
        //Arrays.sort(strArr, new Ideone());
        for(String x: strArr)
            {
            System.out.println(x);
            }
        return strArr[strArr.length-3];
    } 

    @Override
    public int compare(Object s1, Object s2)
    {
        return (s1.toString().length() - s2.toString().length());
    }

    public static void main (String[] args) throws java.lang.Exception
    {
        String[] myarr = {"coder","byte","code", "asfasfasfasf"};
        System.out.println(ThirdGreatest(myarr));
    }
}
4
  • 1
    You have not told sort to use your comparator. This is also a strange way to set up a comparator. See stackoverflow.com/questions/8632857/… for an example. Commented Aug 14, 2015 at 20:23
  • You might want to check that strArr has at least 3 elements too. Commented Aug 14, 2015 at 20:24
  • I recommend separating your comparator implementation from your main class. It is easier to understand when the comparator is just the comparator and doesn't have extraneous static methods in it. Commented Aug 14, 2015 at 20:26
  • @dsh yes I think I will do that in the future! Commented Aug 14, 2015 at 20:32

3 Answers 3

5

Even though I have overridden the default method, if I use Arrays.sort, it calls the default compare instead of my overridden method. Is this because I am explicitly calling the super class method?

No, it's because in the example you've given, you don't pass in the comparator - so the sort method has no way of know that you're trying to use a custom comparison.

In this case, when I initialize a comparator, Arrays.sort(strArr, new Ideone()); the sort works correctly. How does the method know that I am passing it a comparator?

Because you're calling the overload that accepts a comparator. There is only one overload with two parameters:

public static <T> void sort(T[] a, Comparator<? super T> c)

Now admittedly it would be better if you implemented Comparator<String> instead of the raw Comparator type, but it's still valid.

I only initialized a class object and didn't call the compare(ob1, ob2) method explicitly.

Indeed - you don't have to call compare. That's the job of the sort method. You pass the comparator in so that it can call compare.

Sign up to request clarification or add additional context in comments.

3 Comments

That helps! I didn't realize that I was only overriding the 2 parameter and expected it be called automatically by the default sort call.
Sorry meant to say, I didn't realize after overriding compare, I had to pass in a Comparator so that it would use my custom compare method. I was under the assumption that it would be called by default once I overrode it on my class. I have to read up on this subject.
@Help123: Right, no. Without passing an instance to the sort method, it has no way of working out what the context is. Glad it helped.
2

I think the issue here is that while you've created a comparator for use in Arrays.sort, you haven't actually told Arrays.sort to use it. By default, if you just say

 Arrays.sort(strArr);

then the strings will be sorted using the default comparator. To tell the sorting algorithm to use your custom comparator, you need to pass it as a second argument to the method:

 Arrays.sort(strArr, new Ideone());

Try seeing if that fixes things. As a fun test, put a println statement in your comparison function to see if you can watch it getting called.

That said, it's pretty unusual to implement the comparator this way. A more common route would be to do something like this:

 Arrays.sort(strArr, new Comparator<String>() {
     public int compare(Object s1, Object s2) {
       return (s1.toString().length() - s2.toString().length());
     }
 });

Now, you don't need to implement compare on the Ideone class, which makes clearer that (1) it's not going to get called automatically, and (2) you only need it for this one sorting step.

2 Comments

This definitely helps. I am assuming that you are using an anonymous class to create a comparator to pass it into the sort method.
@Help123 Yep, that's exactly it. Generally speaking, if you need a one-time comparator, this is a pretty good way to make one!
0
Arrays.sort(strArr)

This sorts an array of string objects using the java comparator. You haven't told your sort function to use the compare function you created. There needs to be a reference to your Ideone class.

Comparator x = new Ideone();

Because Ideone() implements Comparator, it must implement all the methods within the Comparator interface. The variable x would use the compare method of the Ideone class as it is overridden. However, if you try to use a method from the Ideone class that isn't in the Comparator class then you'll throw an exception.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.