Brandon
Brandon

Reputation: 1027

Unknown comparator Interface error Java

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

Answers (2)

Cyrille Ka
Cyrille Ka

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:

  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.

Upvotes: 0

Narendra Pathai
Narendra Pathai

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

Related Questions