在Java中实现eval()解析器和2d数组

时间:2011-12-17 15:51:30

标签: java arrays parsing 2d eval

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

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

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

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

3 个答案:

答案 0 :(得分:1)

  

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

private String [][] table_of_classifiers = null;

不是真的。这是变量的声明和初始化,它可以指向“2d数组”,“表”或更确切地说是字符串的“数组数组”。

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

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

除非a未在同一时间初始化,否则不会编译。这是一件好事,因为你可以避免潜在的错误。

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

然而,这将编译,如果你忘了实际为变量分配一个真正的数组,程序将“崩溃”一个“空指针异常”,或者你需要添加额外的代码/工作来检查{{1 }}

  

我填写这样的内容:

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代替。


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

然而,反射和CLass类型是一个复杂的问题,考虑到你显然正在努力学习最基本的Java概念,你还有很长的路要走,直到你能够做你想做的事。

答案 1 :(得分:0)

只是做:

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。不过,这几乎肯定不是你想要做的最好的方法。

答案 2 :(得分:0)

关于您的第一个问题:要分配给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将支持哪些功能,否则你只会对你给出的所有要求感到失望结果证明是不可能的。