1

我正在与 Jackcess 一起阅读和分类访问数据库。它只是意味着打开数据库,遍历每一行,并将满足某些条件的单个行数据打印到控制台。它工作正常,除了当我尝试读取数值时。我的代码如下。(此代码内置在 Swing GUI 中,并在按下 jbutton 时执行。)

if (inv == null) {                  // Check to see if inventory file has been set.  If not, then set it to the default reference path.
        inv = rPath;                        
}

if (inventoryFile.exists()) {                   // Check to see if the reference path exists.
        List<String> testTypes = jList1.getSelectedValuesList();
        List<String> evalTypes = jList3.getSelectedValuesList();
        List<String> grainTypes = jList2.getSelectedValuesList();

        StringBuilder sb = new StringBuilder();
        for (int i=0; i<=evalTypes.size()-1; i++) {
            if (i<evalTypes.size()-1) {
                sb.append(evalTypes.get(i)).append(" ");
            }
            else {
                sb.append(evalTypes.get(i));
            }
        }
        String evalType = sb.toString();

        try (Database db = DatabaseBuilder.open(new File(inv));) {

            Table sampleList = db.getTable("NTEP SAMPLES LIST");
            Cursor cursor = CursorBuilder.createCursor(sampleList);

            for (int i=0; i<=testTypes.size()-1; i++) {
                if ("Sample Volume".equals(testTypes.get(i))) {
                    if (grainTypes.size() == 1 && "HRW".equals(grainTypes.get(0))) {
                        switch (evalType) {
                            case "GMM":
                                for (Row row : sampleList){                                        
                                    if (null != row.getString("CURRENTGAC")) {}
                                    if ("HRW".equals(row.get("GRAIN")) && row.getDouble("CURRENTGAC")>=12.00) {
                                        System.out.print(row.get("GRAIN") + "\t");
                                        System.out.println(row.get("CURRENTGAC"));
                                    }
                                }                                    
                                break;
                            case "NIRT":
                                // some conditional code
                                break;
                            case "TW":
                                // some more code
                                break;
                         }
                    }
                    else {
                        JOptionPane.showMessageDialog(null, "Only HRW samples can be used for the selected test(s).", "Error", JOptionPane.ERROR_MESSAGE);
                    }                        
                    break;
                }

            }
        }
        catch (IOException ex) {
            Logger.getLogger(SampleFilterGUI.class.getName()).log(Level.SEVERE, null, ex);
        }

运行代码时出现以下错误:

java.lang.ClassCastException:java.lang.String 不能转换为 java.lang.Double

以下条件看起来是引发错误的原因。

row.getDouble("CURRENTGAC")>=12.00

似乎从数据库中读取数据时,程序将所有内容都作为字符串读取,即使某些字段是数字的。我试图将此字段转换为双精度,但 java 似乎不喜欢这样。我曾尝试使用 Double.parseDouble() 和 Double.valueOf() 命令来尝试转换值(如此所述)但没有成功。

我的问题是,如何将这些字段转换为数值?是在尝试键入要走的路,还是有其他我不知道的方法?您还会在代码中注意到我创建了一个游标,但没有使用它。最初的计划是用它来浏览数据库,但我从 jackcess 网页上找到了一些示例代码,并决定改用它。不确定这是否是正确的举动,但这似乎是一个更简单的解决方案。任何帮助深表感谢。谢谢。

编辑

为了确保程序从我的数据库中读取字符串值,我输入了以下代码

row.get("CURRENTGAC").getClass().getName()

输出是 java.lang.String,所以这确认它是一个字符串。正如建议的那样,我更改了以下代码

case "GMM":
    for (Row row : sampleList){
        if (null != row.get("CURRENTGAC")) 
        //System.out.println(row.get("CURRENTGAC").getClass().getName());
        System.out.println(String.format("|%s|", row.getString("CURRENTGAC")));

        /*if ("HRW".equals(row.get("GRAIN")) && row.getDouble("CURRENTGAC")>=12.00 && row.getDouble("CURRENTGAC")<=14.00) {
             System.out.print(row.get("GRAIN") + "\t");
             System.out.println(row.get("CURRENTGAC"));
        }*/                                        
    }                                    
    break;

这些更改对控制台的输出如下

|9.85| |11.76| |9.57| |12.98| |10.43| |13.08| |10.53| |11.46| ...

这个输出虽然看起来是数字,但仍然是字符串类型。因此,当我尝试使用条件语句(已在更新的示例代码中注释掉)运行它时,我仍然会遇到与之前相同的 java.lang.ClassCastException 错误。

4

1 回答 1

0

Jackcess 不会将所有值都作为字符串返回。它将检索表的字段(列)作为该 Access 字段类型的适当 Java 类型。例如,使用名为“Table1”的测试表...

ID  DoubleField  TextField
--  -----------  ---------
 1         1.23  4.56     

...以下Java代码...

Table t = db.getTable("Table1");
for (Row r : t) {
    Object o;
    Double d;
    String fieldName;

    fieldName = "DoubleField";
    o = r.get(fieldName);
    System.out.println(String.format(
            "%s comes back as: %s", 
            fieldName, 
            o.getClass().getName()));
    System.out.println(String.format(
            "Value: %f", 
            o));
    System.out.println();

    fieldName = "TextField";
    o = r.get(fieldName);
    System.out.println(String.format(
            "%s comes back as: %s", 
            fieldName, 
            o.getClass().getName()));
    System.out.println(String.format(
            "Value: %s", 
            o));
    try {
        d = r.getDouble(fieldName);
    } catch (Exception x) {
        System.out.println(String.format(
                "r.getDouble(\"%s\") failed - %s: %s", 
                fieldName, 
                x.getClass().getName(),
                x.getMessage()));
    }
    try {
        d = Double.parseDouble(r.getString(fieldName));
        System.out.println(String.format(
                "Double.parseDouble(r.getString(\"%s\")) succeeded. Value: %f", 
                fieldName, 
                d));
    } catch (Exception x) {
        System.out.println(String.format(
                "Double.parseDouble(r.getString(\"%s\")) failed: %s", 
                fieldName,
                x.getClass().getName()));
    }
    System.out.println();
} 

...产生:

DoubleField comes back as: java.lang.Double
Value: 1.230000

TextField comes back as: java.lang.String
Value: 4.56
r.getDouble("TextField") failed - java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double
Double.parseDouble(r.getString("TextField")) succeeded. Value: 4.560000

如果您无法Double.parseDouble()解析数据库中的字符串值,那么要么

  • 它们包含您发布的样本中不明显的“有趣字符”,或者
  • 你这样做是错的。

附加信息:您的示例文件

Jackcess 将 CURRENTGAC 作为字符串返回,因为它是表中的文本字段:

表格设计.png

以下 Java 代码...

Table t = db.getTable("NTEP SAMPLES LIST");
int countNotNull = 0;
int countAtLeast12 = 0;
for (Row r : t) {
    String s = r.getString("CURRENTGAC");
    if (s != null) {
        countNotNull++;
        Double d = Double.parseDouble(s);
        if (d >= 12.00) {
            countAtLeast12++;
        }
    }
}
System.out.println(String.format(
        "Scan complete. Found %d non-null CURRENTGAC values, %d of which were >= 12.00.", 
        countNotNull, 
        countAtLeast12));

...产生...

Scan complete. Found 100 non-null CURRENTGAC values, 62 of which were >= 12.00.
于 2015-05-19T20:22:56.363 回答