Java:从静态方法中的其他 ArrayList 派生的实例 ArrayList



我的代码的问题是,当我在下面调用generateCSV()时,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;
    }
}

问题是你试图通过重用相同的对象来过早地优化:

pausePredKseArr.clear();

创建一个新ArrayList而不是清除旧你会没事的。

我的代码的问题是,当我在下面调用 generateCSV() 时,ArrayList 的输出不正确。它只用要实例化的最后一个实例替换所有实例,即最后一个实例正在替换所有以前的事件。

我还没有详细阅读您的代码,也许您可以尝试减少它。但这几乎总是因为相同的对象(修改后)被添加到集合中,而不是每次都创建一个new实例:

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

}

您拥有的是collection中的每个索引处的相同s对象。它的属性将具有在上次迭代中添加的相同值。

您需要的是:

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

}

通过在循环中创建对象,每次迭代都会添加一个不同的对象。

相关内容

最新更新