Reputation: 1027
So I'm working on a general Graph package, and I'm trying to sort my set of edges based on their natural ordering, using this method (that I'm not allowed to change):
/** Returns the natural ordering on T, as a Comparator. For
* example, if stringComp = Graph.<Integer>naturalOrder(), then
* stringComp.compare(x1, y1) is <0 if x1<y1, ==0 if x1=y1, and >0
* otherwise. */
public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
return new Comparator<T>() {
@Override
public int compare(T x1, T x2) {
return x1.compareTo(x2);
}
};
}
I have a HashSet to hold all my edges, and I want to sort them according to this method, so I'm currently doing (iteration is basically an iterator wrapper class):
/** Returns an iterator over all edges in me. If _ordered, return an iterator
over the edges in their natural ordering. */
public Iteration<Edge> edges() {
if (_ordered) {
List<Edge> list = new ArrayList<Edge>(edges);
Collections.sort(list, naturalOrder());
return Iteration.iteration(list.listIterator());
} else {
return Iteration.iteration(edges);
}
}
But Eclipse is giving me the following error under .sort:
The method sort(List<T>, Comparator<? super T>) in the type Collections
is not applicable for the arguments (List<Graph<VLabel,ELabel>.Edge>,
Comparator<Comparable<? super Comparable<? super T>>>)
I don't really understand what this means, nor how to fix it. Could anyone shed some light on the situation?
EDIT: Heres some more info about the class (excuse the off indentation):
/** Represents a general graph whose vertices are labeled with a type
* VLABEL and whose edges are labeled with a type ELABEL. The
* vertices are represented by the inner type Vertex and edges by
* inner type Edge. A graph may be directed or undirected. For
* an undirected graph, outgoing and incoming edges are the same.
* Graphs may have self edges and may have multiple edges between vertices.
*
* The vertices and edges of the graph, the edges incident on a
* vertex, and the neighbors of a vertex are all accessible by
* iterators. Changing the graph's structure by adding or deleting
* edges or vertices invalidates these iterators (subsequent use of
* them is undefined.)
*/
public abstract class Graph<VLabel, ELabel> {
/** Represents one of my vertices. */
public class Vertex {
/** A new vertex with LABEL as the value of getLabel(). */
Vertex(VLabel label) {
_label = label;
}
/** Returns the label on this vertex. */
public VLabel getLabel() {
return _label;
}
@Override
public String toString() {
return String.valueOf(_label);
}
/** The label on this vertex. */
private final VLabel _label;
}
/** Represents one of my edges. */
public class Edge {
/** An edge (V0,V1) with label LABEL. It is a directed edge (from
* V0 to V1) in a directed graph. */
Edge(Vertex v0, Vertex v1, ELabel label) {
_label = label;
_v0 = v0;
_v1 = v1;
}
/** Returns the label on this edge. */
public ELabel getLabel() {
return _label;
}
/** Return the vertex this edge exits. For an undirected edge, this is
* one of the incident vertices. */
public Vertex getV0() {
return _v0;
}
/** Return the vertex this edge enters. For an undirected edge, this is
* the incident vertices other than getV1(). */
public Vertex getV1() {
return _v1;
}
/** Returns the vertex at the other end of me from V. */
public final Vertex getV(Vertex v) {
if (v == _v0) {
return _v1;
} else if (v == _v1) {
return _v0;
} else {
throw new
IllegalArgumentException("vertex not incident to edge");
}
}
@Override
public String toString() {
return String.format("(%s,%s):%s", _v0, _v1, _label);
}
/** Endpoints of this edge. In directed edges, this edge exits _V0
* and enters _V1. */
private final Vertex _v0, _v1;
/** The label on this edge. */
private final ELabel _label;
}
Upvotes: 1
Views: 494
Reputation: 15523
There are two problems.
First Edge
should implement Comparator<Edge>
, as say other answerers:
class Edge implements Comparable<Edge> {
// ...
The second problem is that the compilator will not be smart enough to infer which T is used for naturalOrder()
when it is used like you are using it:
Collections.sort(list, naturalOrder()); // will still give the error.
There are two solutions:
Use a temporary variable:
Comparator<? super Edge> comparator = naturalOrder();
Collections.sort(list, comparator);
Or specify explicitely the generic parameter:
Collections.sort(list, MyClass.<Edge>naturalOrder());
assuming that naturalOrder() is in the class MyClass
.
Upvotes: 0
Reputation: 41945
The problem seems like the Edge
class is not implementing Comparable<Edge>
and so the compiler is giving error.
class Edge implements Comparable<Edge>{
public int compareTo(Edge o){
//implement
}
}
Upvotes: 2