Java 为什么当我在代码中使用ApachePOI时,结果会发生变化?

Java 为什么当我在代码中使用ApachePOI时,结果会发生变化?,java,excel,apache-poi,Java,Excel,Apache Poi,我已将问题缩小到代码中的这一行: “工作簿=新的HSSFWorkbook();” 只要我注释掉这一行并直接使用System.out语句打印结果,所有结果都很好 我甚至尝试过使用XSSFWorkbook,但问题依然存在。 然后我认为我的外部库是一个问题,而DOUBLE是导致问题的原因。我尝试将内部HashMap值类型更改为Double(来自Java),但仍然不起作用 编辑:我还尝试删除此处未显示的代码,并仅运行此处显示的代码。问题依然存在 public static void main(Strin

我已将问题缩小到代码中的这一行: “工作簿=新的HSSFWorkbook();” 只要我注释掉这一行并直接使用System.out语句打印结果,所有结果都很好

我甚至尝试过使用XSSFWorkbook,但问题依然存在。 然后我认为我的外部库是一个问题,而DOUBLE是导致问题的原因。我尝试将内部HashMap值类型更改为Double(来自Java),但仍然不起作用

编辑:我还尝试删除此处未显示的代码,并仅运行此处显示的代码。问题依然存在

public static void main(String[] args) throws Exception {
HashMap<SET<Integer>, HashMap<String,DOUBLE>> Qvalues= 
bb.MSQATVHM();
Workbook workbook = new HSSFWorkbook();
for(SET<Integer> IntegerSet:Qvalues.keySet()){
    System.out.println(IntegerSet);
    System.out.println(Qvalues.get(IntegerSet));
    }
// Program continues.....the rest doesn't matter here.
}
publicstaticvoidmain(字符串[]args)引发异常{
HashMap Qvalues=
bb.MSQATVHM();
工作簿=新的HSSF工作簿();
for(SET IntegerSet:Qvalues.keySet()){
System.out.println(整数集);
System.out.println(Qvalues.get(IntegerSet));
}
//程序继续…剩下的在这里不重要。
}
预期:[1733]

{Value1=0.0657304324073498,Value2=21213.0,Value3=18.57715885746071,Value4=0.33081495617910694}

实际:[1733]


{Value1=0.0394381995860269,Value2=12727.80000000001,Value3=11.14629515620783,Value4=0.35655228866335265}

仅表明您的假设是错误的:

完整示例:

import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import java.util.*;

public class UsingPOITest  {
 public static void main(String[] args) throws Exception {

  HashMap<Set<Integer>, HashMap<String, Double>> Qvalues = new HashMap<Set<Integer>, HashMap<String, Double>>();
  Set<Integer> set = new HashSet<Integer>();
  set.add(new Integer(1733));
  HashMap<String, Double> hashMap = new HashMap<String, Double>();
  hashMap.put("Value1", new Double(0.0657304324073498));
  hashMap.put("Value2", new Double(21213.0));
  hashMap.put("Value3", new Double(18.57715885746071));
  hashMap.put("Value4", new Double(0.33081495617910694));
  Qvalues.put(set, hashMap);
  Workbook workbook = null;
  //workbook = new HSSFWorkbook();
  System.out.println("Workbook: " + workbook);
  for(Set<Integer> IntegerSet : Qvalues.keySet()){
   System.out.println(IntegerSet);
   System.out.println(Qvalues.get(IntegerSet));
  }
 }
}
创建
HSSFWorkbook
的结果:

axel@arichter:~/Dokumente/JAVA/poi/poi-4.0.1$ java -cp .:./*:./lib/*:./ooxml-lib/* UsingPOITest 
Workbook: null
[1733]
{Value3=18.57715885746071, Value4=0.33081495617910694, Value1=0.0657304324073498, Value2=21213.0}
axel@arichter:~/Dokumente/JAVA/poi/poi-4.0.1$ java -cp .:./*:./lib/*:./ooxml-lib/* UsingPOITest 
Workbook: org.apache.poi.hssf.usermodel.HSSFWorkbook@573fd745
[1733]
{Value3=18.57715885746071, Value4=0.33081495617910694, Value1=0.0657304324073498, Value2=21213.0}

如果返回
HashMap Qvalues
bb
在一个单独的线程中运行,并且不断更新
MSQATVHM
,我可以重现该问题。那么,创建工作簿只是一个问题,因为它需要一些时间来再次更新
MSQATVHM

例如:

import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import java.util.*;

public class UsingPOITest  {
 public static void main(String[] args) throws Exception {

  BB bb = new BB();
  bb.start();
  Thread.sleep(1000);

  HashMap<Set<Integer>, HashMap<String, Double>> Qvalues = bb.MSQATVHM();
  System.out.println(Qvalues);

  Thread.sleep(1000);

  for(Set<Integer> IntegerSet : Qvalues.keySet()){
   System.out.println(IntegerSet);
   System.out.println(Qvalues.get(IntegerSet));
  }
 }

 static class BB extends Thread {

  HashMap<Set<Integer>, HashMap<String, Double>> msQatVHM = new HashMap<Set<Integer>, HashMap<String, Double>>();

  void setMSQatVHM(int atVHM) {
   msQatVHM.clear();
   Set<Integer> set = new HashSet<Integer>();
   set.add(new Integer(1733));
   HashMap<String, Double> hashMap = new HashMap<String, Double>();
   if (atVHM == 0) { 
    hashMap.put("Value1", new Double(0.0657304324073498));
    hashMap.put("Value2", new Double(21213.0));
    hashMap.put("Value3", new Double(18.57715885746071));
    hashMap.put("Value4", new Double(0.33081495617910694));
   } else {
    hashMap.put("Value1", new Double(0.0394381995860269));
    hashMap.put("Value2", new Double(12727.800000000001));
    hashMap.put("Value3", new Double(11.14629515620783));
    hashMap.put("Value4", new Double(0.35655228866335265));
   }
   msQatVHM.put(set, hashMap);
  }

  HashMap<Set<Integer>, HashMap<String,Double>> MSQATVHM() {
   return msQatVHM;
  }

  public void run() {
   setMSQatVHM(0);
   try {
    this.sleep(1000);
   } catch (Exception ex) {
    ex.printStackTrace();
   }
   setMSQatVHM(1);
  }
 }

}

免责声明: 上面的代码是用来显示问题的,正如我这里的所有代码示例一样,它不是用来准备生产性使用的

最后一个代码部分显示了多线程的误用
HashMap
不是线程安全的,因此当另一个线程尝试获取映射中的单个项目时,该映射中的单个项目甚至可能没有准备好


此外,问题代码中的变量名在我的代码中被部分接管,尽管它们违反了
Java
命名约定。这是因为具有可比性。我知道变量不应命名为
Qvalues
,而应命名为
Qvalues
-
camleCaseStyle
以小写开头。而且一个方法永远不应该被命名为
MSQATVHM
,因为大写的名称只应该是常量的名称。

SET和
DOUBLE
从何而来?它们不是普通的Java,这也可能是问题所在。您确定添加
工作簿
而不一致地更改其他代码会导致此结果吗?@标记它们来自外部库,我已尝试将其清除,但问题仍然存在。我不明白你的问题。你能详细解释一下吗?还有“不保证地图的顺序;特别是,它不保证随着时间的推移,顺序会保持不变”。你似乎希望它是一致的。@Mark:我不理解你的问题。你能详细说明一下吗?我同意#HashMap不一致,但实际结果中的值是#HashMap读取中甚至没有的值。我不关心它们出现的顺序。唯一的事情是
Workbook Workbook=new HSSFWorkbook()
DoS正在随机访问内存中实例化
HSSFWorkbook
对象。如果这导致这种不一致,那么
SET
可能会不一致地存储在RAM中?因为我们不知道集合实际上是什么,所以我们无法知道。另外,线程问题,你是隐藏的,可能是原因。
HasMap
HSSFWorkbook
都不是线程安全的。嗨,阿克塞尔,谢谢。在你发表评论后,我也在尝试同样的方法,我现在明白你的意思了。我有同样的解决办法。我现在试着看看这是否也适用于我的主代码。不,我试着将我的集合转换为字符串,因为这样更容易进行快速检查。双倍我已经转换成双倍了。问题仍然存在。然后编辑您的问题,使其提供显示问题的完整代码。否则就没有办法了。正如您所看到的,我的完整代码没有这个问题。正如我在评论中所说,可能涉及多个线程?谢谢Axel,但我很难将代码放在这里,因为它涉及10多个类。有什么建议可以让我分享,让你更好地理解我的问题吗?我尝试了更多,现在我发现是for循环导致了问题。同样的代码如果我尝试打印QValues HashMap,注释掉for循环,所有结果都很好。然而,当我使用for循环时,HashMap的结果以及键和值的独立值都会发生变化。有什么建议吗?
axel@arichter:~/Dokumente/JAVA/poi/poi-4.0.1$ javac -Xlint:deprecation -Xlint:unchecked -cp .:./*:./lib/*:./ooxml-lib/* UsingPOITest.java 
axel@arichter:~/Dokumente/JAVA/poi/poi-4.0.1$ java -cp .:./*:./lib/*:./ooxml-lib/* UsingPOITest
{[1733]={Value3=18.57715885746071, Value4=0.33081495617910694, Value1=0.0657304324073498, Value2=21213.0}}
[1733]
{Value3=11.14629515620783, Value4=0.35655228866335265, Value1=0.0394381995860269, Value2=12727.800000000001}