Comparable
interface
The Comparable
interface defines a type's natural ordering. Suppose you have a list of String
or Integer
objects; you can pass that list to
Collections.sort(list);
and you will have a sorted list. How? Because String
and Integer
both implement Comparable
interface and the implementations of Comparable
interface provide a natural ordering. Its like the class definition saying - "If you find a collection of objects of my type, order them according to the strategy I have defined in the compareTo
method".
Now when you define your own type, you can define the natural ordering of the objects of your class by implementing the Comparable
interface. See the Java documentation for more information on object ordering.
Comparator
interface
The Comparator
interface describes how to define custom strategies for object ordering. Suppose we have a simple Person
type as below:
public class Person {
String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Now, by implementing the Comparator
interface, you can write different strategies to order the instances of your Person
type. For example, consider the two strategies for ordering Person
objects given below:
class StrategyOne implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return p1.getName().length() - p2.getName().length();
}
}
class StrategyTwo implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return p1.getName().compareTo(p2.getName());
}
}
Here, StrategyOne
will order Person
objects based on the length of their names, and StrategyTwo
will order Person
objects based on lexicographic ordering of their names.
The ways to implement Comparator
As you can see, the concrete strategy classes are stateless, hence all instances are functionally equivalent. So, we just need a single instance of any concrete strategy class. Thus, it should be a singleton. Using anonymous classes will create a new instance each time the call is executed. Consider storing the object in a private static final field and reusing it by using static factory methods to access them. For example, you can reuse the above two concrete strategies as below:
class Strategies {
private static final Comparator<Person> PERSON_NAME_LENGTH_COMPARATOR = new StrategyOne();
private static final Comparator<Person> PERSON_NAME_LEXICAL_COMPARATOR = new StrategyTwo();
public static Comparator<Person> personNameLengthComparator(){
return PERSON_NAME_LENGTH_COMPARATOR;
}
public static Comparator<Person> personNameLexicalComparator(){
return PERSON_NAME_LEXICAL_COMPARATOR;
}
}
Summary
To summarize, the Comparable
interface is used to define the natural ordering of a class, and the Comparator
interface is used to define particular strategies for object ordering.
Thats not how you should to it. Don't subclass PriorityQueue
.
The easiest thing would be to implement Comparable<Adjacency>
in your Ajacency
class.
In your case this could go like this:
public class Adjacency implements Comparable<Adjacency> {
public int vertex;
public double weight;
public Adjacency(int v, double w) {
vertex = v;
weight = w;
}
@Override
public int compareTo(Adjacency other) {
return Double.compare(this.weight, other.weight);
}
}
Best Answer
You have to pass an object of the comparator:
Update:
This is just a suggestion. Instead of defining a class, use anonymous class (which I think is a good candidate) for this kind of situation.
e.g.