我想使用PriorityQueue
对图表进行拓扑排序。为简洁起见,我想为比较器使用匿名内部类。但是,我需要访问图g
才能确定我正在查看的节点的程度。这可能吗?
/**
* topological sort
* @param g must be a dag
*/
public static Queue<String> topoSort(DirectedGraph<String, DefaultEdge> g) {
Queue<String> result = new PriorityQueue<String>(g.vertexSet().size(),
new Comparator<String>() {
DirectedGraph<String, DefaultEdge> 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;
}
更正后的代码
/**
* topological sort
* @param g must be a dag
*/
public static Queue<String> topoSort(final DirectedGraph<String, DefaultEdge> g) {
Queue<String> result = new PriorityQueue<String>(g.vertexSet().size(),
new Comparator<String>() {
@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;
}
答案 0 :(得分:11)
是的,最后决定:
public static Queue<String> topoSort(final DirectedGraph<String, DefaultEdge> g) {
请参阅The Final Word On the final Keyword:
匿名本地类
涉及最终的第二种情况 变量实际上是由强制要求的 语言语义学。在那种情况下, Java编译器不会让你使用 变量,除非它被声明为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 } }; }
这种限制的原因 如果我们发现一些亮光就会变得明显 如何实施本地类。 匿名本地类可以使用本地 变量因为编译器 自动给出一个班级 用于保存副本的私有实例字段 该类使用的每个局部变量。 编译器还添加了隐藏 每个构造函数的参数 初始化这些自动创建 私人领域。因此,一个本地班 实际上并不访问本地 变量,但仅仅是它自己的私有 他们的副本。唯一的方法就是这样 正确的工作是如果当地的 变量被声明为final,所以 他们保证不会改变。 有了这个保证到位, 当地的班级确信它的 变量的内部副本 准确反映当地的实际情况 变量
答案 1 :(得分:2)
如果在内部类中使用局部变量,编译器将为内部类生成实例字段,并将局部变量值复制到其中。现在,如果局部变量发生变化,则instancs变量值仍将具有旧值。因此,为了使局部变量值与实例字段相同且不可变,它是最终的。
答案 2 :(得分:0)
仅供参考,google collections您也可以选择
Ordering.natural().onResultOf(
new Function<String, Integer>() {
public Integer apply(String arg) {
return g.inDegreeOf(arg);
}
});
除非您可以找到该功能的其他用途,否则这并不一定能为您节省大量的输入,但它确实可以防止您经常陷入手动比较器实现的错误。