2012-12-16 43 views
0

我的代碼的問題是,當我在下面調用generateCSV()時,ArrayList的輸出不正確。它將所有的實例替換爲僅實例化的最後一個實例,即最後一個實例將替換所有先前的事件。Java:靜態方法中源自其他ArrayList的實例ArrayList

我的基類,PausePred,採用一個字符串和一個ArrayList

public class PausePred { 

    private String predString; // the keys preceding the pause 
    private ArrayList<KSE> kseArr; // the arraylist of KSEs comprising the PausePred 

    public PausePred(String predStr) { 
     this.predString = predStr; 
     kseArr = new ArrayList<KSE>(); 
    } 

    public void setKseArr(ArrayList<KSE> kseArr) { 
     this.kseArr.addAll(kseArr); 
    } 

PausePred,我有一個靜態方法來創建的PausePreds陣列。

public static Collection<PausePred> parseKseArray(KSE[] kArr) { 

    Collection<PausePred> pausePredArray = new ArrayList<PausePred>(); 

    String pausePredStr = "";  // to store incrementally appended events preceding pause 
    int pauseDur = 0;    // to store pause duration 
    boolean startPosSet = false; // checks if startPos has been set 
    ArrayList<KSE> pausePredKseArr = new ArrayList<KSE>();; 


    for (int kseArrIdx = 0; kseArrIdx < kArr.length; kseArrIdx++) { 
     if (kArr[kseArrIdx].isKeyPress()) { // only down-keys 
      // if start positio"n has not been set, set it, and update flag 
      // set time stamp, as well 
      if (startPosSet == false) { 
       startPosSet = true; 
       // get first char of PredStr by going back one index 
       if (kseArrIdx > 0) { 
        pausePredStr = VisualCharStream.vkCodetoString(kArr[kseArrIdx-1].getKeyCode()); 
        pausePredKseArr.add(kArr[kseArrIdx-1]); 
       } 
      } 

      if (kArr[kseArrIdx].getM_pauseMs() < PauseBursts.PAUSE) { // is not a pause 
       //append vkCode (to string) to pausePred 
       pausePredStr += VisualCharStream.vkCodetoString(kArr[kseArrIdx].getKeyCode()); 
       pausePredKseArr.add(kArr[kseArrIdx]); 
      } 

      else { // is a pause 

       //start incrementing pause duration, until a non-pause is reached 
       while (kArr[kseArrIdx].getM_pauseMs() >= PauseBursts.PAUSE) { 
        pauseDur = (int) kArr[kseArrIdx].getM_pauseMs(); 
        kseArrIdx++; 
       } 

       //add to pausePred array 
       PausePred pp = new PausePred(pausePredStr); 
       pp.setKseArr(pausePredKseArr); 
       pausePredArray.add(pp); 

       //reset variables 
       pausePredStr = ""; 
       startPosSet = false; 
       pausePredKseArr.clear(); 
       //need to take one step back from above while loop 
       kseArrIdx--; 
      } 
     } // close outer if loop 
    } // close for loop 
    return pausePredArray; 
} // close parseKseArray() 

當我打電話低於此方法中,第一部分給出的每個實例,但第二部分在陣列中給出的最後一個實例的唯一的kseArr。

public static void generateCSV(String fileName,ArrayList<PausePred> pausePredArr) { 
     for (PausePred pp : pausePredArr) 
System.out.println(pp.getPredString()+"\t"+pp.kseArr.get(pp.kseArr.size()-1).getKeyCode()); 
} 

這是調用上述解析方法的提取方法。我不確定這是否與這個問題密切相關。

public class ExtractPausePred implements ExtractionModule { 

    private static ArrayList<PausePred> pausePredArray = new ArrayList<PausePred>(); 

    @Override 
    public void extract(DataNode data) { 

     for (Answer a : data) { 
      //create KSE array 
      KSE[] kseArr = parseSessionToKSE(a.getKeyStrokes()); 

      //from above KSE array, extract Pause Predecessors 
      pausePredArray.addAll(PausePred.parseKseArray(kseArr)); 
      PausePred.generateCSV("testing123",pausePredArray); 
     } 

     return null; 
    } 
} 

回答

1

的問題是你的企圖過早地被重複使用相同的對象優化:

pausePredKseArr.clear();

創建一個新的ArrayList而不是清除舊的,你會沒事的。

+0

我無法每次都創建一個新的'ArrayList'。 'ArrayList'有時會累積'KSEs',有時不會。結果,'ArrayList'必須通過多個循環持續存在。只有實例化一個'PausePred'的新實例才能清除'ArrayList',或創建一個新的實例。 –

+0

好的,然後''pauseKseArr = new ArrayList ()'而不是清除它。你已經添加了'ArrayList' - 當你清除它時,你也清除了你剛剛設置'pp'的那個。 –

+0

就這樣做!謝謝!!如果你想編輯你的答案,我可以給你適當的獎勵。 –

-1

我的代碼的問題是,當我在下面調用generateCSV()時,ArrayList的輸出不正確。它將所有的實例替換爲僅實例化的最後一個實例,即最後一個實例將替換所有先前的事件。

我還沒有詳細閱讀您的代碼,也許您可​​以嘗試減少它。但是 這幾乎總是因爲相同的對象(修改後)被添加到一個集合,而不是每次都創建一個new實例:

SomeType s = new SomeType(); 
while (condition) { 
     s.setAttr1(value1); 
     s.setAttr2(value2); 
     collection.add(s); 

}

你有什麼不一樣的s對象在collection的每個索引處。它的屬性將在最後一次迭代中添加相同的值。

你需要的是:

while (condition) { 
     SomeType s = new SomeType();  
     s.setAttr1(value1); 
     s.setAttr2(value2); 
     collection.add(s); 

}

通過創建循環內的對象,不同的對象在每次迭代增加。

+0

謝謝,但正如我上面解釋的,我不能這樣做。 'ArrayList'有時會累積'KSEs',有時不會。結果,'ArrayList'必須通過多個循環持續存在。只有實例化一個'PausePred'的新實例才能清除'ArrayList',或創建一個新的實例。 –

+0

你是說你要在一個集合中添加不同的對象,並且它們都顯示最後一個添加的元素的屬性? –