Почему результаты меняются, как только я использую Apache POI в своем коде? - PullRequest
0 голосов
/ 10 января 2019

Я сузил свою проблему до этой строки в моем коде: "Workbook workbook = new 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.
}

Ожидается: [1733]

{Значение 1 = 0,0657304324073498, Значение 2 = 21213,0, Значение 3 = 18,57715885746071, Значение 4 = 0,33081495617910694}

Фактически: [1733]

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

1 Ответ

0 голосов
/ 10 января 2019

Только чтобы показать, что ваше предположение неверно:

Полный пример:

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}

Результат с созданием HSSFWorkbook:

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}

Я могу воспроизвести проблему, если bb, который возвращает HashMap<Set<Integer>, HashMap<String, Double>> Qvalues, выполняется в отдельном потоке, и это постоянно обновляет 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);
  }
 }

}

Результат:

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}

Отказ от ответственности: Приведенный выше код предназначен для выявления проблем и, как и все мои примеры кода здесь, он , а не предназначен для продуктивного использования.

Последняя часть кода показывает неправильное использование многопоточности. HashMap не является поточно-ориентированным, поэтому даже может быть так, что отдельные элементы на этой карте не готовы, когда другой поток пытается их получить.

Кроме того, имена переменных из кода в вопросе частично включены в мой код, хотя они нарушают Java соглашения об именах. Это сделано из-за сопоставимости. Я знаю, что переменные должны называться не Qvalues, а qValues - camleCaseStyle, начиная с нижнего регистра. И метод никогда не должен называться MSQATVHM, поскольку заглавные имена должны быть только именами констант.

...