使用 Jackcess 检索存储在文本字段中的数值会给出 ClassCastException
Using Jackcess to retrieve numeric values stored in a text field gives ClassCastException
我正在与 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() 命令尝试转换值(如前所述 here)但没有成功。
我的问题是,如何将这些字段转换为数值?是尝试键入要走的路,还是有其他我不知道的方法?您还会在代码中注意到我创建了一个游标,但并未使用它。最初的计划是用它来浏览数据库,但我从 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 错误。
Jackcess 不会 return 所有值都作为字符串。它将检索 table 的字段(列)作为该 Access 字段类型的适当 Java 类型。例如,测试 table 名为 "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()
解析数据库中的字符串值,那么
- 它们包含 "funny characters" 从您发布的示例中看不出来的内容,或者
- 你做错了。
有关示例文件的其他信息
Jackcess return将 CURRENTGAC 作为字符串,因为它是 table:
中的文本字段
下面的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.
我正在与 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() 命令尝试转换值(如前所述 here)但没有成功。
我的问题是,如何将这些字段转换为数值?是尝试键入要走的路,还是有其他我不知道的方法?您还会在代码中注意到我创建了一个游标,但并未使用它。最初的计划是用它来浏览数据库,但我从 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 错误。
Jackcess 不会 return 所有值都作为字符串。它将检索 table 的字段(列)作为该 Access 字段类型的适当 Java 类型。例如,测试 table 名为 "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()
解析数据库中的字符串值,那么
- 它们包含 "funny characters" 从您发布的示例中看不出来的内容,或者
- 你做错了。
有关示例文件的其他信息
Jackcess return将 CURRENTGAC 作为字符串,因为它是 table:
中的文本字段下面的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.