How to use the Comparator interface

bassandguitar picture bassandguitar · Apr 21, 2013 · Viewed 45.6k times · Source

I'm new to java, and I'm not really getting how to use the comparator interface. I have an ArrayList of Items in an Inventory class and an Item class. In the Item class I wrote:

public class Item implements Comparator<Item> {
    //stuff
    ...
    @Override
    public int compare(Item a, Item b) {
        if (a.getID().compareToIgnoreCase(b.getID())>0)
            return 1;
        else if (a.getID().compareToIgnoreCase(b.getID())<0)
            return -1;
        else
            return 0;
    }
}

The getID() method just gives the id, which I have to use to alphabetize the items. I'm not sure if this is right, it made me put the @Override annotation, I'm not sure why. Also I wrote an interface that just says:

 public interface Comparator<Item>
{
    int compare(Item a, Item b);
}

I'm not sure about that bit. Also how do I implement this method to sort the arraylist created in the inventory class?

Thanks, if my question doesn't make sense or needs clarification just let me know.

Answer

ameed picture ameed · Apr 21, 2013

EDIT: First of all, a couple of things:

  1. The @Override annotation should not be mandatory. If Eclipse wants you to put it on, don't worry.
  2. Don't write your own Comparator interface. Delete that definition NAO and use the one provided by Java. Reinventing the wheel probably violates the Unspoken Code of Computer Programming in about 15 different ways. Use import java.util.Comparator; at the very top of your code (before the public class stuff) to a) use the version given by Java and b) make your code compatible with pretty much everything else that exists in the world.

The Comparator interface is not used to create a class that can put itself in order. This is the Comparable interface.

Both are similar, so I will describe both here.

java.util.Comparator

The Comparator interface, as you already know, has one method: compare. Comparator is generic (uses the angle brackets <>) and takes the type it will compare inside the <>. The thing is that Comparators are used to compare items of other classes. For example, I could create a Comparator for java.lang.Integers that returns the opposite of the "natural order" (how Integers are usually ordered).

Comparators are used mostly to give other objects a way to sort their parameters when they are not in natural order. For example, the java.util.TreeSet class takes a Comparator for its sorting capability.

java.lang.Comparable

Comparable's purpose is to say that an object can be compared. It is also generic and takes the type that it can be compared to. For example, a Comparable<String> can be compared to Strings.

Comparable has one method: compareTo(). Unlike Comparator's compare(), compareTo takes one parameter. It works like compare, except it uses the invoking object as one parameter. So, comparableA.compareTo(comparableB) is the same as comparator.compare(comparableA, comparableB).

Comparable mostly establishes the natural order for objects, and is the default way to compare objects. Comparator's role is to override this natural order when one has different needs for data comparison or sorting.

ArrayList Sorting

To sort a List, you could use the method already available: scroll down to sort on the java.util.Collections class. One method takes a Comparator, the other does not. sort is static; use Collections.sort(...), not Collections c = new Collections(); c.sort(...). (Collections doesn't even have a constructor anyway, so meh.)