【问题标题】:ImplementIon of eval() parser and 2d array in JavaJava 中 eval() 解析和二维数组的实现
【发布时间】:2011-12-17 15:51:30
【问题描述】:

我确实陷入了两个与 Java 相关的问题。一个简单,一个更难。

关于二维数组的创建,我这样初始化一个表:

private String [][] table_of_classifiers = null;

然后,在一个函数中,我像这样填充它的内容:

        String [][] table_of_classifiers = {
            {"x1","x","x","x","x"},
            {"x2","x","x","x","x"},
            {"x3","x","x","x","x"},
            {"x4","x","x","x","x"},
            {"x5","x","x","x","x"},
            {"x6","x","x","x","x"},
        };

但是您可以猜到第二个表会覆盖(本地)第一个表,这当然不是我想要做的。我做错了什么?请注意,表格的维度从一开始就未知。

【问题讨论】:

标签: java arrays parsing 2d eval


【解决方案1】:

关于二维数组的创建,我这样初始化一个表:

private String [][] table_of_classifiers = null;

不是真的。这是一个变量的声明和初始化,它可以指向一个“二维数组”、“表”或更确切地说是一个字符串的“数组数组”。 p>

除非您处理变量可以/将为 null 的事实,否则将其初始化为 null 通常是一个坏主意,因为您需要做额外的工作来检查 null。例子:

String[][] a;
// ...
String b = a[0][0];

这不会编译,除非a 同时没有被初始化。这是一件好事,因为您可以避免潜在的错误。

String[][] a = null;
// ...
String b = a[0][0];

但是这将编译,如果您忘记实际为变量分配一个真正的数组,程序将“崩溃”并出现“空指针异常”,或者您需要添加额外的代码/工作来检查null .

我这样填充它的内容:

String [][] table_of_classifiers = {
  {"x1","x","x","x","x"},
  {"x2","x","x","x","x"},
  {"x3","x","x","x","x"},
  {"x4","x","x","x","x"},
  {"x5","x","x","x","x"},
  {"x6","x","x","x","x"},
};

你没有在这里“填充”任何东西。对于要填充的东西,它必须首先存在,但你还没有创造任何东西。

在这里您要声明第二个同名变量,这只有在您与第一个变量处于不同范围内时才有可能,在这种情况下,您将“隐藏”(“隐藏”)原始变量,如果它最初可以从这个新范围访问。

但是你可以猜到第二个表会覆盖(本地)第一个表 一,那当然不是我想做的。我做错了什么?

哪个“第一”表?直到现在还没有第一个表,只有第一个变量。其他人已经向您展示了如何将“表”分配给原始变量,而不是在行首使用“声明”String[][]

否则就不可能说出你“做错了什么”,因为你还没有真正解释你想要做什么。

请注意,表格的维度从一开始就未知。

不是吗?那么你如何/为什么使用数组文字呢?字面量数组用于创建具有固定“预填充”的固定大小的数组。

“开始”到底是什么意思?在编程时(编译时)或程序启动时(运行时)不知道大小吗?

如果您在运行时获得数组的大小,您可以使用new 创建一个普通数组:

int a = ...; 
int b = ...; // Get the sizes from somewhere, e.g, user input 

String[][] table_of_classifiers = new String[a][b];
// Now you have an "empty" table

如果大小在运行时“变化”,那么 - 取决于您实际尝试执行的操作 - 那么数组是错误的工具,您应该改用 List 实现,例如 ArrayList


关于“eval”,正如其他人所说,Java 是一种编译语言,使得“eval”基本上是不可能的。是“反射”或使用 Class 类型来实现您所暗示的,但您确实需要更广泛地解释您想要实现的目标,那么它可能会在这里为您提供帮助。

但是反射和 CLass 类型是一件复杂的事情,而且考虑到您显然在为最基本的 Java 概念苦苦挣扎,在您能够做您想做的事情之前,您还有很长的路要走。

【讨论】:

  • 谢谢 RoToRa。但是,没有必要提供这么多细节!答案比您最初想的要容易得多!
【解决方案2】:

只要做:

class Foo {
    private String [][] table_of_classifiers = null;

    void bar() {
        table_of_classifiers = new String[][] {
                    {"x1","x","x","x","x"},
                    {"x2","x","x","x","x"},
                    {"x3","x","x","x","x"},
                    {"x4","x","x","x","x"},
                    {"x5","x","x","x","x"},
                    {"x6","x","x","x","x"},
        };
    }
}

Java 没有eval(因为它是一种编译语言),但它确实有reflection。不过,这几乎肯定不是您想要做的任何事情的最佳方法。

【讨论】:

  • 谢谢奥利!我会保留那个回答者!您能否更具体地了解您的 eval() 解决方案?
【解决方案3】:

关于你的第一个问题:分配给table_of_classifiers而不重新声明它,写:

        table_of_classifiers = new String[][] {
            {"x1","x","x","x","x"},
            {"x2","x","x","x","x"},
            {"x3","x","x","x","x"},
            {"x4","x","x","x","x"},
            {"x5","x","x","x","x"},
            {"x6","x","x","x","x"},
        };

关于eval 。 . .问题是运行时没有作用域局部变量的名称,虽然它可以获取实例变量的名称,但它必须在对象的上下文中这样做。解决这类问题是可能的,但这并不重要,而且会涉及重大妥协。我认为您必须彻底了解范围界定的工作原理以及反射的工作原理您开始弄清楚eval 将支持哪些功能,否则您只会对您给出的所有要求感到失望结果是不可能的。

【讨论】:

  • 谢谢你!但是,我正在寻找一个两步实施。你能帮我看看如何创建解析器吗?这对我来说非常重要,因为这样我就可以编写更紧凑且可维护的代码!
  • @eualin:我向您保证,创建自己的 eval,从头开始编写自己的解析器,不会 使代码更加紧凑和可维护。您的其余代码可能更紧凑,但解析器本身将是巨大的、复杂的和错误的。
  • 谢谢@ruakh。那么,你会推荐我什么?任何具体的例子/方法?我认为我们无法找到解决该问题的方法……我并不是说这很简单,我只是说至少考虑到上述要求,这根本不应该那么困难…… .
  • @eualin:我有点困惑。您已经接受了 Oli Charlesworth 的回答。你不满意吗?
  • 如果您仔细阅读了该评论,您就会明白我仍在尝试弄清楚如何为 Java 实现一个手工制作的 eval() 函数。有什么想法吗?
猜你喜欢
  • 2014-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-18
  • 1970-01-01
  • 2014-12-26
  • 1970-01-01
相关资源
最近更新 更多