Java:从匿名内部类访问局部变量? (优先队列)

发布于 2024-08-11 07:51:18 字数 1745 浏览 6 评论 0原文

我想使用 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;
}

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<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;
}

CORRECTED CODE

/**
 * 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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

压抑⊿情绪 2024-08-18 07:51:18

是的,最终确定:

public static Queue<String> topoSort(final DirectedGraph<String, DefaultEdge> g) {

请参阅关于最终关键字的最终决定:

匿名本地类

涉及决赛的第二种情况
变量实际上是由
语言语义。在那种情况下,
Java 编译器不会让你使用
变量,除非它被声明为最终的。
这种情况是随着关闭而出现的,
也称为匿名本地类。
本地类只能引用本地的
变量和参数是
宣布最终。

public void doSomething(int i, int j)
{
  最终 int n = i + j; // 必须声明为final

  比较器 comp = new Comparator()
  {
    public int比较(对象左,对象右)
    {
      返回n; // 返回局部变量的副本
    }
  };
} 

此限制的原因
如果我们阐明一些观点就会变得显而易见
关于如何实施本地课程。
匿名本地类可以使用 local
变量,因为编译器
自动给班级一个
用于保存副本的私有实例字段
类使用的每个局部变量。
编译器还添加了隐藏
每个构造函数的参数
初始化这些自动创建的
私人领域。因此,本地类
实际上并没有访问本地
变量,但仅仅是它自己的私有变量
它们的副本。唯一的办法就是这个
正常工作是如果本地
变量被声明为final,因此
他们保证不会改变。
有了这个保证,
本地类确信其
变量的内部副本
准确反映当地实际情况
变量。

Yes, make it final:

public static Queue<String> topoSort(final DirectedGraph<String, DefaultEdge> g) {

See The Final Word On the final Keyword:

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.

屌丝范 2024-08-18 07:51:18

如果在内部类中使用局部变量,编译器会为内部类生成一个实例字段,并将局部变量值复制到其中。现在,如果局部变量发生更改,则实例变量值仍将具有旧值。因此,为了使局部变量的值与实例字段相同并且不可变,将其设置为final。

If a local variable is used in an inner class, the compiler generates a instance field for the inner class and copies the local variables value to it. Now, if the local variable changes then the instancs variable value will still be having old value. So, in order to make the local variables value same as instance field and not mutable, it is made final.

淡看悲欢离合 2024-08-18 07:51:18

仅供参考,对于 Google 收藏集,您还可以选择“

  Ordering.natural().onResultOf(
      new Function<String, Integer>() {
        public Integer apply(String arg) {
          return g.inDegreeOf(arg);
        }
      });

这并不一定可以节省您大量的打字时间”正如您所看到的,除非您可以找到该函数的其他用途,但它确实可以保护您免受手动比较器实现中经常出现的错误的影响。

FYI, with google collections you also have the option of

  Ordering.natural().onResultOf(
      new Function<String, Integer>() {
        public Integer apply(String arg) {
          return g.inDegreeOf(arg);
        }
      });

This doesn't necessarily save you a lot of typing, as you can see, unless you can find other uses for that Function, but it does shield you from the bugs that very often creep into your by-hand comparator implementations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文