【问题标题】:Java: Instance ArrayList Derived From Other ArrayList in Static MethodJava:从静态方法中的其他 ArrayList 派生的实例 ArrayList
【发布时间】:2012-12-03 14:28:01
【问题描述】:

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

【问题讨论】:

    标签: java arrays static arraylist static-methods


    【解决方案1】:

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

    pausePredKseArr.clear();

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

    【讨论】:

    • 我不能每次都创建一个新的ArrayListArrayList 有时会累积 KSEs,有时不会。因此,ArrayList 有时必须通过多个循环持续存在。只有在 PausePred 的新实例被实例化后,ArrayList 才能被清除或创建一个新实例。
    • 好的,然后执行pausePredKseArr = new ArrayList&lt;KSE&gt;() 而不是清除它。您已经在其中添加了 ArrayList -- 当您清除它时,您清除了您刚刚设置 pp 使用的那个。
    • 行了!谢谢!!如果你想编辑你的答案,我可以给你适当的信用。
    【解决方案2】:

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

    }

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

    【讨论】:

    • 谢谢,但正如我上面解释的那样,我不能这样做。 ArrayList 有时会累积 KSEs,有时不会。因此,ArrayList 有时必须通过多个循环持续存在。只有在 PausePred 的新实例被实例化后,ArrayList 才能被清除或创建一个新实例。
    • 你是说你在一个集合中添加不同的对象并且它们都表现出最后添加元素的属性?
    猜你喜欢
    • 2019-01-31
    • 2012-12-03
    • 2011-02-24
    • 1970-01-01
    • 2015-02-14
    • 2020-03-28
    • 1970-01-01
    • 2018-11-02
    • 1970-01-01
    相关资源
    最近更新 更多