1

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;

}
2
  • Does Edge implement Comparable<Edge>? Post its code. Commented Nov 29, 2013 at 7:22
  • You want to sort edges using their natural ordering, but they don't have any natural ordering defined. Commented Nov 29, 2013 at 7:28

2 Answers 2

2

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
     }
}
Sign up to request clarification or add additional context in comments.

Comments

0

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:

  1. Use a temporary variable:

        Comparator<? super Edge> comparator = naturalOrder();
        Collections.sort(list, comparator);
    
  2. Or specify explicitely the generic parameter:

        Collections.sort(list, MyClass.<Edge>naturalOrder());
    

    assuming that naturalOrder() is in the class MyClass.

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.