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

时间:2012-12-16 02:38:15

标签: java arrays static arraylist static-methods

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

2 个答案:

答案 0 :(得分:1)

问题是您尝试通过重复使用相同的对象来提前优化:

  

pausePredKseArr.clear();

创建一个新的ArrayList而不是清除旧的{{1}},你就可以了。

答案 1 :(得分:-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);

}

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