0

Recently I'm trying to get more familiar with the Comparator interface in Java. I have an exercise which is about to sort the ArrayList of strings from the shortest to longest. I used a Comparator of Strings. When searching the net, I found the following solution proposal:

    public static Comparator<String> lengthComparator = new Comparator<String>() {
    @Override
    public int compare(String a, String b) {
        if (a.length() == b.length()) {
            return a.compareTo(b);
        } else {
            return (a.length() > b.length() ? 1 : -1);
        }
    }

};

Then I used it in my code to sort the set:

Collections.sort(set, lengthComparator);

And it worked. What I'd like to ask is the specific way of defining the lengthComparator object here. We create a new object:

new Comparator<String>()

with the default constructor. But then there is a further code with overwritten method in "{}" brackets. Is it a normal way of creating objects? I've never met it before and I'd like to learn more about it. Could you please advise me some referal materials where I can find more informations about it?

derivee
  • 23
  • 3

2 Answers2

4

Yes this is a common way to create objects, it is called anonymous class.

Comparator is an interface, and you want a class to be instantiated, so you create an object from an anonymous class that implements Comparator.


Anonymous class example

public void sortSetByStringLength(Set set) {
    Comparator<String> lengthComparator = new Comparator<String>() {
        @Override
        public int compare(String a, String b) {
            if (a.length() == b.length()) {
                return a.compareTo(b);
            } else {
                return (a.length() > b.length() ? 1 : -1);
            }
        }
    }

    Collections.sort(set, lengthComparator);
}


Regular class example

public class LengthComparator implements Comparator<String> {
    @Override
    public int compare(String a, String b) {
        if (a.length() == b.length()) {
            return a.compareTo(b);
        } else {
            return (a.length() > b.length() ? 1 : -1);
        }
    }
}

And in your program sort a list this way :

public void sortSetByStringLength(Set set) {
    Collections.sort(set, new LengthComparator());
}
Anthony Raymond
  • 7,434
  • 6
  • 42
  • 59
1

I'm not sure what's the exact question but as it was already said : What you have instanciated is an anonymous class. Indeed, as you already know an interface cannot be instanciated.

So, when you do :

new Comparator<String>()
{
@Override
public int compare(String o1, String o2) {
// TODO Auto-generated method stub
return 0;
}
});

it is like you've created a class called let's say : LengthComparator like this :

public class LengthComparator implements Comparator<String>{
public LengthComparator()
{

}

    @Override
    public int compare(String o1, String o2) {
        int ack = 0;

        if(o1 == null && o2 == null){
            ack = 0;
        }
        else if(o1 != null && o2 == null){
            // Decide what you should do here !
            // returnValue = ???
        }
        else if(o1 == null && o2 != null){
            // Decide here, too !
            // returnValue = ???
        }
        else{

            if(o1.length() == o2.length()){
                // Sort by order ...
                ack = o1.compareTo(o2);
            }
            else{
                ack = o1.length() > o2.length() ? 1 : -1;
            }
        }

        return ack;
    }
}

As a personal advice, always check your arguments toward null values as you don't really know what is going to be passed in...

Jdaydai
  • 101
  • 1
  • 8