I want to use a PriorityQueue to do a topological sort on a graph. For brevity, I'd like to use an anonymous inner class for the comparator. However, I need access to the graph g in order to determine the in degree of the nodes I'm looking at. Is this possible?
/**
* topological sort
* @param g must be a dag
*/
public static Queue topoSort(DirectedGraph g) {
Queue result = new PriorityQueue(g.vertexSet().size(),
new Comparator() {
DirectedGraph g;
@Override
public int compare(String arg0, String arg1) {
if (g.inDegreeOf(arg0) < g.inDegreeOf(arg1)) {
return -1;
}
if (g.inDegreeOf(arg0) > g.inDegreeOf(arg1)) {
return 1;
}
return 0;
}
});
result.addAll(g.vertexSet());
return result;
}
CORRECTED CODE
/**
* topological sort
* @param g must be a dag
*/
public static Queue topoSort(final DirectedGraph g) {
Queue result = new PriorityQueue(g.vertexSet().size(),
new Comparator() {
@Override
public int compare(String arg0, String arg1) {
if (g.inDegreeOf(arg0) < g.inDegreeOf(arg1)) {
return -1;
}
if (g.inDegreeOf(arg0) > g.inDegreeOf(arg1)) {
return 1;
}
return 0;
}
});
result.addAll(g.vertexSet());
return result;
}
解决方案
Yes, make it final:
public static Queue topoSort(final DirectedGraph g) {
Anonymous Local Classes
The second situation involving final
variables is actually mandated by
language semantics. In that situation,
the Java compiler won't let you use a
variable unless it is declared final.
This situation arises with closures,
also known as anonymous local classes.
Local classes can only reference local
variables and parameters that are
declared final.
public void doSomething(int i, int j)
{
final int n = i + j; // must be declared final
Comparator comp = new Comparator()
{
public int compare(Object left, Object right)
{
return n; // return copy of a local variable
}
};
}
The reason for this restriction
becomes apparent if we shed some light
on how local classes are implemented.
An anonymous local class can use local
variables because the compiler
automatically gives the class a
private instance field to hold a copy
of each local variable the class uses.
The compiler also adds hidden
parameters to each constructor to
initialize these automatically created
private fields. Thus, a local class
does not actually access local
variables, but merely its own private
copies of them. The only way this can
work correctly is if the local
variables are declared final, so that
they are guaranteed not to change.
With this guarantee in place, the
local class is assured that its
internal copies of the variables
accurately reflect the actual local
variables.