Java的:从匿名内部类访问的局部变量? (PriorityQueue中)
-
20-09-2019 - |
题
我想使用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;
}
解决方案
是,使其最终:
public static Queue<String> topoSort(final DirectedGraph<String, DefaultEdge> g) {
请参阅一锤定音在最后关键字:
匿名局部类
涉及最终第二种情况 变量实际上是由授权 语言的语义。在这种情况下, 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,因此 他们保证不会改变。 有了这个保障到位, 局部类是有保证的,其 变量的内部副本 准确地反映当地实际 变量
其他提示
如果一个局部变量是在内部类使用的,编译器生成用于内类和拷贝的局部变量值给它的实例字段。现在,如果局部变量变化,则instancs变量的值将仍然是具有旧值。因此,为了使局部变量的值相同的实例字段和不可变,它是由最终的决定。
仅供参考,与谷歌集合你还具有的选择
Ordering.natural().onResultOf(
new Function<String, Integer>() {
public Integer apply(String arg) {
return g.inDegreeOf(arg);
}
});
这并不一定为您节省大量的输入,你可以看到,除非你能找到该功能的其他用途,但它确实从那时候经常潜入你的手比较实现的错误,保护你。